مثالی واقعی در استفاده از کنترلرها – Spring MVC

می خواهیم با استفاده از یک کنترلر ساده، به کاربران اجازه دهیم اطلاعات ژانرهای مختلف فیلم ها را در قالب یک صفحه مشاهده کنند. همچنین، یک کنترلر فرم ایجاد می کنیم که توسط آن کاربران بتوانند عملیات رزرو صندلی را برای نمایش یک فیلم انجام دهند، و در آخر، یک فرایند اتوماتیکی برای افزودن ژانر جدید به مجموعه ژانرهای سایت ایجاد می کنیم.

مشاهده لیستی از صفحات با استفاده از AbstractController

کاربران می توانند از لیست ژانرها، ژانری را برای مشاهده اطلاعات آن انتخاب کنند. بیایید برای انجام این کار یک AbstractController پیاده سازی کنیم.

اگر کنترلرهای پیشنهادی Spring برای نیازهای شما مناسب نیست و می خواهید مستقیما اینترفیس Controller را پیاده سازی کنید، پیشنهاد می شود به جای آن، کنترلر AbstractController را گسترش[۱] دهید. با این کار بسیاری از پارامترهای پیکربندی، به صورت مناسبی تنظیم می شوند و این کار سفارشی کردن رفتار کنترلر را آسان تر می کند.

گردش کار ViewShowController

اجازه دهید گردش کار این کنترلر را مرور کنیم:

  1. ابتدا صفحه نمایش اولیه به کاربر نشان داده می شود. در این صفحه، کاربر لیستی از ژانرها را می بیند. هر ژانر با یک شناسه مشخص که در لینک مربوط به ژانر قرار داده شده است از سایر ژانرها مجزا می شود. با کلیک بر روی یکی از این لینک ها، کار کنترلر آغاز می شود.
  2. کنترلر با بازیابی شناسه از درون HttpServletRequest، ژانری را که کاربر انتخاب کرده است، مشخص می کند.
  3. با استفاده از شناسه، لایه میانی باید اطلاعات ژانری را که مربوط به شناسه است، بازیابی کند.
  4. کنترلر یک نام نمایش منطقی[۲] و محتویات مدلی که با آن، به عنوان مثال، JSP پردازش می شود، را تعیین می کند.

مرحله ۲ به یک درخواست اشاره می کند. فرض کنید درخواست به صورت زیر باشد:

http://www.springframework.org/sample/viewshow.html?id=1234

پیاده سازی کنترلر

در ابتدا، پیاده سازی کنترلر را با هم بررسی کنیم. برای پیاده سازی می توانیم از دو روش استفاده کنیم. روش اول از گسترش AbstractController استفاده می کند. پیاده سازی متدهای الگوی ارائه شده توسط کلاس بالاسری، تنها کاری است که باید انجام شود.

متد الگوی زیر، ژانری که کاربر انتخاب کرده است را بازیابی کرده و در یک مدل مناسب بازمی گرداند.

 

برای بازیابی شناسه از درون url، از کلاس RequestUtils (واقع در بسته org.springframework.web.bind) استفاده شده است. این کلاس در موارد ساده که در آن انقیاد[۳] پیشرفته داده ها آزاردهنده خواهد بود مورد استفاده قرار می گیرد. اگر پارامتر مورد نظر در درخواست وجود نداشته باشد، متد ()getRequiredLongParameter یک استثنا تولید می کند، که در این صورت بهتر است یک HandlerExceptionResolver به متن نرم افزار خود بیافزایید.

توجه داشته باشید که ایجاد یک نمونه از ModelAndView و برگرداندن آن در یک خط انجام شده است. به طور کلی، باید مراقب این مسئله بود، زیرا این کار اشکال زدایی را مشکل تر می سازد. اگر NullPointerException ایجاد شود، در این صورت یافتن مشکل کار دشواری خواهد بود.

ما می توانستیم از ThrowawayController برای اجرای عملکرد مورد نظر استفاده کنیم. ThrowawayController، امکانات بیشتری از سبک استفاده از شی فرمان برای هر درخواست ارائه می دهد، به این صورت که برای این که کنترلر اطلاعات کافی را برای ادامه کار و بازگرداندن یک نمونه از ModelAndView داشته باشد، یک نمونه از کنترلر با مقادیر موجود در درخواست ایجاد می شود. مزیت استفاده از این نوع کنترلرها در این است که شما به API سرولت وابسته نخواهید بود، چرا که همه اطلاعات موجود در HttpServletRequest، توسط چارچوب، درون خود کنترلر قرار گرفته است و هیچ اشاره گری به درخواست، تحویل کنترلر نمی شود.

 

 

مقید کردن کنترلر

پس از ایجاد کنترلر، قصد داریم آن را به متن[۴] برنامه خود، که در دایرکتوری WEB-INF قرار دارد مقید کنیم.

 

با این کار برنامه قادر است ژانرها را با استفاده از لایه میانی بازیابی کرده و به کمک تکنولوژی نمایش مورد نظر ما، آن ها را در قالب یک صفحه HTML، PDF، و یا اکسل، نمایش دهد.

ایجاد یک رزرو

این نرم افزار به کاربران اجازه می دهد بتوانند بلیط خود را تهیه کرده و تعدادی صندلی رزرو کنند. از روی صفحه ای که اطلاعات ژانر را نشان می دهد، کاربر می تواند گزینه رزرو یک یا تعدادی صندلی، و خرید بلیط نهایی آن را انتخاب کند. ابتدا، بر روی گردش کار انجام خرید، نگاه دقیق تری می اندازیم:

  1. کاربر از روی صفحه ای که جزئیات ژانر را به او نشان می دهد، می تواند گزینه رزرو صندلی را به همراه قیمت مورد نظر خود انتخاب کند. با این انتخاب، کاربر به یک صفحه ای منتقل می شود که در آن، می تواند تعداد صندلی های مورد نیاز برای رزرو را مشخص کند.
  2. در این لحظه، برنامه تعداد صندلی های موجود را به کاربر نمایش می دهد. کاربر به فرمی هدایت خواهد شد که به او اجازه می دهد خرید را انجام داده و بلیط را تهیه کند.
  3. در کنار فرم، جزئیاتی از فیلمی که کاربر در حال خرید بلیط آن است نمایش داده می شود. فرم متشکل از متن، چک باکس ها و بخش هایی است که با آن کاربر قادر خواهد بود اطلاعات شخصی (نام، نام خانوادگی، و …) و جزئیات پرداخت (شماره کارت اعتباری، نوع کارت اعتباری) را پر کند.
  4. با ارسال فرم به سمت سرور، اعتبارسنجی انجام خواهد شد. اگر اعتبارسنجی با خطا مواجه شد، فرم دوباره و با جزئیات خطای ایجاد شده نمایش داده می شود. کاربر می تواند قسمت هایی را که با خطا مواجه شده است، دوباره پر کند.
  5. پس از اعتبارسنجی موفق، پرداخت واقعی انجام خواهد شد و بلیط خریداری می شود. پس از آن کاربر به صفحه دیگر هدایت می شود که به او، اطلاعات بلیط خریداری شده نمایش داده می شود.

SimpleFormController

در روند یک نمونه ویرایش و ارسال فرم، ابتدا به کاربر فرمی نشان داده می شود که می تواند آن را پر کرده، ارسال کند و پس از آن انقیاد و اعتبارسنجی داده ها انجام خواهد شد. اگر همه چیز به خوبی پیش رود، نرم افزار، برای مثال اطلاعات را در پایگاه داده ذخیره کرده و پس از آن اتمام موفق کار، نتیجه را به کاربر اطلاع می دهد.

org.springframework.web.servlet.mvc.SimpleFormController دقیقا این کار را انجام می دهد. این کنترلر، یکی از مفید ترین و پرکاربردترین کنترلرهای Spring است و تقریبا می تواند به طور کامل با استفاده از ویژگی های تزریق وابستگی[۵] Spring پیکربندی شود.

