Spring表单支持对象问题

时间:2012-04-06 16:25:55

标签: spring controller

我正在努力解决Spring在POST期间处理表单后备对象的问题。正如预期的那样,在html表单中具有相应输入标记的ScreenObject属性在帖子中幸存。但是如果属性没有输入标记,则会出现两种情况:

  1. 如果将属性作为请求参数传入,则它会在帖子中存活。
  2. 如果未将属性作为请求参数传入,则它不会在帖子中存活。
  3. 这是我的代码。

    屏幕对象

    private Integer hostSiteSectionId; // no input tag but survives if passed as a request param
    private String name;  // input tag so survives
    private String orderFactor; // input tag so survives
    
    private Integer hostSiteId; // no input tag but survives if passed as a request param
    private String hostSiteName; // no input tag and not passed as request param so does not survive
    

    获取

    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView edit(@RequestParam(value="hostSiteId", required=false) Integer hostSiteId, @RequestParam(value="hostSiteSectionId", required=false) Integer hostSiteSectionId, Locale locale) {
        HostSiteSectionHeaderEditScreenObject screenObject=new HostSiteSectionHeaderEditScreenObject();
    
        initializeScreenObject(hostSiteId, hostSiteSectionId, screenObject, locale, true);
    
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("screenObject", screenObject);
        modelAndView.setViewName(WebView.HOST_SITE_SECTION_HEADER_EDIT_PAGE.getViewName());
        return modelAndView;    
    }
    

    以CANCEL发布

    @RequestMapping(method=RequestMethod.POST, params="cancel")
    public String cancel(@ModelAttribute("screenObject") HostSiteSectionHeaderEditScreenObject screenObject) {
        // logic that returns redirect
    }
    

    我的initializeScreenObject()方法只设置screenObject的属性。它不适用于该型号。我不知道它会如何干扰,所以我不会发布它的基本代码。

    在这篇文章中,它在其他帖子中的作用相同,因此screenObject具有以下内容:

    1. 存在用户通过输入标签在表单中提供的所有输入。没问题。
    2. 仅当getter url将其作为参数包含在内时,才会在screenObject中显示
    3. hostSiteId(无输入标记)(例如,编辑?hostSiteId = 2)
    4. 仅当getter url将其作为参数包含时,才会在screenObject中显示
    5. hostSiteSectionId(无输入标记)(例如,编辑?hostSiteSectionId = 2)
    6. 没有相应输入标记且未作为请求参数传入的所有其他属性为空。
    7. 进一步说明#4。我有一个screenObject.hostSiteName属性,它在initializeScreenObject()方法中设置。使用<td>${screenObject.getHostSiteName()}</td>正确呈现视图。现在我单击取消提交控件。当控制器接管提交时,此属性为null。

      请解释是否有预期。如果预料到,请解释如何去做。我想,我可以为那些需要在帖子中存活的属性添加隐藏的表单字段,但这有点像黑客。我希望有更好的答案。原始请求参数如何在后期操作中得到关注..?

1 个答案:

答案 0 :(得分:1)

这听起来像预期的行为。作为POST处理程序方法的参数传递的HostSiteSectionHeaderEditScreenObject实例与您在GET处理程序方法中放入模型的实例不同。默认情况下,它是Spring创建的新实例。 Spring将根据POST请求中的参数将值绑定到对象的字段。因此,如果POST中不存在参数(例如,因为您没有在HTML表单中输入该参数),那么该字段将不会被Spring设置,它将只是该字段的默认初始值。

听起来你想要的是将initializeScreenObject()应用于你的屏幕对象然后在那之后应用请求参数值?有几种方法可以解决这个问题。一种方法是使用@ModelAttribute注释控制器方法:

@ModelAttribute("screenObject")
public HostSiteSectionHeaderEditScreenObject initScreenObject(@RequestParam(value="hostSiteId", required=false) Integer hostSiteId, @RequestParam(value="hostSiteSectionId", required=false) Integer hostSiteSectionId, Locale locale) {
    HostSiteSectionHeaderEditScreenObject screenObject=new HostSiteSectionHeaderEditScreenObject();

    initializeScreenObject(hostSiteId, hostSiteSectionId, screenObject, locale, true);
}

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-methods

如果这样做,您的GET处理程序方法可以简化为只返回一个视图名称。