[英]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()
这个带注释的方法中。 但我在这里的困惑是:
@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.