代码之家  ›  专栏  ›  技术社区  ›  Boden

SpringMVC,当使用setDisallowedFields时,一个用于“添加”和“更新”的控制器?

  •  3
  • Boden  · 技术社区  · 16 年前

    所以我有一个简单的表单,通过它我可以“添加”一个新的东西,或者“更新”一个现有的东西。

    我想要的是有一个控制器,可以处理添加和更新。一开始这看起来很简单,直到我考虑在initbinder中使用setdisallowedfields的问题,这样在添加新内容时就不允许使用“id”字段。

    目前,我有两个控制器,除了initbinder方法之外,它们的代码可能是相同的。

    有什么建议或建议吗?(如果你能给我很好的理由的话,我也愿意保留两个控制器)

    3 回复  |  直到 15 年前
        1
  •  3
  •   Andrew Swan    15 年前

    实际上,在添加和更新时都应该禁用“id”字段。否则,恶意用户可能篡改更新请求的“id”请求参数的值,从而将不同的记录更新到表单所示的记录(假设没有acl或其他域级安全性)。

    但是,如果您只是不允许“id”字段,那么控制器会将id视为空,这在插入时有效,但在更新时无效(例如,它可能会尝试插入新记录而不是更新,这取决于您使用的持久性机制)。因此,您希望控制器记住请求之间域对象的不可编辑值(不仅仅是id,而是所有不允许的字段),以便它可以将所有正确的值发送到服务层或其他业务逻辑。这是使用type level@sessionattributes注释完成的,如下所示(为清楚起见省略了其他注释):

    @SessionAttributes("thing") // the name of your domain object in the model
    public class ThingController {
    
        public void setDisallowedFields(WebDataBinder binder) {
            binder.setDisallowedFields("id", "someOtherUneditableField");
        }
    
        // request handling methods go here as before
    }
    

    为了更好的安全性,请设置允许的字段,而不是不允许的字段。无论哪种方式,您都需要@sessionattributes注释来填充请求中忽略的任何现有字段值。

        2
  •  2
  •   matt b    16 年前

    方法签名到 initBinder 接受 HttpServletRequest :

    protected void initBinder(HttpServletRequest request, 
        ServletRequestDataBinder binder)
    

    所以也许你可以 initBinder() 检查请求参数以确定是否应按条件设置 setDisallowedFields ?

    (如果这没有帮助,也许我没有正确理解问题…)

        3
  •  1
  •   Mark    16 年前

    使用单个控制器的方法是在命令对象上有一个布尔值,指示它是否是新对象。在onsubmit中,我可以检查布尔值,看看是否需要执行添加或更新操作。