فرایند پیاده سازی یک کنترلر فرم ساده به صورت زیر است (قدم هایی که بین پرانترها نوشته شده اند همیشه لازم نیستند):

  • گسترش[۶] دادن springframework.web.servlet.mvc.SimpleFormController.
  • تنظیم formView و successView که در متن نرم افزار مورد استفاده قرار گرفته است.
  • افزودن یک setter برای شی ای که قادر به ذخیره سازی اطلاعات فرم در پایگاه داده است.
  • (سربارگذاری متد referenceData() برای تنظیم پارامترهایی که باید در یک combo-box نمایش داده شود.)
  • (سربارگذاری متد formBackingObject() برای تعریف رفتار مناسب Spring برای ساخت یک نمونه از کلاس فرمان[۷] و یا تنظیم کردن پارامتر commandClass، در صورتی که فقط بخواهیم یک شی فرمان[۸] خالی از سمت فرم برگردد.)
  • (افزودن یک گروه از اشیاء اعتبارسنجی با استفاده از خصیصه validators.)
  • پیاده سازی متد doSubmitAction() برای مدیریت یک فرایند کامل جهت ذخیره اطلاعاتی که پردازش و اعتبارسنجی شده و آماده ذخیره در پایگاه داده هستند.

قبل از شروع پیاده سازی، اجازه دهید خواص و برخی از callbackها و دیگر امکانات سفارشی سازی موجود در SimpleFormController را بررسی کنیم.

انعطاف پذیری کنترلر فرمان و کنترلر فرم نباید باعث نگرانی باشد. معمولا برنامه نویسان تنها از سه متد زیر استفاده می کنند: ()formBackingObject()، referenceData و ()doSubmitAction. با این حال، برخی اوقات ساخت یک شیء از کلاس فرمان به قدری گران تمام می شود که انجام دو بار آن باعث اتلاف منابع خواهد شد. در این صورت می توانیم از خصیصه sessionForm نیز استفاده کنیم. بنابراین، زمانی که نیازهای شما پیچیده نباشد، درمی یابید که کار با زیرساخت های کنترلر Spring آسان است، و در غیر این صورت متوجه قدرت آن خواهید شد.

خواصی که با آن کنترلر را تنظیم می کنیم

SimpleFormController بسیاری از قابلیت های خود را از AbstractFormController و BaseCommandController به ارث می برد. در صورت نیاز، ما می توانیم با کمک خصیصه های زیر، رفتار این کلاس را به اختیار خود تغییر دهیم:

commandClass: از این کلاس به طور پیش فرض یک نمونه ساخته شده و به عنوان شی متناظر با فرم از آن استفاده می شود. به این معنی که خصیصه های فرم، از طریق این شی در دسترس هستند. به طور پیش فرض، Spring با استفاده از سازنده پیش فرض (در صورت وجود) یک شی جدید، از کلاس فرمان تعیین شده خواهد ساخت. اغلب اوقات شما نمی خواهید، تنها یک نمونه از کلاس ایجاد شود، بلکه مثلا در نظر دارید یک شی را از پایگاه داده بارگذاری کنید. در این حالت، نیازی به تنظیم کلاس فرمان نیست و تنها باید متد ()formBackObject را سربارگذاری کنید.

formView و successView: این نام های نمایش منطقی، به نمایش هایی اشاره می کنند که حاوی فرم و نمای رندر شده آن، پس از ارسال، اعتبارسنجی، و پردازش موفق فرم است. SimpleFormController به عنوان خصیصه های خود، success و form را تعریف کرده است؛ اگر شما به نمونه سفارشی از این نمایش ها نیاز دارید، به جای SimpleFormController، کلاس AbstractFormController را گسترش دهید. از جمله مشکلات معمولی در زمان کار با فرم، مشکلات پس از POST است. اگر کاربر یک درخواست را POST کند و گزینه refresh مرورگر خود را بزند، از کاربر نسبت به ارسال مجدد داده ها سوال می شود. در اغلب موارد کاربر نمی خواهد این کار انجام شود. Spring راه حلی ارائه می دهد که یک درخواست GET، بلافاصله پس از یک درخواست POST ارسال شود. این ویژگی با کمک افزودن پیشوند redirect همراه نام نمایش به دست می آید.

