0

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

@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 中)想要在表单上设置默认日期时,它会简单地在表单字段中显示 Date.toString(),而不是使用来自 CustomDateEditor.getAsText() 的返回值!经过一些调试,我了解到当 RequestMethod == GET 时没有调用我的 InitBinder 方法。这是正常的吗?

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

谢谢你的帮助,
斯蒂恩

4

3 回答 3

3

用于@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());
于 2010-12-28T01:22:51.690 回答
1

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

public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)

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

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

希望能帮助到你。

于 2010-04-15T07:55:43.877 回答
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") Category category,
BindingResult 结果
这解决了一切(我知道这不是魔术,只是烟雾、镜子和 Java 反射——但我希望印刷和在线文献能够适当地解决这样的简单用例)。

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



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

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

于 2011-09-15T07:39:31.633 回答