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)