我正在使用带有身份验证启动程序( Hibernate Validation 6.x 附带)的Spring Boot 2.0.1,并尝试验证方法参数并在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
在它们的某些属性(例如@Pattern
,@Min
等上)都使用了一套简单的Bean验证批注。我的问题是这些注释,如果ParamObj
或ReturnObj
未能通过验证过程,则MyRepoImpl#myMethod()
会抛出javax.validation.ConstraintViolationException
。
但是,正如您所看到的,myMethod()
的合同要求抛出CustomException
。是的,ConstraintViolationException
是RuntimeException
,但是现在MyRepoImpl#myMethod()
的调用者,例如服务层逻辑,除了RuntimeException
之外,还需要捕获此CustomException
。
原因是,我需要防止将所有冒泡从服务层冒出(对于这个特定的Spring @Service
,我有哪些电话此存储库)-该服务是一长串服务的一部分,这些服务通过服务编排调用,该服务编排构造了一个更大的包含对象。换句话说,这部分(通过MyRepoImpl
获得的结果)被认为是可选,随后,其失败应该仅记录下来,不要停止整个过程 >。
因此,我无法利用ControllerAdvice
来捕获整个应用程序的ConstraintViolationException
。
我的目标是,当方法参数或返回的验证失败时,只能将CustomException
返回给调用方。
只能使用注释吗?我调查了MethodValidationPostProcessor
,但不知道是否可以实现自己的目标。
P.S。我认为实现此目标的唯一方法是放弃@Valid
/ @Validated
并以编程方式为Validator#validate(obj, ...)
块内的参数和返回值调用try-catch
,捕获约束异常,然后扔掉我的CustomException()
。但是,我想知道是否可以避免这种情况,并将这种经过硬编码的验证从存储库中排除。
答案 0 :(得分:0)
由于我一年前不在这里,所以我没有回答,但是由于这是一个常见问题,从我与同学的经验中可以看出,我认为答案可能是@ControllerAdvice,它可以处理任何类型的异常 doc-> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html