Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

完成优化的todo:添加缓存、业务异常的处理 #19

Closed
stick-i opened this issue Aug 19, 2024 · 1 comment · Fixed by #21
Closed

完成优化的todo:添加缓存、业务异常的处理 #19

stick-i opened this issue Aug 19, 2024 · 1 comment · Fixed by #21
Assignees
Labels
enhancement New feature or request

Comments

@stick-i
Copy link
Owner

stick-i commented Aug 19, 2024

  1. 添加缓存和调整验证的逻辑顺序,以降低耗时。
  2. 提供一种方案,在执行spel的过程中,允许开发者自行处理业务中抛出的异常。由于spel允许开发者调用其他类的方法,所以很可能会出现一些业务异常(BusinessServiceException)被抛出,这些异常应该继续交给开发者,让开发者自行处理。
@stick-i
Copy link
Owner Author

stick-i commented Aug 21, 2024

由于校验过程中抛出的任何异常,都会被更上层的校验器(hibernate-validator)所捕获,并且转换成 javax.validation.ValidationException 再继续抛出。

比如这样的场景:

    public static ExampleEnum getByCode(Integer code) {
        if (code == null) {
            throw new IllegalArgumentException("code can not be null");
        }
        for (ExampleEnum value : values()) {
            if (value.code.equals(code)) {
                return value;
            }
        }
        return null;
    }
    @Data
    @SpelValid
    public class ParamTestBean {

        /**
         * 枚举值校验
         * <p>
         * 通过静态方法调用,校验枚举值是否存在
         */
        @SpelAssert(assertTrue = " T(cn.sticki.validator.spel.enums.ExampleEnum).getByCode(#this.testEnum) != null ", message = "枚举值不合法")
        private Integer testEnum;

    }
      ParamTestBean bean = new ParamTestBean();
      bean.setTestEnum(null);

当使用如上面bean的对象去进行校验时,我们希望得到一个IllegalArgumentException,但实际上会得到一个ValidationException:

image

要从框架层面去解决这个问题,只能够脱离 javax.validation 的规范和 hibernate 的执行器来独自进行校验,目前看来这样做的成本比较大,且会带来一些其他的影响,暂时不考虑这样做。

还有一种解决方案,需要使用框架的开发者进行一点特殊处理。当捕获到 ValidationException e 时,首先判断下 e.getCause() 的类型是不是自己项目中的业务异常基类,如果是业务异常的类型,就丢给对应的方法去处理,像这样:

@ExceptionHandler({BusinessException.class})
public Resp<Void> handleServiceException(BusinessException ex) {
  return new Resp<>(ex.getCode(), ex.getMessage());
}

@ExceptionHandler({ValidationException.class})
public Resp<Void> handleValidationException(ValidationException ex) {
  if (ex.getCause() instanceof BusinessException) {
	  return handleBindException((BindException) ex.getCause());
  }
  return new Resp<>(500, "system error");
}

这种方案也有缺点,如果没有一个合适的基类,那么需要将多种不同的异常类型都进行特殊处理,比较麻烦。

目前决定还是先采用这种方案,后续有机会再做独立吧。

@stick-i stick-i changed the title 项目中还有几个优化的todo需要完成 完成优化的todo:添加缓存、业务异常的处理 Aug 21, 2024
@stick-i stick-i linked a pull request Aug 21, 2024 that will close this issue
@stick-i stick-i added the enhancement New feature or request label Aug 21, 2024
@stick-i stick-i closed this as completed Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

Successfully merging a pull request may close this issue.

1 participant