Spring @InitBinder not invoked when showing form => CustomEditors not defined
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,
Stijnuse @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>
精彩评论