我正在使用Spring MVC 3带注释的样式控制器开发应用程序.在某些情况下,我需要根据会话变量或某些其他条件来添加/修改一些字段值.为了使事情复杂化,如果某些条件匹配,则该字段可能具有固定值,否则,该字段可能具有读取用户输入的值.问题是:有一种方法可以在绑定之后但在使用Spring MVC 3进行验证之前修改表单?使用SimpleFormController(onBind方法)非常简单,但是我在Spring MVC 3中找不到方法.
一个例子:
a)我为表格初始化活页夹.添加验证器,设置允许字段的列表,并添加通用属性编辑器的列表
@InitBinder(value = COMMAND_NAME)
@Override
public void initBinder(final WebDataBinder binder, final HttpServletRequest httpServletRequest) {
binder.setValidator(reenvioAsientoValidator);
binder.setAllowedFields(ReenvioAsientoForm.getListaCamposPermitidos());
.... Add some custom property editors for booleans, integers ....
}
b)创建模型对象
@ModelAttribute(value = COMMAND_NAME)
public ReenvioAsientoForm rellenaModelo(final HttpServletRequest httpServletRequest) {
final ReenvioAsientoForm form = new ReenvioAsientoForm();
... Add some field values, which cannot be modified by user ...
return form;
}
c)绑定发生:它可以修改allowedFields列表中的任何字段.即使是我在阶段b)中设置的那些
d)这是我不能做的.我需要设置/修改表单的某些字段.无法在创建模型阶段完成,因为这些字段在allowedFields列表中(根据不同的条件,它们可以为只读或接受用户输入)
e)验证发生
f)调用控制器POST方法
@RequestMapping(value = URI_REENVIO_ASIENTO, method = RequestMethod.POST)
public ModelAndView submit(@Valid @ModelAttribute(COMMAND_NAME) final ReenvioAsientoForm form, final BindingResult result, HttpServletRequest request) {
.....
}
我尝试过的东西:
>在验证之前在验证器内部进行修改:这是一个可能的解决方案,但是我发现它很讨厌,因为我将验证器用于不想要的东西.另外,它仅在表单通过验证后才有效.
>使用CustomPropertyEditor.这样,我可以检查条件并在绑定期间设置值.问题在于,仅当请求中存在属性时才会触发绑定程序.如果总有办法开火,那将是一个不错的解决方案
解决方法:
最简单的解决方法是避免使用@Valid触发验证.
@Autowired
Validator validator;
@RequestMapping(value = URI_REENVIO_ASIENTO, method = RequestMethod.POST)
public ModelAndView submit(@ModelAttribute(COMMAND_NAME) final ReenvioAsientoForm form, final BindingResult result, HttpServletRequest request) {
// here comes the custom logic
// that will be executed after binding and before validation
// trigger validation
validator.validate(form, result);
// handle validation result and return view name
...
}
请参阅Spring JIRA中的相关问题以及此类钩子/注释将不被实现的说明-@MVC should provide an “onBind” hook prior to automatic validation.