开发者

Spring @InitBinder not invoked when showing form => CustomEditors not defined

开发者 https://www.devze.com 2022-12-27 02:04 出处:网络
I have following (simplified to the bone) Controller: @Controller public class TestController{ @RequestMapping(value = \"/test.htm\", method = RequestMethod.GET)

I have following (simplified to the bone) Controller:

@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));
}开发者_如何学运维

}

The jsp:

<form:form commandName="reportPerResourceForm" id="reportForm">
    <form:input path="startDate" />
</form:form>

This is a controller I quickly created to test out an issue I had with another view-controller. As you can see in the Controller a CustomeDateEditor is defined. In my actual controller this editor is working fine; when you enter for instance 11/01/2010 in the form field this is nicely converted into a Date by the editor; also when going back to the form the Date was again nicely converted back to a String.

However, when I (as in TestController) want to set a default date on the form then this gets simply displayed a Date.toString() in the form field instead of using the returned value from CustomDateEditor.getAsText()! After some debugging I learned that my InitBinder method is not called when RequestMethod == GET. Is this normal?

I'm sure I could workaround this by not using

Thanks for your help,

Stijn


use @ModelAttribute to setup domain before forwarding to page.

carefully to use new when you deal with spring, it will just create a new instance of object outside spring context and you cannot use any of spring capability (such as web binding, validation, etc).

example :

@RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public String showForm(@ModelAttribute yourDomain, final ModelMap map)

and at your domain you can use :

@DateTimeFormat(pattern="dd/MM/yyyy")
private Date balance = new Date(System.currentTimeMillis());


I'm not sure but the second argument in registerCustomEditor method is set to null. This argument is to set the field name you want to associate the editor with, so I don't know exactly what it is going to happen when it's set to null. If you want to use this editor with all fields of a specific type it exists the same method without this parameter:

public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)

I would try with this, though I'm not sure this will solve the problem.

binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));

Hope it helps.


To solve this, I myself have following code in my Controller:



        @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);
        }
    }


My issues was with my "Category" class not being recognized, because @InitBinder was not being called. The "secret" here was to modify my "@RequestMapping" method to include - in it's prototype - 2 parameters which I do not need:
@ModelAttribute("category") Category category,
BindingResult result
This solved everything (I know it's not magic, just smoke, mirrors and Java reflection - but I wish the printed and online literature would address simple use-cases like this appropriately).

Here's the relevant code in my corresponding JSP file:



        <div>
        Select a category: 
        <form:select path="category">
                    <form:options items="${categoryList}" itemValue="id" itemLabel="name" 

    />
        </form:select>
        </div>

0

精彩评论

暂无评论...
验证码 换一张
取 消