/ / @RestController: valide le @ResponseBody (pas le @RequestBody) - spring, spring-mvc

@RestController: Validez le @ResponseBody (pas le @RequestBody) - spring, spring-mvc

Comment puis-je faire pour que le @ResponseBody (dans moncas, une classe de type SomePojoInterface) est automatiquement validée (disons via la validation JSR-303). Il serait agréable d’avoir, en cas d’échec de la validation, que le gestionnaire Exception qui peut être manipulé dans certains @ControllerAdvice classe annotée

Mon code jusqu'ici

@RestController
public class MyRestController {

@GetMapping(value = "validate", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
protected SomePojo validateResponse() {
return new SomePojo();
}
}

@ControllerAdvice
class GlobalControllerExceptionHandler {

@ResponseStatus(HttpStatus.XXX)
@ExceptionHandler(MyResponseValidationException.class)
public void handleResponseValidationException() {
// ...
}
}

public class SomePojo implements SomePojoInterface {

@NotNull
private String someValue;

// getter / setter
}

Réponses:

0 pour la réponse № 1

Si vous avez annoté votre classe SomePojo, alors:

     @GetMapping(value = "validate", produces = MediaType.APPLICATION_JSON_VALUE)
protected SomePojo validateResponse() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

SomePojo somePojo = new SomePojo(null);

Set<ConstraintViolation<Car>> constraintViolations = validator.validate(somePojo);
// Other stuff
}

L'annotation @Valid est à la demande. Plus d'exemples de leur docs. Je ne suis pas sûr de ce que vous voulez valider


0 pour la réponse № 2

J'ai réussi à y parvenir grâce à la @RestControllerAdvice.

@RestControllerAdvice
public class RestPostProcessingAdvice implements ResponseBodyAdvice<SomePojoInterface> {

@Inject
private Validator validator;

@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
if(doSomeChecksIfEligiable(returnType, converterType)) {
return true;
}
return false;
}

@Override
public SomePojoInterface beforeBodyWrite(SomePojoInterface body, MethodParameter returnType,
MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(body);
if(constraintViolations.size() > 0) {
response.setStatusCode(HttpStatus.XXX);
LOG.fatal("Sorry, I"m sending crap");
}

return body;
}
}

Sachez que lancer un Exception et l'attraper dans un @ExceptionHandler qui envoie le même objet (mofifié) dans le @ResponseBody pourrait conduire à une boucle sans fin, puisque l'objet sera vérifié à nouveau cette @RestControllerAdvice.