Spring Cloud Gateway GatewayFilter的使用

网友投稿 272 2022-09-26

Spring Cloud Gateway GatewayFilter的使用

Spring Cloud Gateway GatewayFilter的使用

​​一、GatewayFilter的作用​​​​二、Spring Cloud Gateway内置的 GatewayFilter​​

​​1、AddRequestHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​1、方式一、添加一个固定的请求头​​​​2、配合 uri variables 添加动态请求头​​

​​2、AddRequestParameter​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​3、AddResponseHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​4、DedupeResponseHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​5、MapRequestHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​6、Prefix​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​7、PreserveHostHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​8、RemoveRequestHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​9、RemoveResponseHeader​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​9、RemoveRequestParameter​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​10、RewritePath​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​11、StripPrefix​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​12、RequestSize​​

​​1、描述​​​​2、参数​​​​3、示例​​

​​13、ModifyRequestBody​​

​​1、描述​​​​2、需求:​​​​3、路由配置,只可通过 Java 代码来配置​​

​​14、ModifyResponseBody​​

​​1、 描述​​

​​15、更多的 GatewayFilterFactory​​

​​三、配置默认拦截器​​

​​1、描述​​​​2、配置方法​​​​3、示例​​

​​四、全局过滤器​​

​​1、ForwardRoutingFilter​​​​2、LoadBalancerClientFilter​​​​3、The Websocket Routing Filter​​​​4、更多全局过滤器​​

​​五、自定义全局过滤器​​​​六、编写一个 GatewayFilter​​

​​1、Java代码实现​​

​​2、配置文件中的写法​​

​​七、其它的配置​​

​​1、获取当前命令的路由​​​​2、过滤器的执行顺序​​​​3、配置超时时间​​

​​1、配置全局超时时间(注意单位)​​​​2、配置每个路由的超时时间(注意单位)​​

​​4、输出gateway调试日志​​

​​1、输出 netty 的 access log​​​​2、设置日志级别 debug or trace​​

​​八、网关错误的处理​​​​九、完整代码​​​​十、参考链接​​

一、GatewayFilter的作用

路由过滤器允许我们以某种方式修改进来的​​Request​​​和出去的​​Response​​​。Spring Cloud Gateway内置很多的 ​​GatewayFilter​​。

二、Spring Cloud Gateway内置的 GatewayFilter

1、AddRequestHeader

1、描述

1、用于向下游服务 ​​添加​​​ 请求头, 2、支持 uri variables

2、参数

1、​​name​​​:向下游服务传递请求头的 key 2、​​​value​​:向下游服务传递请求头的 value

3、示例

1、方式一、添加一个固定的请求头

spring: cloud: nacos: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddRequestHeader=x-token,xxxxx

表示会向下游服务传递一个 ​​x-token​​​ 的请求头,值是 ​​xxxxx​​

2、配合 uri variables 添加动态请求头

spring: cloud: gateway: routes: - id: product-provider-02 uri: lb://product-provider predicates: - Path=/product/findOne/{productId} filters: - AddRequestHeader=x-token,xxxxx-{productId}

表示会向下游服务传递一个 ​​x-token​​​ 的请求头,值是 ​​xxxxx-匹配上的productId的值​​

2、AddRequestParameter

1、描述

用于向下游服务 添加一个请求参数

2、参数

1、​​name​​​:添加的参数 key 2、​​​value​​​:添加的参数 value,可以支持 Path或Host 中的 ​​uri variables​​

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddRequestParameter=username,zhangsan

向下游服务增加一个 ​​username​​​ = ​​zhangsan​​ 的请求参数

3、AddResponseHeader

1、描述

向下游的响应中增加一个 响应头。

2、参数

1、​​name​​​:添加的响应头的 key 2、​​​value​​​:添加的响应头的 value,可以支持 Path或Host 中的 ​​uri variables​​

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddResponseHeader=encryption,false

向下游服务响应增加一个 ​​encryption​​​ = ​​false​​ 的响应头

4、DedupeResponseHeader

1、描述

移除重复的请求头

2、参数

1、​​name​​​:需要移除的重复的响应头,多个以 ​​空格​​​ 分隔 2、​​​strategy​​​:重复时,移除的策略,默认是​​RETAIN_FIRST​​,即保留第一个头

RETAIN_FIRST:保留第一个值RETAIN_LAST:保留最后一个值RETAIN_UNIQUE:保留所有的不重复的值

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - DedupeResponseHeader=x-token Access-Control-Allow-Credentials Access-Control-Allow-Origin,RETAIN_FIRST

移除上方指定的重复的响应头,并且保留第一个出现的。

5、MapRequestHeader

1、描述

将 ​​fromHeader​​​ 参数的值 追加到 ​​toHeader​​ 参数中。

fromHeader 在 header 中不存在,那么没有什么影响。fromHeader 存在

toHeader 存在,那么往配置中 toHeader 对应的 header 中追加 fromHeader对应的值

toHeader 不存在,那么往 header 中增加一个header ,key: 配置中的toHeader的值,value: fromHeader 在header中的值

