I implemented custom validation annotation for a request in Spring Rest Controller which validates if field2 is available in the input request body, then field1 should not be empty. My question is how do I get rid of Field UserInputDTO.userInputDTO in my error response (before passing it to the ExceptionHandler)?
Note: I need this because I don't want to expose sensitive data(Class name and Instance name) in the error response. I debugged this and tried but failed to remove the default path or base path(from PathImpl) from the object ConstraintValidatorContextImpl.
Error Response
{
status : 400
title : Bad Request: Field 'UserInputDTO.userInputDTO' : field1 should not be empty if Field2 is present
}
Annotation Class
@Documented
@Constraint(validatedBy = UserInputValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface UserInputConstraint {
String message() default "Invalid request";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Validator Class
public class UserInputValidator implements
ConstraintValidator<UserInputConstraint, UserInputDTO> {
@Override
public void initialize(UserInputConstraint userInputConstraint) {
}
@Override
public boolean isValid(UserInputDTO userInputDTO,
ConstraintValidatorContext cxt) {
boolean isValid=true;
String errorMessage = null;
if (userInputDTO.field2 != null && userInputDTO.field1 == null) {
isValid = false;
context.buildConstraintViolationWithTemplate("field1 should not be empty if Field2 is presen").addConstraintViolation();
}
return isValid;
}
You can @Override handleMethodArgumentNotValid
and customize your error response body.
Example:
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
public ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException exception, HttpHeaders headers, HttpStatus status,
WebRequest request) {
List<Object> errors = new ArrayList<Object>();
for (FieldError fielderror : exception.getBindingResult().getFieldErrors()) {
Map<String, Object> error = new HashMap<>();
error.put("code", fielderror.getCode());
error.put("message", fielderror.getDefaultMessage());
errors.add(error);
}
return new ResponseEntity<>(errors, apiError.getStatus());
}
}
And disable DefaultConstraintViolation
in annotation validator
context.disableDefaultConstraintViolation();