【发布时间】:2019-11-11 07:00:13
【问题描述】:
我正在使用 Spring Boot 2.0.1,其中包含验证启动器(Hibernate Validation 6.x 附带)并尝试验证方法参数并在我的 Spring 存储库层中返回对象.这个方法基本上有ParamObj和ReturnObj,
@Repository
@Validated // Spring integration of validation
public class MyRepoImpl implements MyRepo {
@Override
@Valid
public ReturnObj myMethod(@Valid ParamObj param) throw CustomException {
try {
// makes a call that might throw an exception
} catch (Exception e) {
throw new CustomException(/*...*/, e);
}
return returnObj;
}
}
ParamObj 和 ReturnObj 都在它们的某些属性上使用一组简单的 Bean Validation 注释,例如 @Pattern、@Min 等。我的问题是,如果使用这些注释,如果 ParamObj或 ReturnObj 验证过程失败,MyRepoImpl#myMethod() 将抛出 javax.validation.ConstraintViolationException。
但是,如您所见,myMethod() 的合约要求抛出 CustomException。是的,ConstraintViolationException 是 RuntimeException,但是,现在是 MyRepoImpl#myMethod() 的调用者,例如一个服务层逻辑,除了CustomException之外,还需要捕获这个RuntimeException。
原因是,我需要防止所有异常冒出服务层(对于这个特殊的 Spring @Service 我有它调用这个存储库) -- 该服务是通过服务编排调用的一长串服务的一部分,该服务编排构造了一个更大的包含对象。换句话说,这部分(通过MyRepoImpl 获得的结果)被认为是可选,随后,它的失败应该只被记录但不要停止整个过程。
因此,我不能利用ControllerAdvice 为整个应用程序捕获ConstraintViolationException。
我的目标是,当任一方法参数或返回的验证失败时,仅将 CustomException 扔回给调用者。
这是否可能仅使用注释?我查看了MethodValidationPostProcessor,但不知道我是否可以实现自己的目标来实现这一目标。
附:我能想到的唯一方法是放弃@Valid/@Validated 并以编程方式调用Validator#validate(obj, ...) 以获取try-catch 块内的参数和返回值,捕获约束异常,然后抛出我的CustomException()。但是,我想知道我是否可以避免这种情况,并将这个硬编码验证排除在存储库之外。
【问题讨论】:
标签: java spring spring-boot bean-validation hibernate-validator