7Zuul 数据传递 · SpringCloud微服务实战 · 看云

7. 数据传递

导航

本节代码地址


上节我们说过过滤器的拦截顺序,现在继续分析拦截器如何在第一个没通过,就不会执行第二个。

7.1 分析源码

通过分析Zuul 的这段源码,可以看出,先判断这个过滤器是不是已经禁用了,禁用的话不执行,然后判断shouldFilter(),我们可以通过设置shouldFilter()true、false 来控制过滤器的执行。

public ZuulFilterResult runFilter() {
    ZuulFilterResult zr = new ZuulFilterResult();
    if (!this.isFilterDisabled()) {
        if (this.shouldFilter()) {
            Tracer t = TracerFactory.instance().startMicroTracer("ZUUL::" + this.getClass().getSimpleName());

            try {
                Object res = this.run();
                zr = new ZuulFilterResult(res, ExecutionStatus.SUCCESS);
            } catch (Throwable var7) {
                t.setName("ZUUL::" + this.getClass().getSimpleName() + " failed");
                zr = new ZuulFilterResult(ExecutionStatus.FAILED);
                zr.setException(var7);
            } finally {
                t.stopAndLog();
            }
        } else {
            zr = new ZuulFilterResult(ExecutionStatus.SKIPPED);
        }
    }

    return zr;
}

7.2 数据传递

因此我们可以在第一个失败的时候,通过RequestContext传递变量,为什么用RequestContext,主要还是因为RequestContext的实现原理是基于ThreadLocal实现的,源码如下

private static RequestContext testContext = null;
protected static final ThreadLocal<? extends RequestContext> threadLocal = new ThreadLocal<RequestContext>() {
    protected RequestContext initialValue() {
        try {
            return (RequestContext)RequestContext.contextClass.newInstance();
        } catch (Throwable var2) {
            throw new RuntimeException(var2);
        }
    }
};


在TokenFilter中设置如下值。


ctx.set("isShould",false);

将ZuulFilter 中的shouldFilter()修改成如下。

@Override
public boolean shouldFilter() {
    RequestContext requestContext=RequestContext.getCurrentContext();
    Boolean isShould = (Boolean) requestContext.get("isShould");
    return null==isShould?true:isShould; 
}

7.3 项目重启

浏览器或Postman 输入localhost:8679/ribbon/user/1
d280f1c846894a8087a3870c3578efe0_MD5.png

控制台中我可以看到只输出一条日志了

2020-01-03 21:44:02.236  INFO 19344 --- [nio-8679-exec-1] c.yisu.gateways.zuul.filter.TokenFilter  : 我是TokenFilter