sessionForm: بر اساس اینکه یک نمونه از این خصیصه از قبل ایجاد شده باشد یا خیر، Spring در اولین باری که فرم نشان داده می شود، یک شی جدید را ایجاد کرده و آن را در نشست کاربر ذخیره می کند. پس از ارسال فرم، این نمونه فرم ذخیره شده در نشست، بازیابی شده و برای انقیاد به داده های ورودی مورد استفاده قرار می گیرد. البته، پس از ارسال فرم، شی ذخیره شده در نشست، حذف خواهد شد. به طور پیش فرض، مقدار این ویژگی برابر false است. در صورت استفاده از این مقدار، هر زمان که کنترلر به یک درخواست جدید پاسخ دهد (در هر دو حالت نمایش فرم و همچنین ارسال فرم پرشده)، یک شیء فرمان جدید ایجاد می شود. نمونه سازی یک کلاس فرمان ساده با استفاده از رفتار پیش فرض (به عبارت دیگر، اگر شما ()formBackingObject را سربارگذاری نکرده باشید) خیلی هزینه بر نیست. با این حال، اگر شی متناظر فرم را از پایگاه داده بازیابی کنید، احتمالا بخواهید این ویژگی را فعال کنید، زیرا عدم انجام آن ممکن است برخی اثرات منفی بر سرعت عملکرد صفحه داشته باشد.

bindOnNewForm: گزینه ای که مشخص می کند آیا انقیاد پارامترهای درخواست، در زمانی که درخواستی برای فرم جدید در حال پردازش است انجام پذیرد. اگر شما مقدار این خصیصه را برابر true قرار دهید (به طور پیش فرض false است)، تمام پارامترهای موجود در HttpServletRequest در زمان نمایش یک فرم جدید به شی فرمان مقید می شوند. این کار در زمانی که بخواهیم یک فرم را از قبل، مقداردهی کنیم بسیار مفید است.

validator: این گزینه پس از مقید کردن داده ها به کار می رود. اعتبارسنج ها از نوع org.springframework.validation.Validator هستند.

validateOnBinding: به طور پیش فرض این ویژگی true است؛ اگر شما آن را false کنید، اعتبارسنجی اتفاق نخواهد افتاد.

commandName: این خصیصه اجازه می دهد نام شی فرمان قرار گرفته در مدل (شی ای که معادل فرم است) را مشخص کنیم. به طور پیش فرض نام این شی command است. هنگامی که از کنترلر فرم استفاده می کنیم، نیازی نیست تمام فن آوری های نمایش، دسترسی مستقیم به مدل داشته باشند، زیرا برای مثال، ماکروهای فرم و برچسب[۹] های سفارشی راه های مناسب برای ارائه فیلد ها و مقادر موجود در فرم هستند. با این وجود، در شرایط خاص ممکن است به دسترسی به مدل نیاز پیدا کنیم.

متدهای callback و template برای رفتارهای خاص

چندین متد callback وجود دارد که می توانیم با پیاده سازی آن ها، رفتارهای سفارشی مورد نظر خود را ایجاد کنیم و یا رفتارهای پیش فرض Spring را گسترش دهیم. این موارد شامل متدهایی می شوند که قبل و پس از اعتبارسنجی فراخوانی شده و همچنین متدهایی که برای سفارشی سازی رفتار مورد نظر ما در زمان ارسال فرم باید پیاده سازی گردند.

Map referenceData(HttpServletRequest request, Object command, BindException errors): از این متد زمانی استفاده می شود که در فرم علاوه بر شی فرمان، داده های اضافی دیگری مثل گزینه هایی که باید در یک جعبه کشویی[۱۰] نمایش داده شود، و یا انتخاب هایی که کاربر می تواند با استفاده از چک باکس داشته باشد، می بایست نمایش داده شود. همه عناصر درون map بازگشتی از این متد، درون مدل افزوده خواهند شد و در نتیجه برای رندر کردن view قابل استفاده خواهند بود.

initBinder(HttpServletRequest request, ServletRequestDataBinder binder): این متد شاید بعد از متدی که برای عمل ارسال شی فرمان باید سربارگذاری شود، مهم ترین متد کنترلر باشد. این متد به شما اجازه می دهد ویرایش گر سفارشی برای خصیصه ها فرم اضافه کنید. از DataBinder مشخص شده با نام binder، برای تبدیل خصیصه های دامنه[۱۱] (مانند تاریخ، و همچنین تبدیل خصیصه های دیگر مانند ژانر به رشته) استفاده می شود که پس از ارسال فرم می تواند دوباره به شی اصلی خود تبدیل شود. این متد امکان جدایی کامل بین کنترلر فرم و شی دامنه را ایجاد می کند. از آنجا که کنترلر فرم را به طور کامل stateless است، این متد در هر دو زمان ارسال درخواست نمایش فرم و همچنین درخواست ارسال اطلاعات فرم فراخوانی می شود.

