当 Spring Boot 中使用 Hibernate Validator 的 Bean 验证失败时,如何抛出自定义异常?
Posted
技术标签:
【中文标题】当 Spring Boot 中使用 Hibernate Validator 的 Bean 验证失败时,如何抛出自定义异常?【英文标题】:How to Throw a Custom Exception When Bean Validation In Spring Boot with Hibernate Validator Fails? 【发布时间】: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()
。但是,我想知道我是否可以避免这种情况,并将这个硬编码验证排除在存储库之外。
【问题讨论】:
【参考方案1】:因为我一年前不在这里,所以我不会回答,但由于这是一个常见问题,我可以从我与同学的经验中看出,我认为答案可能是@ControllerAdvice,在任何类型的例外情况下都很方便 文档 --> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html
【讨论】:
ControllerAdvice
类仅捕获 ConstraintViolationException
。问题是,如何抛出自定义异常而不是为这些验证错误定义一个异常?
ControllerAdvice 捕获任何类型的扩展运行时的异常。
是的,这不是这里的问题。请重新阅读全文。以上是关于当 Spring Boot 中使用 Hibernate Validator 的 Bean 验证失败时,如何抛出自定义异常?的主要内容,如果未能解决你的问题,请参考以下文章
当用户使用 Spring Boot 登录失败时,如何在登录页面中显示错误消息?
当 Spring Boot 中使用 Hibernate Validator 的 Bean 验证失败时,如何抛出自定义异常?
当 logging.config 指向 logfj2 外部配置文件的错误文件位置时,spring-boot 应用程序停止