java - 如何在响应正文中返回 ConstraintViolationException 消息?

标签 java spring spring-boot annotations bean-validation

我正在开发一个基于 Spring Boot 的 REST API。我正在使用自定义 ConstraintValidator 注释验证输入实体。我的问题是我无法在响应中返回 ConstraintViolationException 消息。我的异常处理程序没有捕获异常(可能是因为它们被包装在其他类型的异常中)。

我可以得到一些关于如何处理这种情况的建议吗?

我在互联网上进行了搜索,但找不到适合我的解决方案,而且我还浪费了一些时间。

注释示例:

@Documented
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
@Constraint(validatedBy = BirthDateValidator.class)
public @interface ValidBirthDate {

    String message() default "The birth date is not valid.";

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

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

}

validator 类:

public class BirthDateValidator extends FieldValidationBase implements ConstraintValidator<ValidBirthDate, LocalDate> {

    private static final Logger LOGGER = LoggerFactory.getLogger(BirthDateValidator.class);

    @Override
    public void initialize(ValidBirthDate constraintAnnotation) {
    }

    @Override
    public boolean isValid(LocalDate birthDate, ConstraintValidatorContext constraintValidatorContext) {
        constraintValidatorContext.disableDefaultConstraintViolation();
        LOGGER.info("Starting the validation process for birth date {}.", birthDate);

        if(birthDate == null) {
            constraintValidatorContext.buildConstraintViolationWithTemplate("The birth date is null.")
                    .addConstraintViolation();
            return false;
        }

        //other validations

        return true;
    }

模型类:

public class Manager extends BaseUser {

    //other fields 

    @Valid
    @ValidBirthDate
    private LocalDate birthDate;

    //setters & getters

异常处理程序:

@ExceptionHandler(value = ConstraintViolationException.class)
    public ResponseEntity handleConstraintViolationException(ConstraintViolationException ex, WebRequest request) {
        List<String> errors = new ArrayList<>();

        for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            errors.add(violation.getRootBeanClass().getName() + ": " + violation.getMessage());
        }

        Error response = new Error(errors);
        return new ResponseEntity<Object>(response, new HttpHeaders(), BAD_REQUEST);
    }

Controller :

@RestController
@RequestMapping(value = "/register", consumes = "application/json", produces = "application/json")
public class RegistrationController {

    @Autowired
    private RegistrationService registrationService;

    @PostMapping(value = "/manager")
    public ResponseEntity registerManager(@RequestBody @Valid Manager manager) {
        registrationService.executeSelfUserRegistration(manager);
        return new ResponseEntity<>(new Message("User " + manager.getEmailAddress() + " registered successfully!"), CREATED);
    }
}

我收到 400 响应代码,但没有看到任何包含违反约束消息的响应正文。

最佳答案

经过更多调试后,我发现所有约束违规都被包装到 MethodArgumentNotValidException 中(因为 @Valid 注释) - 我必须深入挖掘一下获取我的信息的异常。

我已经重写了 ResponseEntityExceptionHandler 中的 handleMethodArgumentNotValid() 方法,这就是我让它工作的方式:

@Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

        List<String> errorMessages = new ArrayList<>();
        BindingResult bindingResult = ex.getBindingResult();
        List<ObjectError> errors = bindingResult.getAllErrors();
        for(ObjectError error : errors) {
            String message = error.getDefaultMessage();
            errorMessages.add(message);
        }

        return new ResponseEntity<>(new Error(errorMessages), new HttpHeaders(), BAD_REQUEST);
    }

也许这对某人有帮助。

关于java - 如何在响应正文中返回 ConstraintViolationException 消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58399947/

相关文章:

java - 使用 JaCoCo 和 spring-boot-maven-plugin 生成代码覆盖率

tomcat - 在集成测试期间服务未使用 Spring-boot 启动

java - Wicket:避免将 ListChoice 的模型分配给表单的模型

c# - Java 和 C# 和 Python 一样是 "customizable"吗?

java - 使用 ApplicationContext 在运行时以编程方式修改 spring bean

web-services - CXF jaxws 端点相对发布地址

java - Spring 启动1.5.2.RELEASE : Rolling File logging

java - 数据推送时如何监听

java - 文档的根元素不是 <xsd :schema>

java - @RetryTransaction : how to make it work when deadlock was found