Reputation: 342
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:
Upvotes: 1
Views: 3086
Reputation: 49925
A lot of what you are doing manually can be completely handled by Spring MVC, you should be able to get your method to this structure:
@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();
}
with Spring MVC taking care of calling JAXB unmarshaller and @Valid
annotation on the type taking care of the validation.
Now to register a custom validator for your types, you can do this:
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(this.authenticationValidator );
}
If you want to set it globally instead of for a specific controller, you can create your custom global validator, internally delegating to other validators, for eg:
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
}
}
and register this global Validator:
<mvc:annotation-driven validator="globalValidator"/>
Upvotes: 1