提问者:小点点

如何在Spring Boot中使用Hibernate Validator进行Bean验证失败时抛出自定义异常?


我使用的是Spring Boot 2.0.1,包含了Validation-starter(Hibernate Validation 6 . x附带的),并尝试在我的Spring repository层中验证方法参数并返回对象。这个方法基本上有一个< code>ParamObj和< code>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;
  }
}

ParamObjReturnObj都在它们的某些属性上使用一组简单的Bean验证注释,例如@Pattern@Min等,MyRepoImpl#myMethod()将抛出javax.validation.ConstraintViolationException

但是,正如您所看到的,myMethod()的契约要求抛出CustomException。是的,ConstraintViolationException是一个RuntimeException,但是,现在MyRepoImpl#myMethod()的调用方,例如服务层逻辑,除了CustomException之外,还需要捕获这个RuntimeException

原因是,我需要防止所有异常从服务层冒泡(对于这个特定的 Spring @Service,我有它调用这个存储库)——这个服务是通过服务编排调用的一长串服务的一部分,它构造了一个更大的包含对象。换句话说,这块(通过MyRepoImpl获得的结果)被认为是可选的,因此,它的失败应该只被记录,但不要停止整个过程。

出于这个原因,我无法使用控制建议来捕获整个应用程序的约束暴力异常

我的目标是,当方法参数或返回的验证失败时,能够仅将 CustomException 抛回调用方。

仅通过注释就可以做到这一点吗?我查看了方法验证后处理器,但不知道我是否可以实现自己的来实现这个目标。

我能想到的实现这一点的唯一方法是放弃< code > @ Valid /< code > @ Validated 并调用< code>Validator#validate(obj,...)以编程方式获取< code>try-catch块中的参数和返回值,捕获约束异常,并引发my < code > custom exception()。然而,我想知道我是否可以避免这种情况,并且将这种硬编码的验证从存储库中删除。


共1个答案

匿名用户

由于一年前我不在这里,所以我不会回答,但由于这是一个常见的问题,因为我可以通过我与同学的经验看到,我认为答案可能是@ControllerAdvice,任何类型的例外文档都派上用场——