网关全局过滤器(CloudGatewayFilter)
CloudGatewayFilter 是 ExFilter 的扩展接口,主要是为了突出名字的专属性。使用时与 Filter 的区别:
- 最后要返回一个
Completable
。用于触发一个响应式订阅,从而让异步结束。 - 所有的异常,也要用
Completable.error(err)
返回
作用范围是网关全局。
1、网关全局过滤器
接口 | 说明 |
---|---|
CloudGatewayFilter | 原始网关过滤器接口 |
CloudGatewayFilterMix | 组合网关过滤器接口,可以方便组合 RoutePredicateFactory |
CloudGatewayFilterSync | 网关过滤器接口同步形态(用于对接同步 io)。v3.2.1 后支持 |
- CloudGatewayFilter 示例(原始接口)
@Component
public class CloudGatewayFilterImpl implements CloudGatewayFilter {
@Override
public Completable doFilter(ExContext ctx, ExFilterChain chain) {
//代码写这儿
return chain.doFilter(ctx);
}
}
- CloudGatewayFilterMix 示例(虚拟类,组合网关接口)
@Component
public class CloudGatewayFilterMixImpl extends CloudGatewayFilterMix {
@Override
public void register() {
//配置写这儿
filter("StripPrefix=1");
filter("AddRequestHeader=app.ver,1.0");
}
@Override
public Completable doFilterDo(ExContext ctx, ExFilterChain chain) {
//组合过滤器执行后的,代码写这儿
return chain.doFilter(ctx);
}
}
2、对接 solon-web 经典上下文接口
使用同步接口,可能会很伤害响应式的性能(这个要注意,不要做费时的事情)。ExContext 提供了一个转经典上下文接口的方法 toContext()
,可满足特殊需要。比如和 sa-token 对接(仅供参考):
@Component
public class CloudGatewayFilterImpl implements CloudGatewayFilter {
@Override
public Completable doFilter(ExContext ctx, ExFilterChain chain) {
Context ctx2 = ctx.toContext();
//...处理代码
return chain.doFilter(ctx);
}
}
//如果需要使用 Context.current();
@Component
public class CloudGatewayFilterImpl implements CloudGatewayFilter {
@Override
public Completable doFilter(ExContext ctx, ExFilterChain chain) {
try {
Context ctx2 = ctx.toContext();
ContextHolder.currentSet(ctx2);
//...处理代码
} finally {
ContextHolder.currentRemove();
}
return chain.doFilter(ctx);
}
}
3、对接同步 io 接口(v3.2.1 后支持)
使用同步 io 会卡住线程,这对网关引擎的事件循环器非常不友好。框架设计了两个对接的同步io接口的过滤器(旧版本的,可以直接复制代码):
//同步过滤器(会自动转异步)
@FunctionalInterface
public interface ExFilterSync extends ExFilter {
@Override
default Completable doFilter(ExContext ctx, ExFilterChain chain) {
return Completable.create(emitter -> {
//暂停接收流
ctx.pause();
//开始异步
RunUtil.async(() -> {
try {
//开始同步处理
boolean isContinue = doFilterSync(ctx);
if (isContinue) {
//继续
chain.doFilter(ctx).subscribe(emitter);
} else {
//结束
emitter.onComplete();
}
} catch (Throwable ex) {
emitter.onError(ex);
}
});
});
}
/**
* 执行过滤同步处理(一般用于同步 io)
*
* @param ctx 上下文
* @return 是否继续
*/
boolean doFilterSync(ExContext ctx) throws Throwable;
}
//同步网关过滤器(会自动转异步)
@FunctionalInterface
public interface CloudGatewayFilterSync extends CloudGatewayFilter, ExFilterSync {
}
使用示例(对接一个 jdbc 签权服务。关于 sa-token 对接,参考后续的鉴权资料)
@Component(index = -9)
public class AuthFilterSync implements CloudGatewayFilterSync {
@Inject
AuthJdbcService authService;
@Override
public boolean doFilterSync(ExContext ctx) throws Throwable {
String userId = ctx.rawQueryParam("userId");
//检测路径权限
return authService.check(userId, ctx.rawPath());
}
}
目前支持异步框架有:
- solon-net-httputils,支持异步 http
- solon-data-rx-sqlutils,支持异步 jdbc
- vert.x 的工具包
- projectreactor 的工具包