显示form =>时不调用Spring @InitBinder CustomEditors未定义

时间:2010-04-14 15:43:36

标签: binding spring-mvc annotations propertyeditor

我有以下(简化为骨骼)控制器:

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

这是我快速创建的控制器,用于测试我与另一个视图控制器的问题。正如您在Controller中看到的那样,定义了CustomeDateEditor。在我的实际控制器中,这个编辑器运行正常;当您在表单字段中输入例如11/01/2010时,编辑器可以很好地将其转换为日期;回到表单时,Date再次很好地转换回String。

但是,当我(如在TestController中)想要在表单上设置默认日期时,这将在表单字段中显示一个Date.toString(),而不是使用CustomDateEditor.getAsText()返回的值!经过一些调试后,我了解到RequestMethod == GET时我的InitBinder方法没有被调用。这是正常的吗?

我确信我可以通过不使用来解决这个问题

感谢您的帮助,
斯泰恩

3 个答案:

答案 0 :(得分:2)

在转发到页面之前使用@ModelAttribute设置域。

当你处理spring时,小心地使用new,它只会在spring上下文之外创建一个新的对象实例,你不能使用任何spring功能(比如web绑定,验证等)。

示例:

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

答案 1 :(得分:1)

我不确定,但registerCustomEditor方法中的第二个参数设置为null。这个参数是设置你想要与编辑器关联的字段名称,所以当它被设置为null时我不确切知道它会发生什么。如果要将此编辑器与特定类型的所有字段一起使用,则它与不带此参数的方法相同:

public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)

我会尝试这个,虽然我不确定这会解决问题。

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

希望它有所帮助。

答案 2 :(得分:0)

要解决这个问题,我自己在控制器中有以下代码:



        @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(“category”)类别类别,
            BindingResult结果
这解决了一切(我知道它不是魔术,只是烟雾,镜子和Java反射 - 但我希望它 印刷和在线文献将恰当地解决这样的简单用例。

这是我相应的JSP文件中的相关代码:



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

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