2、参数

1、​​fromHeader​​​:从请求参数中获取​​header​​​的值 2、​​​toHeader​​​:向​​header​​中设置一个 header, key是toheader的值,value 是 fromHeader的值

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - MapRequestHeader=from-header,x-token

即会向 request 中增加一个 key 为 ​​x-token​​​ 的header ,值为 ​​header 中 from-header​​ 对应的值。(存在多种情况,参考描述)

6、Prefix

1、描述

为匹配到的路由,在转发到下游服务时,增加一个前缀​​prefix​​

2、参数

1、​​prefix​​:需要增加的路径前缀

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/findOne filters: - PrefixPath=/product

访问 ⇒ 转发到下游服务地址 增加了一个前缀。

7、PreserveHostHeader

1、描述

它表示在Spring Cloud Gateway转发请求的时候,保持客户端的​​Host​​信息不变,然后将它传递到下游服务器中。

2、参数

没有参数

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - PreserveHostHeader

8、RemoveRequestHeader

1、描述

移除请求头中的参数

2、参数

1、​​name​​:需要移除的请求头

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveRequestHeader=x-token

9、RemoveResponseHeader

1、描述

移除响应头

2、参数

1、​​name​​:需要移除的响应头

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveResponseHeader=x-token

9、RemoveRequestParameter

1、描述

移除请求参数,往下游服务传递时,此参数就没有来

2、参数

1、​​name​​:需要移除的请求参数

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveRequestParameter=password

10、RewritePath

1、描述

根据正则表达式,执行路径重写

2、参数

1、​​regexp​​​:匹配的正则表达式 2、​​​replacement​​​:需要替换成的字符串注意: 1、在​​​yml​​​配置中 ​​$​​​ 需要写成 ​​$\​​​ 2、路径替换规则是: ​​path.replaceAll(regexp,replacement)​​

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/admin/product/findOne filters: - RewritePath=/admin(?/?.*), $\{segment} # 当访问/admin/product/findOne 将会替换成 /product/findOne

页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 ​​/product/findOne​​

11、StripPrefix

1、描述

移除路径前缀,比如访问: /admin/aa/bb/cc 实际的下游服务器地址是 /bb/cc 则可以使用这个实现

2、参数

1、​​parts​​​:请求的路径按照​​/​​分隔后,需要跳过的部分,从1开始。

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/admin/product/findOne filters: - StripPrefix=1 # 当访问/admin/product/findOne 将会替换成 /product/findOne

页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 ​​/product/findOne​​

12、RequestSize

1、描述

配置请求体的大小,当请求体过大时,将会返回 ​​413 Payload Too Large​​。

2、参数

1、​​maxSize​​:请求体的大小

3、示例

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - name: RequestSize args: maxSize: 1B

此处需要通过 ​​filters[index].args.maxSize​​ 配置,否则不生效。

13、ModifyRequestBody

1、描述

修改传递到下游服务 ​​RequestBody​​ 的值,比如我们所有的经过网关的服务,到达下游服务时,都需要将 用户当前的用户名和数据权限传递下去,此时就可以使用这个。

2、需求:

修改原始服务的参数,增加​​username​​​和​​roles​​参数传递到下游服务。

3、路由配置,只可通过 Java 代码来配置

@Configurationpublic class RouteConfig { @Bean public RouteLocator routes(RouteLocatorBuilder builder) { return builder.routes() .route("product-provider", predicateSpec -> predicateSpec.path("/product/modifyRequestBody") .filters(gatewayFilterSpec -> gatewayFilterSpec.modifyRequestBody(String.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> { Map params = new HashMap<>(16); params.put("old", s); params.put("username", "v_huan"); params.put("roles", "ROLE_ADMIN"); return Mono.just(params); })).uri("lb://product-provider")).build(); }}

14、ModifyResponseBody

1、 描述

修改下游服务返回的​​ResponseBody​​​的值,和上方的​​RequestBody​​类似,此处不在处理。

15、更多的 GatewayFilterFactory

在代码中查看 ​​GatewayFilterFactory​​ 的子类即可。

三、配置默认拦截器

1、描述

默认拦截器,对所有的路由都会生效。

2、配置方法

配置文件中使用 ​​spring.cloud.gateway.default-filters​​ 配置

3、示例

spring: cloud: gateway: default-filters: - AddResponseHeader=X-Response-Default-Red, Default-Blue - PrefixPath=/​​GatewayFilter​​​会组合成一个过滤器链,排序规则是通过 Spring 的 ​​Ordered​​ 来排序。

​​GlobalFilter​​​有​​pre​​​和​​post​​​2个执行阶段,优先级越高 ​​pre​​​ 阶段执行越早, ​​post​​阶段执行越迟。

1、ForwardRoutingFilter

ForwardRoutingFilter 用来处理 ​​forward:///localendpoint​​ 请求。

2、LoadBalancerClientFilter

LoadBalancerClientFilter 用来处理 ​​lb://service-name​​ 这样的请求

