My Annotation class:
public @interface CustomAnnotation {
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { })
@Pattern(regexp="^[0-9]{12}", message="Validate Number Must be 12 Digit.")
public @interface ValidateNumber {
String message() default "{javax.validation.constraints.Size.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@interface List {
Size[] value();
}
}
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {AccountLocation.class })
public @interface ValidateVisitLocation {
String message() default "Invalid Site Location.";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
}
On ValidateVisitLocation class, I have created custom annotation AccountLocation.
public class AccountLocation implements ConstraintValidator<ValidateVisitLocation, String> {
@Value("${siteLocation}")
String siteLocation;
@Override
public void initialize(ValidateVisitLocation constraintAnnotation) {
// TODO Auto-generated method stub
}
@Override
public boolean isValid(String contactField, ConstraintValidatorContext cxt) {
return contactField != null && siteLocation.contains(contactField.substring(0, 3));
}
}
In my property file:
siteLocation=001,002,003,004,005
My controller class:
@Controller
@Validated
public class WelcomeController {
@GetMapping("/v1")
public ResponseEntity<String> get(@RequestParam String name) {
return new ResponseEntity<String>(name, HttpStatus.OK);
}
@GetMapping("/v2")
public String getAccount(@ValidateNumber @ValidateVisitLocation @RequestParam String accountId) {
return "welcome";
}
@PostMapping("/v3")
public ResponseEntity<Customer> post(@RequestBody @Valid Customer customer) {
return new ResponseEntity<Customer>(customer, HttpStatus.CREATED);
}
}
I have controller advice exception handling:
@ControllerAdvice
public class DataValidationExceptionHandler {
@ExceptionHandler
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map handle(MethodArgumentNotValidException exception) {
return error(exception.getBindingResult().getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.toList()));
}
@ExceptionHandler
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map handle(ConstraintViolationException exception) {
return error(exception.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toList()));
}
private Map error(Object message) {
return Collections.singletonMap("error", message);
}
}
When I hit the GET request http://127.0.0.1:8080/v2?accountId=999000
I am getting both error message
{"error":["Invalid Site Location.","Validate Number Must be 12 Digit."]}
I am looking for if @ValidateNumber
failed, do not look for @ValidateVisitLocation
.