Today I'm trying to implement a validator using jaxrs, I'm only familiar with springmvc using spring-starter-validator and hibernate-validator wherein the errors are bind in the BindingResult using @restController. So as I was working around I made this solution works.
- create a custom global mapper for constraintViolationException.
public class ConstraintValidatorExceptionMapper implements ExceptionMapper<ConstraintViolationException>{ @Override public Response toResponse(ConstraintViolationException exception) { final Map<String, String> errorResponse = exception.getConstraintViolations() .stream() .collect(Collectors.toMap(o -> o.getPropertyPath().toString(), o -> o.getMessage())); return Response .status(Response.Status.BAD_REQUEST) .entity(errorResponse) .build(); } }
- Next create a payload request for your API.
@Data @NoArgsConstructor @AllArgsConstructor @Builder @CompareDates public class ViewTransactionHistoryRequest { @JsonProperty private String customerId; @JsonProperty private String cardSerNo; @JsonProperty @NotBlank(message="contact id must not be null or empty") private String contactId; @JsonProperty private String dateFrom; @JsonProperty private String dateTo; @JsonProperty private Double amountFrom; @JsonProperty private Double amountTo; @JsonProperty private int page; }
- Notice the
@CompareDates
I created a sample annotation validator for validating dates.
@Constraint(validatedBy = DateValidator.class) @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface CompareDates { String message() default "dateTo should not be less than dateFrom!"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
- Next for our endpoint we need to add
@Valid
to trigger the validation.
@POST @Path("/view-transaction") @Consumes("application/json") @ApiOperation(value = "Get transaction history") public Object fiterBy(@RequestBody @Valid ViewTransactionHistoryRequest request) { LOGGER.info("Get account contact transaction history"); return accountContactService.viewTransactionHistory(request); }
- Then register your custom validator in your jersey configuration file.
@Component public class JerseyConfig extends ResourceConfig { @Value("${spring.jersey.application-path}") private String basePath; public JerseyConfig() { register(ConstraintValidatorExceptionMapper.class); } }
That's it! Sample response in postman should be something like this:
In this way we can provide to the client which fields have errors instead of just relying the 400 bad request exception response.
Top comments (0)