onBind(HttpServletRequest request, Object command, BindException errors) و onBind(HttpServletRequest req, Object command): از این متد زمانی استفاده می کنیم که بخواهیم انقیاد سفارشی داشته باشید. این متد پس از انقیاد داده ها و قبل از اعتبارسنجی استفاده می شود. فرض کنید فرمی داریم که شامل سه ورودی است که با هم یک تاریخ (یک سال، ماه، و روز) را می سازند. ما با استفاده از PropertyEditors نمی توانیم از سه فیلد فرم به یک خصیصه دامنه انقیاد ایجاد کنیم. ما باید از جاوا اسکریپت برای ارسال سه فیلد در درون یک فیلد مخفی و از یک ویرایشگر خصیصه برای تبدیل پارامتر ورودی مخفی به تاریخ، به جای سه رشته جداگانه، استفاده کنیم. رویکرد دیگر (و شاید بهتر) این است که متد onBind() را سربارگذاری کرده و انقیاد سفارشی خود را اینجا انجام دهیم.

onBindAndValidate(HttpServletRequest req, Object command, BindException errors): از این متد زمانی استفاده می کنیم که به انجام اعتبارسنجی خاصی نیاز داریم و توسط اعتبارسنجی عادی تعریف شده برای کنترلر قابل انجام نمی باشد. معمولا اعتبارسنج ها به درخواست دریافت شده توسط سرولت دسترسی ندارند، بنابراین اگر بخواهیم اعتبارسنجی ای انجام دهیم که نیاز به حضور درخواست باشد، این متد مکان مناسبی است.

ModelAndView onSubmit(HttpServletRequest req, HttpServletResponse res, Object command, BindException errors) و شکل ساده تر آن onSubmit(Object command, BindException errors) و onSubmit(Object command): این متدها شی ای از نوع ModelAndView (و یا null در زمانی که نخواهیم چارچوب به درخواست، بیشتر رسیدگی کند) را برمی گردانند و معمولا برای انجام پردازش های فرم سفارشی درگیر سربارگذاری می شوند. این متدها پس از انقیاد داده ها، اعتبارسنجی، و در صورتی که پس از اعتبارسنجی، شی BindException شامل هیچ گونه خطایی نباشد، فراخوانی می شوند. اگر بخواهیم فرم را مجدد نمایش دهید (برای مثال زمانی که خطایی به وجود آمده باشد)، می توانیم از showForm(HttpServletRequest request, HttpServletResponse response, BindException exception) استفاده کنیم.

void doSubmitAction(Object command): این متد ساده ترین شکل متد ارسال است. نیازی به زحمت اضافی برای برگرداندن شی ModelAndView نیست؛ SimpleFormController به طور خودکار با استفاده از خصیصه successView این کار را انجام می دهد. این جا مکانی است که ما می توانیم، برای مثال، شی فرمان را با استفاده از تکنولوژی مورد نظر، در پایگاه داده ذخیره کنیم.

isFormChangeRequest(HttpServletRequest request): این متد زمانی توسط کنترلر فراخوانی می شود که به نمایش دوباره فرم، بدون انجام هر گونه اعتبارسنجی نیاز باشد. این امر به ویژه در شرایطی مفید است که یک ارسال میانی وجود داشته باشد و بخواهیم داده ها (و شاید خود فرم) را، بر اساس انتخاب هایی که کاربر انجام داده است تغییر دهیم. به عنوان مثال فرمی را با دو ورودی در نظر بگیرید که یکی با نام کشورها و یکی با شهرستانها پر شده باشد و زمانی که کاربر کشور را انتخاب کند، باید ورودی شهرستان ها به روز شود. کمی جاوا اسکریپت می تواند عمل ارسال را پس از انتخاب کشور انجام دهد. ()referenceData را می توان برای اضافه کردن لیست شهرستان ها به مدل مربوطه استفاده کرد. به طور پیش فرض، این متد مقدار false برمی گرداند، که به کنترلر می گوید از گردش کار عادی که برای ارسال فرم استفاده می شود، در اینجا نیز استفاده شود.

