有两种方式:
1、继承GatewayFilter,实现后使用java方式配置路由;
2、继承AbstractGatewayFilterFactory,注入为bean即可(推荐)
另外可参考:
https://www.cnblogs.com/chenglc/p/13139407.html
https://www.cnblogs.com/cloudxlr/p/11820638.html
自定义过滤器工厂
过滤器工厂的顶级接口是GatewayFilterFactory,我们可以直接继承它的两个抽象类来简化开发AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,这两个抽象类的区别就是前者接收一个参数(像StripPrefix和我们创建的这种),后者接收两个参数(像AddResponseHeader)。
1、AbstractNameValueGatewayFilterFactory
复制进来提前准备好的类
去掉一些没有用到的包
类名的结尾
继承类,并自定义Config
Config是来承载我们的参数的
自定义请求的一个name和value。当name和value都能匹配的上的时候,就返回true继续往下走。匹配不上就报错。这个绝大多数我们不是在parameter里面做的 巨大多数是在header头里面做的。jwt要验证token是否正确。这个时候需要验证我们有没有authorization的信息。同时把它的内容取出来。紧接着跟我的jwt服务器 作比较。看看jwt是否有效。
在之类先给大家演示的是一个比较简单的
匹配的两个值
这两个常量是在上面来定义的
这是具体的业务处理
把所有请求的parameters都打印出来了
请求的头里面获取configParameter
如果和我定义的值不相同就返回无效的请求。直接Response回去了。 就不继续处理下一个逻辑了。
本身加了@Component的注解了。所以不需要在config内注入。
要求参数内必须有个imooc。值必须是jiangzh
重启gateway测试
测试一个失败的
2、AbstractGatewayFilterFactory
做一个可配置是否开启的打印请求耗时的过滤器
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
public class RequestTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTimeGatewayFilterFactory.Config> {
private static final Log log = LogFactory.getLog(GatewayFilter.class);
private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
private static final String KEY = "withParams";
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(KEY);
}
public RequestTimeGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis());
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN);
if (startTime != null) {
StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath())
.append(": ")
.append(System.currentTimeMillis() - startTime)
.append("ms");
if (config.isWithParams()) {
sb.append(" params:").append(exchange.getRequest().getQueryParams());
}
log.info(sb.toString());
}
})
);
};
}
public static class Config {
private boolean withParams;
public boolean isWithParams() {
return withParams;
}
public void setWithParams(boolean withParams) {
this.withParams = withParams;
}
}
}
在上面的代码中 apply(Config config)方法内创建了一个GatewayFilter的匿名类,具体的实现逻辑跟之前一样,只不过加了是否打印请求参数的逻辑,而这个逻辑的开关是config.isWithParams()。静态内部类类Config就是为了接收那个boolean类型的参数服务的,里边的变量名可以随意写,但是要重写List shortcutFieldOrder()这个方法。
需要注意的是,在类的构造器中一定要调用下父类的构造器把Config类型传过去,否则会报ClassCastException
最后,需要在工程的启动文件Application类中,向Srping Ioc容器注册RequestTimeGatewayFilterFactory类的Bean。
@Bean
public RequestTimeGatewayFilterFactory elapsedGatewayFilterFactory() {
return new RequestTimeGatewayFilterFactory();
}
配置项:
spring:
cloud:
gateway:
routes:
- id: elapse_route
uri: http://httpbin.org:80/get
filters:
- RequestTime=false
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
profiles: elapse_route
现在可以通过配置来决定是否开启打印时间的日志