1

I have a controller that receives as @RequestBody a string containing a request XML.

@RequestMapping(method = RequestMethod.POST, value="/app-authorization")
public Response getAppAuthorization(
        HttpServletResponse response, BindingResult results,
        @RequestBody String body){
    log.info("Requested app-authorization through xml: \n" + body);

    Source source = new StreamSource(new StringReader(body));
    RefreshTokenRequest req = (RefreshTokenRequest) jaxb2Mashaller.unmarshal(source);

    validator.validate(req, results);
    if(results.hasErrors()){
        log.info("DOESN'T WORK!");
        response.setStatus(500);
        return null;
    }
    InternalMessage<Integer, Response> auth = authService.getRefreshToken(req);
    response.setStatus(auth.getHttpStatus());
    return auth.getReponse();
}

The AuthorizationValidator is the following:

@Component("authenticationValidator")
public class AuthenticationValidator implements Validator{

    public boolean supports(Class<?> clazz) {
        return AuthorizationRequest.class.isAssignableFrom(clazz);
    }

    public void validate(Object target, Errors errors) {
        errors.rejectValue("test", "there are some errors");

    }
}

I'd like to know if there's a way to inject an object Validator into my controller in such a way that:

  1. @Autowired \n Validator validator; makes me obtain automatically a reference to my AuthenticationValidator
  2. every controller is linked to one or more validators withouth indicating their class explicitly.
4

1 回答 1

1

你手动做的很多事情都可以完全由 Spring MVC 处理,你应该能够让你的方法得到这个结构:

@RequestMapping(method = RequestMethod.POST, value="/app-authorization")
public Response getAppAuthorization(@Valid @RequestBody RefreshTokenRequest req, BindingResult results){

    if(results.hasErrors()){
        log.info("DOESN'T WORK!");
        response.setStatus(500);
        return null;
    }
    InternalMessage<Integer, Response> auth = authService.getRefreshToken(req);
    response.setStatus(auth.getHttpStatus());
    return auth.getReponse();
}

Spring MVC 负责调用 JAXB 解组器,并@Valid在类型上进行注释以负责验证。

现在要为您的类型注册一个自定义验证器,您可以这样做:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.setValidator(this.authenticationValidator );
}

如果您想全局设置它而不是针对特定控制器,您可以创建自定义全局验证器,在内部委托给其他验证器,例如:

public class CustomGlobalValidator implements Validator {

    @Resource private List<Validator> validators;

    @Override
    public boolean supports(Class<?> clazz) {
        for (Validator validator: validators){
            if (validator.supports(clazz)){
                return true;
            }
        }
        return false;
    }

    @Override
    public void validate(Object obj, Errors e) {
        //find validator supporting class of obj, and delegate to it

    }
}

并注册这个全局验证器:

<mvc:annotation-driven validator="globalValidator"/>
于 2012-11-03T20:52:45.663 回答