使用Dubbo自带的参数校验

5,749 阅读1分钟

使用dubbo的参数校验

  • dubbo支持JSR-303的参数校验,只需要将validation="true",就相当于开启dubbo的ValidationFilter过滤器。
 <dubbo:service retries="0" version="1.0.0" interface="cn.gov.zcy.hammurabi.facade.service.ConfigReadFacade"
                   ref="configReadFacadeImpl" timeout="1000" validation="true"/>
  • 但是dubbo直接抛出的错误进行了多层的封装,如果想要直接使用这个参数校验不通过的错误比较困难,所以为了方便业务上的直接使用,使用自定义的参数校验器。

自定义参数校验器

  • 自定义的参数校验器完成的功能基本与ValidationFilter相同,所以代码基本上可以与ValidationFilter相同,主要将参数校验不通过时,抛出的错误(参数校验不通过dubbo内部抛出的错误是ConstraintViolationException)进行自己的封装和处理。

  • 为了将自己的校验器加入到dubbo框架中进行管理,需要实现Filter接口的invoke方法。并加入@Activate注解,标识为dubbo的 Filter

    @Slf4j
    @Activate(order = -100, value = {"validation"})
    public class ConfigValidationFilter implements Filter {
    
        private Validation validation;
    
        public void setValidation(Validation validation) {
            this.validation = validation;
        }
    
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
            try {
                Validator validator = this.validation.getValidator(invoker.getUrl());
                if (validator != null) {
                    validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
                }
            } catch (ConstraintViolationException e) {
                Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
                List<String> message = constraintViolations.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList());
                ConfigParamException configParamException = new ConfigParamException(message.toString());
                return new RpcResult(Response.fail(configParamException.getCode(), configParamException.getMessage()));
            } catch (RpcException var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new RpcException(var5.getMessage(), var5);
            }
            return invoker.invoke(invocation);
        }
    }
    
    
  • 将自定义的filter加入dubbo中还需要在dubbo.xml中和资源文件中进行配置

    dubbo.xml
    <!--参数校验filter-->
        <dubbo:provider filter="configValidationFilter"/>
    在META-INF文件夹下建一个dubbo的文件夹,并建一个com.alibaba.dubbo.rpc.Filter文件
    内容为:校验器的全路径
    configValidationFilter = cn.gov.zcy.hammurabi.facade.filter.ConfigValidationFilter