首页 > 技术文章 > Dubbo添加Filter过滤器

expiator 2021-03-25 16:09 原文

使用场景

在使用Dubbo的过程中,我们有时需要做一些过滤拦截的操作,比如字符编码、黑名单、添加日志、接口耗时统计等,这时可以使用过滤器来处理。

Filter过滤器

Dubbo 使用Filter,需要实现Filter接口,重写invoke方法,在前后添加逻辑即可。
注意,引入的Filter是com.alibaba.dubbo.rpc包的。
@Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上。
@Activate注解可以用于指定过滤器范围。
@Activate(group = {Constants.PROVIDER, Constants.CONSUMER}), Constants.PROVIDER表示用于服务提供者,Constants.CONSUMER表示服务消费者,如果都支持可以用逗号隔开。

格式如下:

@Activate(group = {Constants.PROVIDER})
public class FilterTest implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        // 过滤前的逻辑
        Result result = invoker.invoke(invocation);
        // 过滤后的逻辑
        return result;
    }
}

示例如下:

import com.alibaba.dubbo.rpc.*;

@Activate(group = {Constants.PROVIDER})
public class ContextFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(ContextFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation)  {
        try {
            //获取request请求
            HttpServletRequest request=  (HttpServletRequest)RpcContext.getContext().getRequest();
            //设置字符编码,也可以是其他的内容
	    request.setCharacterEncoding("UTF-8");

        } catch (UnsupportedEncodingException e) {
            logger.error("ContextFilter error.", e);
        }

        return invoker.invoke(invocation);
    }
}

配置Filter

在这个路径下 src/main/resources/META-INF 添加文件夹,名称为 dubbo,
在dubbo文件夹下添加一个文件(注意,这个是文件),名称为 com.alibaba.dubbo.rpc.Filter 。

变量名随意取,值为Filter实现类的路径 ,如果有多个过滤器,就写多行,如下 :

charFilter=com.service.filter.ContextFilter

Filter作用范围

在dubbo配置文件中的 <dubbo:service /> 、<dubbo:reference />里面,添加 Filter属性。
<dubbo:service /> 是服务提供者,用于暴露服务。<dubbo:reference />是服务消费者。
如下,添加filter就可以进行过滤了,filter对应的值为 com.alibaba.dubbo.rpc.Filter文件中的变量名。

<bean class="com.service.impl.UserServiceImpl" id="userService"/>
<dubbo:service filter="charFilter" document="userServiceCofiguration" interface="com.service.UserService" protocol="rest" ref="userService" />

添加filter属性后,就可以使过滤器生效了。
如果想要添加多个过滤器,可以按照同样的配置添加,然后 filter="charFilter" 改成类似 filter="timesFilter,charFilter" 这种逗号隔开的格式就可以了。

参考资料:

https://dubbo.apache.org/zh/docs/v3.0/references/spis/filter/

推荐阅读