Spring @initBinder لم يتم الاحتجاج بها عند عرض النموذج => لم يتم تعريف المخصصين

StackOverflow https://stackoverflow.com/questions/2638848

سؤال

لدي جهاز تحكم متابع (مبسط حتى العظام):

@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>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top