使用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