spring: cloud: gateway: routes: - id: myRoute uri: lb://service predicates: - Path=/service/**

3、The Websocket Routing Filter

处理 ​​websocket​​ 请求

spring: cloud: gateway: routes: # SockJS route - id: websocket_sockjs_route uri: predicates: - Path=/websocket/info/** # Normal Websocket route - id: websocket_route uri: [ws|wss]://localhost:3001 predicates: - Path=/websocket/**

4、更多全局过滤器

​​GlobalFilter 接口和 Ordered 接口加入到 Spring 管理代码实现

@Slf4j@Componentpublic class CustomGlobalFilter implements GlobalFilter, Ordered { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { String path = exchange.getRequest().getPath().toString(); log.info("进入了全局过滤器,path:[{}]", path); // 修改 request ServerHttpRequest request = exchange.getRequest().mutate().header("x-token", "123456").build(); return chain.filter(exchange.mutate().request(request).build()); } /** * 指定全局过滤器执行的顺序 * * @return */ @Override public int getOrder() { return 0; }}

六、编写一个 GatewayFilter

1、实现 ​​GatewayFilterFactory​​​ 或者继承 ​​AbstractGatewayFilterFactory​​​ 类 2、继承​​​AbstractGatewayFilterFactory​​​ 类时,构造方法中需要调用 super(C.class) 3、重写 ​​​shortcutFieldOrder​​​方法,定义配置文件中字段的位置 4、编写的过滤器类必须要以 ​​​GatewayFilterFactory​​​结尾 5、自定义过滤器的名字为,​​​GatewayFilterFactory​​​前面的字符,比如 TokenGatewayFilterFactory,那么过滤器名字是 ​​Token​​ 5、功能实现:过滤器实现,从请求中获取一个参数的值,打印出来

1、Java代码实现

@Component@Slf4jpublic class TokenGatewayFilterFactory extends AbstractGatewayFilterFactory { public TokenGatewayFilterFactory() { super(Config.class); } @Override public List shortcutFieldOrder() { return Lists.newArrayList("tokenName"); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { log.info("每次路由匹配到会执行"); String tokenName = config.getTokenName(); log.info("从配置文件中获取到的 tokenName 的值=[{}].", tokenName); String value = exchange.getRequest().getQueryParams().getFirst(tokenName); log.info("从请求中获取到的token value 是:[{}]", value); return chain.filter(exchange); }; } @Data public static class Config { private String tokenName; }}

2、配置文件中的写法

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - Token=gateway-token

七、其它的配置

1、获取当前命令的路由

// 1、获取当前匹配上的路由Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);String routeId = route.getId();Map metadata = route.getMetadata();log.info("routeId:[" + routeId + "]" + "metadata:[" + metadata + "]");

2、过滤器的执行顺序

3、配置超时时间

1、配置全局超时时间(注意单位)

spring: cloud: gateway: # 全局的连接超时,单位毫秒 connect-timeout: 1000 # 全局的响应超时,需要符合java.time.Duration规范 response-timeout: 3s

2、配置每个路由的超时时间(注意单位)

spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne metadata: # 单个路由配置响应超时,单位毫秒 response-timeout: 200 # 单个路由配置连接超时,单位毫秒 connect-timeout: 200

4、输出gateway调试日志

1、输出 netty 的 access log

需要使用设置如下参数,注意是 ​​JVM​​ 的参数

-Dreactor.netty.debug or trace

logging: level: org.springframework.cloud.gateway: trace org.springframework.trace org.springframework.web.reactive: trace org.springframework.boot.autoconfigure.web: trace reactor.netty: trace

八、网关错误的处理

实现 ​​WebExceptionHandler​​​ 接口,在里面出现错误逻辑。需要注意 ​​指定该接口的 order​​​ 否则可能被别的处理了,自己的不生效。​​​返回完成信号​​​:表示错误处理完成​​​返回错误信息​​​:交由下个处理器处理。eg:

/** * 异常处理器,需要注意 @Order 指定执行的顺序 * * @author huan.fu 2020/11/15 - 14:47 */@Component@Slf4j@Order(Integer.MIN_VALUE)public class GatewayExceptionHandler implements WebExceptionHandler { @Override public Mono handle(ServerWebExchange exchange, Throwable ex) { log.info("发生了异常", ex); String errorMsg = "{\"code\":500,\"msg\":\"服务器内部错误\"}"; ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); response.getHeaders().setContentType(MediaType.APPLICATION_JSON); DataBuffer dataBuffer = response.bufferFactory().wrap(errorMsg.getBytes(StandardCharsets.UTF_8)); return response.writeWith(Mono.just(dataBuffer)); }}

九、完整代码

​​https://gitee.com/huan1993/spring-cloud-alibaba-parent/tree/master/gateway-filter​​

十、参考链接

​​https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:聚合打车再掀战火,腾讯将联合滴滴入局!
下一篇:SpringBoot整合kafka
相关文章

 发表评论

暂时没有评论,来抢沙发吧~