dubbo validation,ValidationFilter

dubbo可以实现类似spring mvc validation一样的功能,基于注解实现参数的校验

此处默认认为已经有可用的 dubbo环境,,

测试项目使用 SpringBoot 2.X + dubbo2.7.X

1、添加 校验相关的 依赖

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.0.Final</version>
</dependency>

定义接口和实现


public interface IUserService {

    CommonResponse<Long> addUser(UserAddBO userAddBO);

}


@Service
public class UserService implements IUserService {
    @Override
    public CommonResponse<Long>  addUser(@NotNull UserAddBO userAddBO) {
        System.out.println(userAddBO.toString());
        return CommonResponse.success(1L);
    }
    
}
@Data
public class UserAddBO implements Serializable {

    @NotNull
    private String name;

    @NotNull
    @Min(value = 1,message = "年龄不能小于0")
    private Integer age;

    @NotNull
    @Size(min = 1, max = 50,message = "地址长度不能大于50")
    private String address;

}

默认情况下,校验不通过会抛出异常,此处,我们包装一下异常,返回相应的错误信息和状态码给上游调用方

实现 dubbo中的 ListenableFilter


@Slf4j
@Activate(group = CommonConstants.PROVIDER)
public class DubboExceptionFilter extends ListenableFilter {

    public DubboExceptionFilter() {
        super.listener = new DubboExceptionFilter.ExceptionListener();
    }


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        return invoker.invoke(invocation);
    }

    static class ExceptionListener implements Listener {

        @Override
        public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
            if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
                try {
                    Throwable exception = appResponse.getException();
                    if (exception instanceof ConstraintViolationException) {
                        ConstraintViolationException realException = (ConstraintViolationException) exception;
                        if (invocation instanceof RpcInvocation) {
                            RpcInvocation realInvocation = (RpcInvocation) invocation;
                            Class<?> returnType = realInvocation.getReturnType();
                            if (returnType.isAssignableFrom(CommonResponse.class)) {
                                String errorMsg = CollectionUtils.isEmpty(realException.getConstraintViolations())
                                        ? PARAMS_INVALID_EMPTY
                                        : realException.getConstraintViolations()
                                        .stream().map(item -> item.getPropertyPath().toString() + ":" + item.getMessage()).collect(Collectors.joining(","));
                                appResponse.setValue(BaseResponse.error(PARAMS_INVALID_EMPTY, errorMsg));
                                appResponse.setException(null);
                            }
                        }
                    }

                    return;
                } catch (Throwable e) {
                    log.error("error",e);
                    return;
                }
            }

        }

        @Override
        public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
            log.error("Got unchecked and undeclared exception which called by {},service: {}, method:{}",
                    RpcContext.getContext().getRemoteHost(), invoker.getInterface().getName(), invocation.getMethodName(), e);

        }
    }
}

在 src/main/resources/META-INF/dubbo 中新建文件 org.apache.dubbo.rpc.Filter

内容如下

DubboExceptionFilter=com.example.dubboserver.filter.DubboExceptionFilter

最后,在resources目录下的配置文件中(例如application.properties,application.yml)加上

dubbo.provider.validation=true

说明:

dubbo.provider.validation=true代表在 接口提供方校验,

也可以指定  dubbo.consumer.validation=true,在 消费端校验

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值