2

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

控制器方法如下:

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

其中SomethingParams 有一个token字段,并由Spring 从请求的JSON 正文中自动填写。

有没有办法自动在所有控制器方法上调用验证器来检查SomethingParams等参数是否具有有效令牌?

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

4

3 回答 3

3

您可以在这种情况下使用弹簧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);
}

最后,您需要添加的只是对象@Valid上的注释,SomethingParams它将被验证。

@RequestMapping(value = "/something", method = RequestMethod.POST)
public @ResponseBody Map something(@Valid @RequestBody SomethingParams params) {
    // ...
}
于 2013-05-14T13:30:39.953 回答
0

您可以使用带有注释的令牌字段创建基类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 实现自动验证参数。

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

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.1.Final</version>
</dependency>
于 2013-05-14T13:41:56.347 回答
0

您也可以实现自己的Aspect,它将拦截所有控制器方法并验证参数。这将使您有机会摆脱@Valid注释。但不幸的是,我没有时间举出完整的例子。

于 2013-05-14T13:44:38.183 回答