我正在Spring Web MVC 3.0中运行一个webapp,我有许多控制器方法,其签名大致如下:
@RequestMapping(value = "/{level1}/{level2}/foo", method = RequestMethod.POST)
public ModelAndView createFoo(@PathVariable long level1,
@PathVariable long level2,
@RequestParam("foo_name") String fooname,
@RequestParam(value = "description", required = false) String description);
我想添加一些验证 - 例如,description
应限制在一定长度,或fooname
应仅包含某些字符。如果此验证失败,我想向用户返回一条消息,而不是仅抛出一些未经检查的异常(如果我让数据渗透到DAO层,那么无论如何都会发生这种情况)。我知道JSR303但没有使用它,并且不太了解如何在Spring上下文中应用它。
根据我的理解,另一种选择是将@RequestBody
绑定到整个域对象并在那里添加验证约束,但是目前我的代码设置为接受如上所示的各个参数。
使用此方法将验证应用于输入参数的最简单方法是什么?
答案 0 :(得分:38)
现在似乎有可能(尝试使用Spring 4.1.2),请参阅https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/
从上页摘录:
将MethodValidationPostProcessor添加到Spring @Configuration类:
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
将@Validated添加到控制器类
在@RequestParam之前使用@Size
@RequestMapping("/hi")
public String sayHi(@Size(max = 10, message = "name should at most 10 characters long") @RequestParam("name") String name) {
return "Hi " + name;
}
在@ExceptionHandler方法中处理ConstraintViolationException
答案 1 :(得分:29)
无论如何都没有内置任何内容,not yet。对于当前发行版本,如果需要自动验证,仍需要使用WebDataBinder将参数绑定到对象上。如果您正在使用SpringMVC,那么值得学习,即使它不是您完成此任务的首选。
它看起来像这样:
public ModelAndView createFoo(@PathVariable long level1,
@PathVariable long level2,
@Valid @ModelAttribute() FooWrapper fooWrapper,
BindingResult errors) {
if (errors.hasErrors() {
//handle errors, can just return if using Spring form:error tags.
}
}
public static class FooWrapper {
@NotNull
@Size(max=32)
private String fooName;
private String description;
//getset
}
如果你的类路径上有Hibernate Validator 4或更高版本并使用默认的调度程序设置它应该“正常工作。”
编辑,因为评论有点大:
你的方法签名中不是“预期”的一个对象Spring知道如何注入,例如HttpRequest
,ModelMap
等,将获得数据绑定。这只是通过将请求参数名称与bean属性名称和调用setter匹配来实现的。 @ModelAttribute
只是个人风格的东西,在这种情况下它没有做任何事情。 JSR-303与方法参数上的@Valid集成通过WebDataBinder
连接。如果使用@RequestBody
,则基于Spring为请求体确定的内容类型(通常仅来自http头)使用对象编组器。调度程序servlet(AnnotationMethodHandlerAdapter
实际上)不是有一种方法可以为任意编组器“翻转验证开关”。它只是将Web请求内容传递给消息转换器并获取一个Object。没有生成BindingResult对象,因此无论如何都无法设置错误。
您仍然可以将验证器注入控制器并在您获得的对象上运行它,它与填充@Valid
的请求参数上的BindingResult
没有神奇的集成。您。
答案 2 :(得分:17)
如果您有多个需要验证的请求参数(使用Http GET 或 POST )。您也可以创建自定义模型类并使用@ 有效以及@ ModelAttribute 来验证参数。这样您就可以使用Hibernate Validator或javax.validator api来验证参数。它是这样的:
请求方法:
@RequestMapping(value="/doSomething", method=RequestMethod.GET)
public Model dosomething(@Valid @ModelAttribute ModelRequest modelRequest, BindingResult result, Model model) {
if (result.hasErrors()) {
throw new SomeException("invalid request params");
}
//to access the request params
modelRequest.getFirstParam();
modelRequest.getSecondParam();
...
}
ModelRequest类:
class ModelRequest {
@NotNull
private String firstParam;
@Size(min = 1, max = 10, message = "You messed up!")
private String secondParam;
//Setters and getters
public void setFirstParam (String firstParam) {
this.firstParam = firstParam;
}
public String getFirstParam() {
return firstParam;
}
...
}
希望有所帮助。