Spring @InitBinder is not called when a form is displayed => Non-standard parameters

I have the 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)); } 

}

jsp:

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

This is the controller that I quickly created to test the problem that I had with another controller. As you can see in the controller, CustomeDateEditor is defined. In my actual controller, this editor works fine; when you enter, for example, 11/01/2010 in the form field, it is beautifully converted to Date by the editor; also, returning to the form, the date is again beautifully converted back to a string.

However, when I (as in TestController) want to set the default date on the form, then it simply displays Date.toString () in the form field instead of using the return value from CustomDateEditor.getAsText ()! After some debugging, I found out that my InitBinder method is not called when RequestMethod == GET. This is normal?

I'm sure I can get around this without using

Thank you for your help,
Stein

0
source share
3 answers

use @ModelAttribute to configure the domain before redirecting to the page.

carefully use new when working with spring, it will simply create a new instance of the object outside the context of spring, and you will not be able to use any spring features (for example, network binding, validation, etc.).

example:

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

and in your domain you can use:

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

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

 public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor) 

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

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

Hope this helps.

+1
source

To solve this problem, I have the 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); } }
@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 problems were that my β€œCategory” class was not recognized because @InitBinder was not called. The "secret" here was to modify my "@RequestMapping" method to include a prototype in it - 2 parameters that I do not need:
@ModelAttribute ("category") Category category,
Result BindingResult
It all solved (I know that this is not magic, just smoke, mirrors and Java reflection), but I wish print and online literature will address simple use cases like this, respectively).

Here is 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
source

Source: https://habr.com/ru/post/1264499/


All Articles