Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom message for ConstraintValidator

I am using ConstraintValidator implementation as given below for validating request object for a spring boot REST service

@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = MyRequestValidator.class)
@Documented
public @interface MyRequestValidation {

    String message() default "Mandatory fields missing";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

public class MyRequestValidator
            implements
                ConstraintValidator<MyRequestValidation, MyRequest>{
   @Override
    public void initialize(MyRequestValidation constraintAnnotation) {
        // Nothing to do here
    }
   @Override
    public boolean isValid(MyRequest myRequest, ConstraintValidatorContext context) {
 //do some validation
     context.disableDefaultConstraintViolation();    
     context.buildConstraintViolationWithTemplate("Id can contain only alphabets and digits")
    .addPropertyNode("id")
    .addConstraintViolation();
   }
}

//REST end point
public interface RestApi{
  @Produces(MediaType.XML)
  @Consumes(MediaType.XML)
  @POST
  MyResponse action(@MyRequestValidation MyRequest myRequest);
}

@Component
public class RestApiImpl implements RestApi {
..
}

This produces output as

[PARAMETER]
[myRequest.arg0.id]
[Id can contain only alphabets and digits]

Is there anyway to produce JSON or XML message (or based on the @Produces annotation on the REST end point). I am using Hibernate implementations of these interface ConstraintValidatorContext

like image 485
Sajin Surendran Avatar asked May 04 '26 10:05

Sajin Surendran


1 Answers

Yes, you can capture ConstraintViolationException when occurs by implementing a custom error handler then you can add anything on your response and status as well.

1.- Simple way to change status when ConstraintViolationException is thrown.

import javax.validation.ConstraintViolationException;

@ControllerAdvice
public class CustomErrorHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    public void handleConstraintViolationException(ConstraintViolationException exception,
        ServletWebRequest webRequest) throws IOException {
        webRequest.getResponse().sendError(HttpStatus.BAD_REQUEST.value(), exception.getMessage());
    }
} 

2.- Custom way to put the response when a ConstraintViolationException occurs.

@ControllerAdvice
public class CustomErrorHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<CustomError> handleConstraintViolationException(ConstraintViolationException exception) {
        CustomError customError = new CustomError();
        customError.setStatus(HttpStatus.BAD_REQUEST);
        customError.setMessage(exception.getMessage());
        customError.addConstraintErrors(exception.getConstraintViolations());
        return ResponseEntity.badRequest().body(customError);
    }
}   
like image 155
Jonathan JOhx Avatar answered May 06 '26 00:05

Jonathan JOhx