Spring 3 MVC请求validation

我有一个Spring 3.2应用程序,我创建了一个使用基于令牌的安全性的REST API。 每个REST JSON有效内容都包含一个“令牌”字段,用于执行安全validation。

控制器方法如下:

@RequestMapping(value = "/something", method = RequestMethod.POST) public @ResponseBody Map something(@RequestBody SomethingParams params) { } 

SomethingParams有一个token字段,并由Spring从请求的JSON主体自动填充。

有没有办法在所有控制器方法上自动调用validation器来检查诸如SomethingParams之类的参数是否具有有效令牌?

以前我使用过拦截器,并且令牌包含在查询字符串中,但是现在,因为它位于请求的主体中,所以我必须解析拦截器中的JSON才能检查它。 由于Spring已经解析了JSON以绑定参数,我很好奇是否有更聪明的方法。 理想情况下只需要一些全局或控制器级别的设置(不是每种方法)。

对于这种情况,您可以使用spring Validator

 @Component public class SomethingParamsValidator implements Validator { @Override public boolean supports(Class clazz) { return clazz.isAssignableFrom(SomethingParams.class); } @Override public void validate(Object o, Errors errors) { SomethingParams sp = (SomethingParams)o; validateToken(sp.getToken(), errors); } private void validateToken(String token, Errors errors) { if (!TokenUtils.isValid(token)) { errors.rejectValue("token", "foo", "Token is invalid"); } } } 

然后通过添加以下方法在Controller注册它

 @Autowired SomethingParamsValidator somethingParamsValidator; @InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(somethingParamsValidator); } 

最后,你需要添加的是SomethingParams对象上的@Valid注释,它将被validation。

 @RequestMapping(value = "/something", method = RequestMethod.POST) public @ResponseBody Map something(@Valid @RequestBody SomethingParams params) { // ... } 

您可以使用带有JSR-303 @NotNull注释的标记字段创建基类,并从中扩展。

 public class ParamsBase { @NotNull private String token; // getters, setters ... } public class SomethingParams extends ParamsBase {...} 

然后用@Valid标记参数:

 @RequestMapping(value = "/something", method = RequestMethod.POST) public @ResponseBody Map something(@Valid @RequestBody SomethingParams params) { // ... } 

Spring将在运行时使用JSR-303实现自动validation参数。

我通常使用hibernate-validator作为实现提供者:

  org.hibernate hibernate-validator 5.0.1.Final  

您还可以实现自己的Aspect ,它将拦截所有控制器方法并validation参数。 这将为您提供摆脱@Valid注释的机会。 但不幸的是,我没有时间充分的例子。