@ModelAttribute在表单提交上返回一个新实例

时间:2014-08-02 02:49:08

标签: spring forms jsp spring-mvc spring-annotations

我正在开发基于Spring MVC的应用程序。流程如下:

  1. 从DB(映射到POJO的表)中获取数据
  2. 显示由POJO支持的表单(从步骤1开始)。并非所有字段都显示(如主键等)。
  3. 用户可以更新表单中的某些字段值,然后提交。
  4. 在我的Controller中使用@ModelAttribute注释接收更新的POJO时,我发现并非所有字段都填充在通过@ModelAttribute接收的POJO中。未映射到JSP上的所有字段(如主键)都设置为null或基本情况下的默认值。由于这个原因,我无法在数据库中更新相同内容。

    我找到的一个解决方案是我可以使用字段,但这听起来不是很有效的解决方案,因为我有大量的属性没有显示在JSP页面上。

3 个答案:

答案 0 :(得分:1)

模型属性只是一个美化的请求属性。请求属性仅在一个请求 - 响应周期的持续时间内生效。

  

HTTP请求->从数据库->获取POJO将POJO添加到模型属性->渲染JSP -> HTTP响应

之后,请求属性最终被GC化,因为应用程序无法再访问它们(servlet容器确保这一点)。

您发送的下一个请求将具有一组新的请求属性,与先前的请求无关。

当您从模型属性生成<form>时,Spring会从您选择的模型属性的字段中创建<input>元素。当您最终提交form时,只有这些值将作为请求中的请求参数发送。因此,您的应用程序只能访问那些生成新模型属性的应用程序。

您似乎需要会话属性或Flash属性(实际上只是短暂的会话属性)。

答案 1 :(得分:0)

如果有人知道更好的解决方案请告诉我,但是在我的应用程序中,我们总是发回所有那些我们希望在隐藏字段的请求响应中保留的id和其他值,但我认为是有点风险,例如在id的情况下。可用于SQLInjections攻击。

答案 2 :(得分:0)

您可以使用路径变量来传输主键(其他类型的URL ...)并充分利用Spring的所有魔力:

  • 创建一个DefaultFormattingConversionService bean(以保持默认转换)
  • 注册(在ConversionService中)Converter转换POJO中的字符串(字符串 - &gt;主键 - &gt;数据库中的对象)
  • 直接使用控制器方法中的路径变量

    @RequestMapping(value=".../{data}/edit", method=RequestMethod.GET)
    public String edit(@ModelAttribute("data") Pojo pojo) {
        return "view_with_form";
    }
    
    @RequestMapping(value=".../{data}/edit", method=RequestMethod.POST)
    public String update(@ModelAttribute("data") Pojo pojo, BindingResult result) {
        if (result.hasErrors()) {
            return "view_with_form";
        }
        return "redirect:.../data/edit";
    }
    

当您向控制器方法提供ModelAttribute时,Spring会尝试在会话或路径变量中找到它。即使您没有要求它,错误管理也不是很昂贵......