Spring形式ModelAttribute字段验证,以避免400 Bad Request Error

Mat*_*usz 6 java spring http-status-code-400 modelattribute

我有一个ArticleFormModel正常发送的包含数据,html form由Spring使用@ModelAttribute注释注入,即

@RequestMapping(value="edit", method=RequestMethod.POST)
public ModelAndView acceptEdit(@ModelAttribute ArticleFormModel model, 
    HttpServletRequest request, BindingResult errors)
{
    //irrelevant stuff
}
Run Code Online (Sandbox Code Playgroud)

在某些方面,一切都很完美.问题是ArticleFormModel包含一个double字段(protected使用普通的setter设置).只要用户发送的数据是数字,一切正常.当他们输入一个单词时,我得到的只是400 Bad Request Http Error.

我已经WebDataBinder为这个控制器注册了一个

@InitBinder
protected void initBinder(WebDataBinder binder) throws ServletException
{
    binder.setValidator(validator);
}
Run Code Online (Sandbox Code Playgroud)

where validator实现org.springframework.validation.Validator接口的自定义类的实例,但我不知道下一步该做什么.我希望能够解析模型,获得有效的HTTP响应并在表单中显示错误消息.initBinder()调用该方法,我可以从中调用validator.validate(),但它不会更改错误(对于错误的数据).

我知道我可以使用setter来解析字符串,检查它是否为数字,如果没有,将该信息存储在变量中,然后在验证期间检索该变量,但这似乎太多了.必须有一种更简单的方法来强制字段上的类型而不会出现错误.此外,问题在于数据绑定,而不是验证,所以我觉得它应该放在相应的代码层中.

我也在考虑实施java.beans.PropertyEditor和调用binder.registerCustomEditor(),但我缺乏可靠的知识来源.

客户端验证(通过JavaScript检查数据是否为数字)是不可能的.

TL; DR:

如何在@ModelAttribute不获取项目的情况下强制某个字段具有特定类型400 Bad Request Http Error

Shi*_*Kai 20

您可以使用<form:errors>绑定错误.

它看起来像这样:

控制器:

@RequestMapping(value="edit", method=RequestMethod.POST)
public ModelAndView acceptEdit(@ModelAttribute ArticleFormModel model, 
    BindingResult errors, HttpServletRequest request)
{
  if (errors.hasErrors()) {
    // error handling code goes here.
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

errors 参数需要放在模型后面的右侧.

有关详细信息,请参见下文(例17.1):

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-methods

JSP:

<form:form modelAttribute="articleFormModel" ... >
  ...
  <form:errors path="price" />
</form:form>
Run Code Online (Sandbox Code Playgroud)

消息属性文件:

typeMismatch.articleFormModel.price=customized error message
Run Code Online (Sandbox Code Playgroud)

  • 我永远不会认为参数的顺序很重要,并且`BindingResults`必须在`@ ModelAttribute`之后.谢谢你,现在它完美无缺! (9认同)