7Zuul 数据传递 · SpringCloud微服务实战 · 看云
7. 数据传递
导航
本节代码地址
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-gateways/fw-cloud-gateways-zuul-simple
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-ribbon/fw-cloud-ribbon-server
上节我们说过过滤器的拦截顺序,现在继续分析拦截器如何在第一个没通过,就不会执行第二个。
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
控制台中我可以看到只输出一条日志了
2020-01-03 21:44:02.236 INFO 19344 --- [nio-8679-exec-1] c.yisu.gateways.zuul.filter.TokenFilter : 我是TokenFilter