suppressValidation(HttpServletRequest request): این متد به طور پیش فرض کار را به متد ()isFormChangeRequest محول می کند. با این حال، در برخی شرایط، ممکن است بخواهیم اعتبارسنجی صورت نپذیرد. بازگشت مقدار true از این متد دقیقا این کار را انجام خواهد داد.

handleInvalidSubmit(HttpServletRequest request, HttpServletResponse response): پیاده سازی پیش فرض کنترلر تلاش می کند در ارسال مجدد فرم، از شی فرم جدیدی که توسط ()formBackingObject برمی گردد، استفاده کند. سربارگذاری این متد، کمک می کند بتوان رفتار سفارشی اضافه کرد، مانند این که اجازه ندهیم کاربران فرمی را ارسال کنند که هیچ شی ای متناظر با آن در نشست وجود ندارد. به هر حال، رفتار پیش فرض این متد، برای زمانی که کاربر دکمه Back را پس از ارسال فرم می زند به خوبی کار می کند.

ما در زمان انجام کارهایی مانند انقیاد سفارشی در متد ()onBind،احتمالا نیاز به دسترسی به HttpServletRequest پیدا می کنیم. بهترین گزینه برای انجام این کار استفاده از org.springframework.web.bind.RequestUtils است. این کلاس متدهایی از قبیل ()getIntParameter()، getBooleanParameter، و انواع دیگر دارد و در صورتی که پارامتر مورد نظر وجود نداشته باشد یک استثنا ایجاد می کند. استفاده از HttpServletRequest به صورت مستقیم اذیت کننده است، به گونه ای که ما نیاز خواهیم داشت بسیاری از موارد را چک کنیم. بنابراین بهتر است از استفاده از آن اجتناب شود (و یا این وظیفه به یک کلاس کاربردی[۱۲] منتقل شود).

گردش کار فرم

گردش کار فرم در نمودار شکل های زیر نمایش داده شده است.

Contoller Diagram1Contoller Diagram2

هنگامی که قرار است یک کنترلر فرم خدماتی به یک درخواست دهد، بر اساس نتیجه حاصل از متد ()isFormSubmission، فرایند پردازش ارسال فرم و یا جریان کاری، برای نشان دادن یک فرم جدید را طی می کند. به طور پیش فرض، تمام درخواست های GET با فرم جدید در ارتباط هستند. تمام درخواست های POST به صورت درخواست های ارسال فرم در نظر گرفته می شوند. با سربارگذاری متد isFormSubmission(HttpServletRequest)، می توان این رفتار را تغییر داد.

  1. فرایند نمایش فرم با ایجاد یک شی فرمان جدید شروع می شود. متد ()formBackingObject انجام این کار را بر عهده دارد. به طور پیش فرض، این متد یک نمونه جدید از کلاس فرمانی که از قبل پیکربندی کرده ایم، ایجاد می کند. اگر این متد را سربارگذاری کنیم، می توانیم به جای این کار، یک شی از پایگاه داده را بازیابی کنیم. به عنوان مثال، می توانیم از پارامتر اضافی در درخواست برای شناسایی شی مورد نظر جهت ویرایش استفاده کنیم. این پارامتر در متد ()formBackingObject بازیابی شده و شی مربوطه را با استفاده از DAO مورد نظر از پایگاه داده واکشی می شود.
  2. یک نمونه مقید کننده ایجاد می شود. ما می توانیم مقید کننده را (با اضافه کردن ویرایشگرهای خصیصه اضافی، و غیره) در متد ()initBinder سفارشی کنیم.
  3. فرمی که فرآیند را نمایش می دهد برای تعیین اینکه آیا به انقیاد داده نیاز است یا خیر، کار خود را ادامه می دهد. انقیاد در هنگام نمایش یک فرم جدید را می توان با تنظیم خصیصه bindOnNewForm به true ایجاد کرد.
  4. قدم بعدی این است که شی فرمان ایجاد شده را در نشست ذخیره کنیم (البته تنها در صورتی که sessionForm برابر true باشد).
  5. آخرین چیزی که کنترلر انجام می دهد این است که مدل را ایجاد کند. این کار با فراخوانی ()getModel و یا ()Errors.getModel انجام می شود. BindException در واقع شی فرمان واقعی را برمی گرداند و می تواند مدل مناسبی را ایجاد کند.

