Bean验证引发ConstraintViolationException时自定义JAX-RS响应

Fra*_*ois 6 java rest jax-rs resteasy bean-validation

Bean Validation是验证对象的好选择,但是如何在ConstraintViolationException抛出时自定义REST API的响应(使用RESTeasy)?

例如:

@POST
@Path("company")
@Consumes("application/json")
public void saveCompany(@Valid Company company) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

包含无效数据的请求将返回400具有以下正文的HTTP 状态代码:

[PARAMETER]
[saveCompany.arg0.name]
[{company.name.size}]
[a]
Run Code Online (Sandbox Code Playgroud)

这很好但不够,我想在JSON文档中规范化这些错误.

我该如何自定义此行为?

cas*_*lin 12

使用JAX-RS可以定义一个ExceptionMapper来处理ConstraintViolationExceptions.

从中ConstraintViolationException,您可以获得一组ConstraintViolation公开约束违规上下文,然后将您需要的详细信息映射到abitrary类并返回响应:

@Provider
public class ConstraintViolationExceptionMapper 
       implements ExceptionMapper<ConstraintViolationException> {

    @Override
    public Response toResponse(ConstraintViolationException exception) {

        List<ValidationError> errors = exception.getConstraintViolations().stream()
                .map(this::toValidationError)
                .collect(Collectors.toList());

        return Response.status(Response.Status.BAD_REQUEST).entity(errors)
                       .type(MediaType.APPLICATION_JSON).build();
    }

    private ValidationError toValidationError(ConstraintViolation constraintViolation) {
        ValidationError error = new ValidationError();
        error.setPath(constraintViolation.getPropertyPath().toString());
        error.setMessage(constraintViolation.getMessage());
        return error;
    }
}
Run Code Online (Sandbox Code Playgroud)
public class ValidationError {

    private String path;
    private String message;

    // Getters and setters
}
Run Code Online (Sandbox Code Playgroud)

如果您使用Jackson进行JSON解析,您可能需要查看此答案,显示如何获取实际JSON属性的值.