Spring @initBinder لم يتم الاحتجاج بها عند عرض النموذج => لم يتم تعريف المخصصين
-
26-09-2019 - |
سؤال
لدي جهاز تحكم متابع (مبسط حتى العظام):
@Controller
public class TestController {
@RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public String showForm(final ModelMap map) {
final TestFilter filter = new TestFilter();
filter.setStartDate(new Date(System.currentTimeMillis()));
map.addAttribute("reportPerResourceForm", filter);
return "test";
}
@InitBinder
public void initBinder(final WebDataBinder binder) {
binder.registerCustomEditor(Date.class, null, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
}
}
JSP:
<form:form commandName="reportPerResourceForm" id="reportForm">
<form:input path="startDate" />
</form:form>
هذه وحدة تحكم قمت بإنشائها بسرعة لاختبار مشكلة واجهت مع مراقبة عرض أخرى. كما ترون في وحدة التحكم ، يتم تعريف CustomEdateEditor. في جهاز التحكم الفعلي الخاص بي ، يعمل هذا المحرر بشكل جيد ؛ عندما تدخل على سبيل المثال 11/01/2010 في حقل النموذج ، يتم تحويل ذلك بشكل جيد إلى تاريخ بواسطة المحرر ؛ أيضًا عند العودة إلى النموذج ، تم تحويل التاريخ مرة أخرى إلى سلسلة.
ومع ذلك ، عندما أرغب (كما في TestController) في تعيين تاريخ افتراضي في النموذج ، يتم عرض هذا ببساطة تاريخ. بعد بعض تصحيح الأخطاء ، علمت أن طريقة initbinder الخاصة بي لا يتم استدعاؤها عند الحصول على requestMethod == Get. هل هذا طبيعي؟
أنا متأكد من أنه يمكنني حل هذا من خلال عدم الاستخدام
شكرا لمساعدتك،
stijn
المحلول
استعمال @ModelAttribute
لإعداد المجال قبل إعادة التوجيه إلى الصفحة.
بعناية للاستخدام new
عندما تتعامل مع الربيع ، فإنه سيقوم فقط بإنشاء مثيل جديد للكائن خارج سياق الربيع ولا يمكنك استخدام أي من إمكانات الربيع (مثل ربط الويب والتحقق من الصحة وما إلى ذلك).
مثال :
@RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public String showForm(@ModelAttribute yourDomain, final ModelMap map)
وفي مجالك يمكنك استخدامه:
@DateTimeFormat(pattern="dd/MM/yyyy")
private Date balance = new Date(System.currentTimeMillis());
نصائح أخرى
لست متأكدًا ولكن تم تعيين الوسيطة الثانية في طريقة RecordCustomeditor على Null. هذه الوسيطة هي تعيين اسم الحقل الذي تريد ربط المحرر به ، لذلك لا أعرف بالضبط ما الذي سيحدث عندما يتم تعيينه على NULL. إذا كنت ترغب في استخدام هذا المحرر مع جميع الحقول من نوع معين ، فهو موجود نفس الطريقة بدون هذه المعلمة:
public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)
سأحاول ذلك ، على الرغم من أنني لست متأكدًا من أن هذا سيحل المشكلة.
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
أتمنى أن يساعد ذلك.
لحل هذا ، أنا نفسي لدي رمز يتبع في وحدة التحكم الخاصة بي:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor(categoryService));
}
@ModelAttribute("categoryList") // Populate reference-data (EG select-lists) in the view. (p. 390-
391).
public List<Category> populateCategoryList() {
return categoryService.list();
}
// Note: without adding "BindingResult result" to the following prototype
// (and preceding it with a @ModelAttribute("categoryList") -
// my initBibder() method does not get called!
// I discovered and added this hokum in response to the following links:
// http://forum.springsource.org/showthread.php?46837-InitBinder-not-called
// http://forum.springsource.org/showthread.php?46876-Custom-date-format-on-GET-requests&p=154820
@RequestMapping("/site/list.htm")
@ModelAttribute("sites") // 20110819
public ModelAndView listSite(
@ModelAttribute("category") Category category,
BindingResult result
)
{
// List<Site> sites = siteService.list();
List<Site> sites = new ArrayList<Site>(); // = siteService.list();
return new ModelAndView("siteList", "sites", sites);
}
}
كانت مشاكلي مع عدم التعرف على صفي "فئتي" ، لأنه لم يتم استدعاء initBinder. كان "السر" هنا هو تعديل طريقة "requestmapping" لتضمين - في النموذج الأولي - 2 معلمات لا أحتاج إليها:
modelattribute ("الفئة") فئة فئة ،
نتيجة bindingresult
هذا يحل كل شيء (أعلم أنه ليس سحراً ، فقط الدخان والمرايا وانعكاس Java - لكنني أتمنى أن تعالج الأدبيات المطبوعة وعبر الإنترنت حالات الاستخدام البسيطة مثل هذا بشكل مناسب).
إليك الرمز ذي الصلة في ملف JSP المقابل:
<div>
Select a category:
<form:select path="category">
<form:options items="${categoryList}" itemValue="id" itemLabel="name"
/>
</form:select>
</div>