فرایند ارسال فرم (که در شکل بالا نشان داده شده است) کمی پیچیده تر است. این فرایند شامل چک کردن شی فرمان، فراخوانی متدهای callback، اعتبارسنجی (در صورت نیاز)، و فراخوانی متدهای ارسال است.

 

همانطور که می بینید، هم اکنون مقید کننده[۱۳] می داند که چگونه یک نمونه ژانر را به رشته و رشته را به ژانر تبدیل کند – همه این ها به خاطر این است که ShowEditor ثبت شده است.

  1. هنگامی که یک فرم ارسال می شود (معمولا این مورد زمانی اتفاق می افتد که یک درخواست POST به کنترلر ارسال شود)، در ابتدا کنترلر تشخیص می دهد که آیا sessionForm برابر true تنظیم شده است یا خیر. اگر چنین باشد، آنگاه شی فرمان را از جلسه واکشی می کند. اگر هیچ موردی پیدا نشد، تابع ()handleInvalidSubmit را فرا می خواند، که به طور پیش فرض فرم را مجدد ارسال می کند. البته سربارگذاری این متد امکان پذیر است.
  2. اگر sessionForm برابر false تنظیم شده باشد، کنترلر متد ()formBackingObject را دوباره فراخوانی می کند تا از این طریق شی فرمان را بدست آورد.
  3. پس از آن که مقید کننده ایجاد شد، انقیاد و اعتبارسنجی انجام می شود و callbackهای مربوطه فراخوانی می شود تا پردازش های سفارشی صورت پذیرد. به هر حال، اعتبارسنجی، می تواند با تنظیم suppressValidation به true از دور خارج شود.
  4. پس از آن که انقیاد انجام شد و اعتبارسنجی مورد تایید قرار گرفت، متد ()onSubmit فراخوانی می شود. به طور پیش فرض، اگر هیچ یک از متدها سربارگذاری نشوند، آخرین متدی که فراخوانی می شود ()doSubmitAction خواهد بود که مقدار void برمی گرداند و از successView پیکربندی شده توسط کنترلر استفاده می کند.

در صورتی که اعتبارسنجی رد شود، این روند کمی متفاوت خواهد بود، زیرا ما باید فرم را به همراه خطاهای به دست آمده از اعتبارسنجی، دوباره نمایش دهیم. این روند تا حدودی شبیه به نمایش فرم برای اولین بار است. همانطور که می دانید، تمام کنترلرهای Spring به عنوان مقدار بازگشتی خود یک ModelAndView ایجاد می کنند. این کار توسط کنترلرهای فرم نیز انجام می شود. مدلی که یک کنترلر فرم ایجاد می کند متشکل از سه چیز است:

  • شی فرمان (تحت عنوان کلیدی که در صورت پیکربندی، با استفاده از خاصیت commandName و در صورت عدم تغییر در پیکره بندی با نام command شناخته می شود).
  • خطاها (در صورت وجود)، توسط ابزار ویژه ای گردآوری می شوند.
  • شی داده بازگشته از متد ()referenceData، که درون مدل ادغام می شود.

هنگام سربارگذاری یکی از متدهای callback مانند ()onSubmit، شما می توانید به کاربر مجددا فرم را نمایش دهید (در صورت بروز خطا و یا موقعیت های دیگری که ممکن است به آن نیاز پیدا کنید). این کار با کمک فراخوانی showForm(HttpServletRequest request, BindException errors, String viewName) انجام می شود. این متد به نوبه خود، متد referenceData را فراخوانی کرده و view مناسب را بازمی گرداند. چیزی که باید به خاطر داشت این است که BindException در واقع شی فرمان را در بر دارد و اگر ما مدلی که از فراخوانی ()showForm برمی گردد را تحت کنترل خود درآورده و در کار مدل دخالت کنیم باعث بروز خطا خواهیم شد.

جایگزینی شی فرمان در طول فرآیند ارسال فرم، باید قبل از فراخوانی ()onSubmit یا با ایجاد یک BindException جدید و ارسال آن به متد ()showForm صورت پذیرد.

[۱] extend

[۲] Logical View

[۳] Binding

[۴] Context

[۵] Dependency Injection

[۶] Extend

[۷] Command Class

[۸] Command Object

[۹] Tag

[۱۰] Drop-down box

[۱۱] Domain Properties

[۱۲] Utility Class

[۱۳] Binder

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *