SpringCloudGateway 学习笔记 - 自定义过滤器 之 获取响应头
Posted 笑虾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloudGateway 学习笔记 - 自定义过滤器 之 获取响应头相关的知识,希望对你有一定的参考价值。
SpringCloudGateway 学习笔记 - 获取响应头
SpringCloudGateway
支持两种过滤器,
Global Filters
和
GatewayFilterFactories
。
同时还内置了
31
种
GatewayFilterFactories
常用实现。
我们自己需要自定时,基本照着改就行了。
下面我们就来实现一个获取响应头的自定义过滤器 。
规则
- 继承:
AbstractGatewayFilterFactory<C>
public abstract class AbstractGatewayFilterFactory<C> extends AbstractConfigurable<C>
implements GatewayFilterFactory<C>, ApplicationEventPublisherAware {...}
- 定义一个内部类接收参数。本例中直接用了
AbstractGatewayFilterFactory.NameConfig
它定义了一个名为name
的参数 - 无参构造中将参数对象传给父类
注意:如果使用配置文件设置路由,有几点要注意。(下面会讲到)
自定义过滤器
直接复制RemoveResponseHeaderGatewayFilterFactory.java
来改。
别看代码多,真正自己要写的业务逻辑只有这两行。其他都是拷过来的。
HttpHeaders headers = exchange.getResponse().getHeaders();
log.info("获得响应中的cookie: {}", headers.get(config.getName()));
package com.jerry.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
@Component
@Slf4j
public class CustomResponseHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> {
public CustomResponseHeaderGatewayFilterFactory() {
super(NameConfig.class);
}
@Override
public GatewayFilter apply(NameConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(
() -> {
HttpHeaders headers = exchange.getResponse().getHeaders();
log.info("获得响应中的cookie: {}", headers.get(config.getName()));
}
)
);
}
@Override
public String toString() {
return filterToStringCreator(CustomResponseHeaderGatewayFilterFactory.this)
.append("name", config.getName()).toString();
}
};
}
}
设置路由,并指定过滤器
JavaConfig 实现
package com.jerry.config;
import com.jerry.filter.CustomResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class RoutesDemo {
private static final String url = "http://127.0.0.1";
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p.path("/api/code") // 要过滤的地址
// 定义过滤器,同时通过 Lambda 设置了参数
.filters(f -> f.filter(new CustomResponseHeaderGatewayFilterFactory().apply(c -> c.setName("Set-Cookie"))))
.uri(url) // 转发到 url
).build();
}
}
配置文件yml 实现
除了用上面的 javaConfig 方式配置路由,还可以使用配置文件配置,但有些需要注意的点:
注意 1、自定义过滤器命名规则
1.1. 默认规则
按照 SpringCloudGateway 默认命名规则,所有自定义过滤器要以GatewayFilterFactory
结尾。
形式如:xxxxGatewayFilterFactory
这样在配置文件中使用 xxxx
作为过滤器名称。
比如本例要把过滤器名CustomResponseHeader
改为 CustomResponseHeaderGatewayFilterFactory
spring:
cloud:
gateway:
routes:
- id: checkResponseHeader
uri: http://127.0.0.1
sensitiveHeaders: "*"
predicates:
- Path=/**
filters:
- CustomResponseHeader=Set-Cookie
1.2. 自定义规则
如果觉得默认规则太啰嗦,可以重写name()
自定义。比如:
@Override
public String name() {
return "CustomRH666";
}
spring:
cloud:
gateway:
routes:
- id: checkResponseHeader
uri: http://127.0.0.1
sensitiveHeaders: "*"
predicates:
- Path=/**
filters:
- CustomRH666=Set-Cookie
注意 2、配置文件参数规则
2.1. 完全参数名
在我们没有做短参数前,需要点名道姓的传参:
属性 | 说明 |
---|---|
filters | 指定过滤器 |
args | 接下来设置参数 |
name | 参数名 name 值 Set-Cookie 这里参数名叫 name 因为我们没自己定义参数对象,直接用的 AbstractGatewayFilterFactory.NameConfig 它的内容就是一个private String name; |
spring:
cloud:
gateway:
routes:
- id: checkResponseHeader
uri: http://127.0.0.1
sensitiveHeaders: "*"
predicates:
- Path=/**
filters:
- name: CustomRH666
args:
name: Set-Cookie
# 参数名2: 参数值2
# 参数名3: 参数值3
2.2. 短参数
参考 :4.1. Shortcut Configuration
短参数的格式:过滤器名=参数1,参数2,参数3
2.2.1. 单个参数
如果像如前面例子中那样使用短格式设置参数:CustomRH666=Set-Cookie
可以重写:
/** 下面讲配置文件时会说明*/
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(NAME_KEY);
}
这里直接使用了 GatewayFilterFactory
接口定义的参数名字。
String NAME_KEY = "name"; // 我们用了这个
String VALUE_KEY = "value";
2.2.2. 多个参数
这里的数组定义的就是参数顺序
。
注意这里的参数名:索引1
这个位置的值,我把它传给param4
/** 配置文件短参数 */
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(NAME_KEY, "param4", "param2", "param3");
}
相应的AbstractGatewayFilterFactory.NameConfig
现在不满足需求了。我们自己定义一个内部类CustomResponseHeaderGatewayFilterFactory.Config
@Data
public static class Config {
private String name;
private String param2;
private String param3;
private String param4;
}
配置如下:
spring:
cloud:
gateway:
routes:
- id: checkResponseHeader
uri: http://127.0.0.1
sensitiveHeaders: "*"
predicates:
- Path=/**
filters:
- CustomRH666=Set-Cookie,我是老二,我是老三,我是老四
参考资料
SpringCloudGateway 官方文档
4.1. 短参数:Shortcut Configuration
6.13. 内置过滤器:RemoveResponseHeader GatewayFilter Factory
17.2. 自定义过滤器 Writing Custom GatewayFilter Factories
以上是关于SpringCloudGateway 学习笔记 - 自定义过滤器 之 获取响应头的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloudGateway 学习笔记 - 搭建项目
SpringCloudGateway 学习笔记 - 自定义过滤器 之 获取响应头
SpringCloudGateway 学习笔记 - yml 配置
SpringCloudGateway 学习笔记 - 使用内置过滤器添加请求头响应头