【发布时间】:2019-10-15 17:36:54
【问题描述】:
我正在开发一个基于 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 {};
}
验证器类:
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);
}
控制器:
@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 响应代码,但我没有看到任何包含违反约束消息的响应正文。
【问题讨论】:
-
我也有一个通用的异常处理程序(用于
Exception),但这也没有捕捉到它。我假设异常是由 Spring 在内部处理并包装到其他东西中,但我不知道那是什么。当对象未通过验证(isValid()返回 false)时,不应该抛出ConstraintViolationException吗? -
您检查过
birthDate是否为空吗? -
是的(见上文)。我的日志中或调试时没有发现异常。
-
在另一个线程上,有人提醒我们RestController类也需要“@Validated”注解。
标签: java spring spring-boot annotations bean-validation