繁体   English   中英

用于onBind()的Spring MVC 3 Controller注释 - 如何?

[英]Spring MVC 3 Controller annotation for onBind() - how to?

我正在从Spring 2.5升级到Spring 3.2。 我有一个MVC控制器,以前扩展了CancellableFormController 它分别声明了initBinder()onBind()方法。 我重构了Controller以使用@Controller注释,并将重写的initBinder()方法切换为使用Spring MVC 3注释@initBinder

我的具体问题是,在Spring MVC 3中,从Spring 2.5升级,如何重构重写的onBind()方法以使用注释等价物? 现有方法的签名是:

@Override
protected void onBind(HttpServletRequest request, Object command, BindException errors)  throws Exception {
    MyCommand cmd = (MyCommand) command;
    ....
}

我想过使用@initBinder()并将之前的代码放在onBind()这个带注释的方法中。 但我在这里的困惑是:

  1. 这样做,代码是否会像以前一样在整个框架过程中同时被调用?
  2. 如何从@initBinder注释方法获取Command对象的句柄。

我可以将它声明为方法签名中的另一个参数,Spring MVC框架将确保我得到一个副本吗? 似乎在旧的onBind()方法中已经创建了Command对象(通过formBackingObject方法)。 我可以安全地假设使用@initBinder方法时也是如此吗?

感谢任何人的一些见解。 我正在努力加快Spring MVC流程的速度!

我现有的@initBinder方法签名是这样的:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    // register custom editor here.. etc
}

我希望我可以这样做:

@InitBinder
protected void initBinder(WebDataBinder binder, MyCommand cmd) {
   // register custom editor here.. etc
}

这是使用注释升级cancellableformcontroller onBind()方法的标准最佳实践方法吗?

尝试根据答案标记正确,仍然无法正常工作:

@InitBinder("myCommand")
protected void onBind(WebDataBinder binder) throws Exception {
    MyCommand cmd = (MyCommand) binder.getTarget();
    .... // do whatever was required here...
}

解决

请参阅下面我对zeroflag的评论。 使用onBind()中包含的相同逻辑创建一个私有方法,然后在onSubmit()注释方法(POST / GET)中验证命令对象后,调用现在已不存在的onBind()方法,将Command对象作为一个传递给参数。 类似于以下内容:

@RequestMapping(method=RequestMethod.POST) 
public ModelAndView onSubmit(@ModelAttribute("myCommand") MyCommand cmd, BindingResult result, <any other params> {

        new MyCommandValidator().validate(cmd, result);
        if (result.hasErrors()) {
            return new ModelAndView("context");
        }
        onBind(cmd, <any other params>);

        ... // do business stuff

}

它似乎是一个丑陋的解决方法,对我的特殊情况是好的。

您可以使用binder.getTarget()访问命令对象。 为控制器方法的每个模型参数调用@InitBinder 我们假设以下代码

@RequestMapping("/somePath")
public String myMethod(@ModelAttribute("user") User user,
                       @ModelAttribute("info") Info info) {

然后,您的initBinder方法至少被调用两次:对于User对象和Info对象。 要仅为特定对象调用它,请添加模型名称:

@InitBinder("user")

这样只会为User对象调用它。 但请注意,该方法可能仍会被多次调用,即使目标对象为null也是第一次。

如果要确保未自动设置某些字段,则可以在initBinder方法中使用setDisallowedFields()

如果您想进行一些验证,那么让JSR 303(Bean Validation)完成这项工作。

根据您的想法,控制器中的@ModelAttribute方法可以是一个解决方案:

@ModelAttribute("user")
public User createUser(HttpServletRequest request /*or whatever*/) {
  User user = new User();
  //check some parameters and set some attributes
  return user;
}

绑定发生之前创建用户对象。

最后一个解决方案可以是命令对象的消息或类型转换器,它从请求中创建对象。 这实际上与上面的示例相似,但与控制器无关,并且对于使用转换器创建的对象没有绑定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM