Spring Cloud 系列之 Gateway 服务网关(三)


本篇文章为系列文章,未读第一集的同学请猛戳这儿:

  • Spring Cloud 系列之 Gateway 服务网关(一)
  • Spring Cloud 系列之 Gateway 服务网关(二)

本篇文章解说 Gateway 网关过滤器和大局过滤器以及自定义过滤器。

  

过滤器

  

  Spring Cloud Gateway 依据效果规模8 B 8 1 ! c划分为 GatewF q ( x x k { D /ayFilterGlobalFilter,二者差异如下:

  • GatewayFilter:网关过} 0 f A D ] i v滤器,需求经过 spring.cloud.routes.filters 装备在具体路由下,只效果在当前路由上或经过 spr& o : / h { z 3 Qing.cloud.default-filters 装备在大局,效果在所有路由( 1 % + n z上。
  • GlobalFilter:大局过滤器,y B 0 k U }不需求在装备文b o : e q ` (件中f s D s装备,效果在所有的路由上,终究经过 GatewayFilterAdaI ! 9pter 包装成 Ga* b A O gtewayFilx i - X B P p ] @terChain 可辨认的过滤器,它为恳求事务以及路由的 URI 转换为真实事务服务恳求地址的核心过滤器,不需求装备体系初始化时加载,并效果在每个路由上。

  

网关过滤器 GatewayFilter

  

q | o t s w Z n o 点击链接观看:网关过滤器视频(获取更多请重视公众号「+ Q k l哈喽沃德先生」)

  I C A x

  网; : s B关过滤器用于阻拦并链式处理 Web 恳求,能够完成横切与运用无` $ } 8关的需求,比如:安全、拜访超时的设置等。O 2 t G ` S ^ R b修正传入的 HTTP 恳求或传出 HTTP 呼应。Spring Cloud Gateway 包含许多内置的网关过滤器工厂一共有 22 个,包括头部过滤器i = W !、 途径类过滤器、Hystrix 过滤器和重写恳求 URL 的过滤器, 还有参数和状态码等其他类型的过滤^ I w 5 W –器。依据过滤 B ] H器工厂的用途来划分,能够分为以下几种:Header、Parameter、Path、Bod` } & @ ~y、Status、Session、Redirect、Retry、RateLiv d A # f Bmiter 和 Hystrix。

Spring Cloud 系列之 Gateway 服务网关(三)

  

  接下来咱们举例说明其中一部分如何运用,其余等咱们工作中需求运用时再查询资料学习或许咨询我也能够。

  

Path 途径过滤器

  

  Path 途径过滤器能够完成 URL 重写,经过重写 URL 能够完成隐藏实际途径进步安全性,易于用户回忆和键入,易V 2 n P I 7 8于被搜索引擎收录等优点。完成方式如B @ T ? o V下:

  

RewritePathGatewayFiltn t i r ; t –erFactory

  

  RewrV h } `itePath 网关过滤器工厂选用途径正则表达式参数和替换参数,运用 Java 正则表达式来灵活地重写恳求途径z 8 –

spring:
  application:
    name: gateway-server9 ^ { D 9 + M 7 M # 运用称号
  cloul # P zd:
    gateway:a u 5 ( x S + k
# 路由规矩
      routes:
        - id:[ N u V pF w m b ( g - G }roduct-service           # 路由 ID,仅有
          uri: lW 7 F G p Pb://product-serv# e I 3ice     # lb:// 依据服务称号从注册中心获取服务恳求地址
          predicates:                   # 断语(判别条件)
# 匹配对应 URI 的恳求,将匹配到的恳求追加在方针 URI 之后
            - Path=/product/**, /api-gateway/**
          filters:                      # 网关过滤器
# 将c u ? /api-gateway/produ, r _ @ n sct/1 重写为 /product/1
            - RewritePath=/api-gateway(?<segment>/?.*), ${segment}

  

  拜访:http://localhost:9000/api-gateway/product/1 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

Preu Z IfixPathGatewayFilterFactory

  

  PrefixPaty O H – r wh 网关过滤器工厂为匹配的 URI 增加指定前缀。

spring:
  applicatioH [ mn:
    name: gateway-server # 运用称号
  cloud:
    gateway:
# 路由规矩
      routes:
        - id: product-service           # 路由 ID,仅有
          uri: lb://product-service     # lb:// 依据服务称号从注册中心获取服务恳求地址
          predica j Ttes:                   # 断语(判别条件)
# 匹配对应 URI 的恳求C } O } f ~ m,将匹配到的恳求追加在方针 URI 之后
            - Path=/**
          filters:                       # 网关过滤器
# 将 /1 重写为 /G Q r I [ A 7 4product/1
            - PrefixPathe v j J=/product

  

  拜访v T |:http://localhost:9000/1 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

StrK u X n A a n M !ipPrefix% ] vGatewayFilterFactory

  

  StripPrefix 网关过滤器工厂选用一个参数 StripPrefix,该参数表明在将恳求发送到下游之前从恳求中剥离的途径个数l g 3

spring:
  application:
    name: gateway-server # 运用称号
  cloud:
    gateway:
# 路由规矩
      routes:
        - idl { 2 P Z: productO Z ^ X J 2-service           # 路由 ID,仅有
          uriv s E 9 t S: lb://prod` ; . N G & @uct-service     # lb:// 依据服务称号从注册中心获取服务恳求地址
          predi + Q b ( )cates:                   # 断语(判别条件)
# 匹配对应 URI 的恳求,将匹配到的恳求追加在方针 URI 之后
            - Path=/**
          fg 5 P )  9 riltersX 1 N 7 v:                       # 网关过滤器
# 将 /api/123/product/1 重写为 /product/1
            - StripPrefix=2

  

  拜访:http://localhost:9000/api/1A ! } m ]23/product/1 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

SetPathGatewayFilterFactory

  

  SetPath 网关过滤器工厂选用途径模板参数。 它提供了一种经过答应模板化途径段来操作恳求途径的简略办法,运用了 Spring Framework 中的 uri 模板,答应多个匹配段 d n

spring:
  application:
    namb 0 h W X J p ?e: gateway-server # : J 运用称号
  cloud:
    gateway:
# 路由规矩
      routes:
        - id: product-service           # 路由 ID,仅有
          uri: lb://product-service     # lb://` c ) W u ^ , 依据服务称号从注册中心获取服务恳求地址
          predicates:                   # 断语(判别条件)
# 匹配对# * p 9 e X e b应 URI 的恳求,将匹配到的恳求追加在方针 URI 之后
            - Path=/api/product/{segment}
          filters:                       # 网关过滤器
# 将 /api/pro? ; 9 {duct/1 重写为 /product/1
            - SetPath=/product/{segment}

  

  拜访:http://localhost:9000/api/product/1 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

Parameter 参数过滤器

  

  AddRequestParaE f 8 Q Dm. Q Deter 网关过滤器工厂会将指定参数增加至匹配到的下游恳求中。

spring:
  application:
    name: gateway-servers j P 4 i O ^ s C # 运用称号
  cloud:
    gateway:
# 路由规矩
      routes:
        - id: product-sed * U J Drvice           # 路由 ID,仅有
          uri: lb://product-service     # lb:// 依据服务称号从注册中心获取服务恳求地址
          predicates:                   # 断语(判别条件)
# 匹配对应 URI 的恳求,将匹配到的恳求追P K D B a B加在方针 URI 之= , h R F
            - Path=/api-gateway/**
          filters:                       # 网关过滤器
# 将 /api-gateway/ph _ Zroduct/1 重写为 /product/1
            - RewritePath=/api-gaF e C / 6 q f i 4teway(?<segmentl k = 0 Z>/?.*), ${segment}
# 在下游恳求中增加 flag=1
            - AddRequL i l z 7 Z 5 6 mestParameter=flag, 1

  

  修G r ; e ( & , + C正产品服务的控制层代码。

package com.9 P 7 ]example.control| A Wler;
import com.example.pojo.Product;
import com.example.service.ProductService;
import org.springframeG J M ~ Ywork.beans.facf R * ) g itory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMappingI 9 4 1 O k H } ?;
import org.springframeworkx 6 Q K R ^ * Q.web.bind.annotation.PathVariable;
import org.springframework.web.bi) M j o { 8nd.annotatiov b 3 & c Qn.RequestMapping;
import org.springframework.web! I ( r ` P A E.bind.annotation.RestCon K P #troller;
@RestController
@RequestMapping("/product")
public class ProductController[ i h ? 6 B - {
@Autod q 7 n . 3 Twired
private ProductService productService;
/**
* 依据主键f Q ? x  s q ! %查询产品
*
* @param id
* @return
*/
@GetMapping("/{id}")
public@ . e 2 V a b Prh c : I } L Koduct selectProductById(@PathVariable("id") Integer id, String flag) {
System.out.println("flag = " + fla| % S H Qg);
return productService.selectProductById(id);
}
}

  

  拜访:http://localhost:9000/api-gateway/productB H I/1 控制台成果如下:! T K N d J

flag = 1

  

Status 状态过滤器

  

  SetStatus 网关过滤器工厂选用单个状态参数,它有必要是有用的 Spring Hl 3 . BttpStatX ) = uE 2 5 I 4s。它+ j / n # x能够是整数 404 或枚举 NOT_FOUNG g * g _ zD 的字符串表明。

spring:
  application:
    name: gateway-server # 运用称号
  cloud:
    gateway:
# 路由规矩
      routes:
        - id: product-service           # 路由 ID,仅有
          uri: lb://product-servv m B / aice     # lb:// 依据服务称号从注册中心获取服务恳求地址
          predicates:                   # 断语(判别条件)
#S $ - k v 0 匹配对应 URI 的恳求,将匹配到的恳求追加在方针 URI 之后
            - Path=/api-gateway/**g + C
          filt. W B 5 J R x x jers:                       # 网关过滤器
# 将 /api-gatewayH  8 r/product/1 重写为 /product/1
            - RewritePath=/api-gateway(} d X?<segmen7 k O /t>/?.*), ${segment}
# 任何情况下,呼应的 HTTP 状态都将设置为 404
            - SetStatusR ; Z h O @ U 8 5=404 			 # 404 或许对应的枚举 Nl 4 n XOT_FOUND

  

  拜访:http://localhost:9000/api-gateway/product/1 成X Q u F K果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

大局过滤器 GlobalFilter

6 r ( * 4 = R R

  大局过滤器不需求在装备文件中装备,效果在所有的路由上,终究经过 Gatewk – Y J 9 H hayFilterAdapter 包装成 GatewayFilterChain 可辨认的过滤器,它是恳求事务以及路由的 URI 转换为真实事务T * C u } } : x Y服务恳求地址的核心过滤器,不需求装备体系初始化时加载,并效果在每个路由上。

Spring Cloud 系列之 Gateway 服务网关(三)

  

自定义过滤器

  

  即便 Spring Cloud Gatec F [way 自带许多实用的 GatewayFilter Factory、D 0 [ ; # ( zGateway Filter、Global Filtera ` a (,但是在许多情形下咱们仍然希望能够自定义自己的过滤器,完成一些骚操作。

  

自定义网关过滤器

  

  自定义网关过滤器需求完成以下两个接口 :GatewayF7 & eilterOrdered

  

创立过滤器

  

  CustomGatewayFilter.java

package com.exaI ! M & ! g s 9mple.fill i o w dter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
importu  n / org.sp* f + 8ringframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 自定义网关过滤器
*/
public class CustomGatewayFiZ t b D p E % ,lter implements Gate` e [ d bwayFilter,@ Z $ ; + Ordered {
/**
* 过滤器事务逻辑
*
* @param exchanP t @ge
* @q = Z L E k D X 6param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExD E A ^ i J y ;change exc/ X y d Ohange, GatewayFilterCha! I g y P ; Cin chain) {
System.out.printlnI M E W I u("自定义网关过滤器被履行");
return chain.filA ? c g P F Z Cter(exchange); // 持续向下履行
}
/**
*t $ ~ }  @ ? H t 过滤器履行次序,数值越小,优先级越高
*
*@ I F I * = } F ! @return
*/k i c 0
@Override
public int getOrder() {
return 0;
}
}

  

注册过滤器

  

packv O y age com.example.config;
i2 + D F Amport com.example.filter.CustomGatewayFilter;
import org.springframework.cloud.gateway.route.RouteLoZ J N O & = .cator;
import org.springframe; f - ) U bwork.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.sprin) h X M | E )gframe. p 3 | N m ,work.context.ai 4 !nnotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 网关路由装备类
*/
@Configuration
public class GatewayRoutesConfiguration {
@Bean
public RouteLocator routeLX U A ] ;ocatorF 5 Y $(RouteLocatorBuildere U U f * builder) {
return builder.routes()L ? } ..route(r -> r
// 断语(判别条件)
.path("/product/3 x } C**")
// 方针 URI,路由到微服务的地址
.uri("lb://product-service")
// 注册自定义网关过滤器
.filters(new Cui + y c r EstomGatewayFilter())
//H j 7 Z 路由 ID,仅有
.id("product-service"))
.build();
}
}

  

拜访

  

  注释装备文件中所有网关装备,重启并拜访:http://H M K @ ?localhost:9~ 9 5 J / L 0 ~000/4 1 | f ? t iproduct/1 控制台成果如下:

自定义网关过滤器被履行

  

自定义大局过滤器

  

  自定义大局过滤器需求完成以下两个$ Q B接口 :GlobalFilterOrdeP = | 4 xred。经过大局过滤器能v r X + S r +够完成权限校验,安全性验证等功能。

  

创立过滤; O Z = o q K d

  

  完成指定接口,增S K { _ t r@Component 注解即可。

  CustomGlobalFilter.java

package com.example.filter;
import org.springfraO K J }mework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
imO 3 S ^ eport org.springframework.l Z icore.Ordered;
import org.springframework.stereotype.Component;
import org.spring= E 6 x 7 K + } Aframework.web.server.ServerWebExchange;
import reactor.c& O ;ore.publisher.Mono;
/**
* 自i V O [ M I C !定义大局过滤器
*/
@Component
public class CustomGlobalFilter implements Globa= - E (lFilteO w ) } u B 5 lr, Ordered {z R | u C i c
/**
* 过滤器事务逻辑
*
* @param exchange
* @param chain
* @return
*/
@ H lOverride
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Syst7 + ; ; 8 Qem.out.println("自定义大局过滤器被(  } f履行");
return chain.filter(exchange); // 持续向q I y下履行
}
/**
* 过滤器履行次序,数值越小,优先级越高
*
* @return
*/
@Ove# m vrride
public( x i h 0 ^ P iA z 5 /nt getOrder() {
return 0;
}
}

  

拜访

  

  拜访:http://localhost:9000/product/1 控f 1 v Y 2制台成果如下:

自定义大局过滤d , N { G p u l ]器被履行

  

一致鉴权

  

  接下来咱们在网关过滤器中经过 token 判别用户是否登录,完成一个一致鉴权事例。

  

创立过滤器

  

  AccessFilter.java

package com.examplew s T _.filter;
import org.slf4j.LogY c E T L @ iger;
import org.slf4j.LoggerFactory;
import org.springframework.clou) ! M / T Nd.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.fY : ` i 7ilter.GlobalFy t hilter;
import org.springframework.core.Ordered;
import org.s@ , C S c O = 0 ^pringframework.core.io.buffer.DataBuffer;
impory y ^t org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttp; u l 0 k v vRespw A | = | ! (  Uonse;
import org.springframework.stereotype.Component;
import org.springframework.web.m } X b 7server.Ser, O d Q } h A CverWebEx7 , I . 3change;
import reactor.core.V n 6 w A 8 Rpublisher.Mono;
/**
* 权限验证过滤器
*/
@Component
publ^ W f ` Iic class AccessFilter implements GlobalFilter, Ordered {
private Logger logger = LoggerFactory.getLogger(AccessFiltV ^ P k u ) ber.class);
/**
* 过滤* I ` d器事务逻辑
*
* @param exchange
* @para# ) o h Q 0 , om chain
* @returni 1 M z ) A U
*/
@Override
puQ Y 7 { /blic Mono<Void> filter(ServerU ` Z m q - A QWebExchang T I 6 } q ? ` ?e exchange, GateJ N g pwZ R 6 v f S = VayFilterChain chain) {
// 获取恳求参数
Sti V s &ring token = exchange.getRequest().getQux | , A I U ; | 2eryParams().ge/ N 1tFirst("token) B ` Y & F - f w"b Z . P);
// 事务逻辑处理
if (null == token) {
logger.warn("toW E ( 2 wkenM z Q c 4 is null...");
ServerHttpRes0 a ~ $ponse response = exchangv v De.getResponse();
// 呼应类型
response.getHeaders().add("ContZ * & h H Uent-Type", "applA | | Eication/json; charset=utf-8");
// 呼应状态码,HTTP 401 过错代表用户没有拜访权限
response.setStatusCode(HttpStatus.UNAUTHORIZED);
// 呼应内容
String mk _ T T d W n 1 Pessage = "{"message":"" + HttpStatus.UNAUTHORIZED.getReasonPhrase() + a t $ T O i j i""}";
DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());
// 恳求结束,不在持续向下恳求Z 9  1 B Q E ~ m
retu~ Z m }  8rn response.writeWith(Mono.just(buffer));
}
// 运用 token 进行身份验证
logger.info("token is OK!");
return chain.filter(exchange);
}
/**
* 过滤器履行次序,数值越小,优先级越高
*
* @J x h j |return
*/
@Override
public int getOrder() {
reE # w Rturn 1;
}
}

  

拜访

  

  拜访:http://locav { v h R # nlhost:~ ? b z 2 g A P9000/product/1 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

  

  拜访:http://localhost:9000/product/1?token=abc123 成果如下:

Spring Cloud 系列之 Gateway 服务网关(三)

下一篇咱们解说 Gateway 网关如何完成限流、整合Sentinel完成限流以及高可用网关环境搭建,记得重视噢~

Spring Cloud 系列之 Gateway 服务网关(三)

  本文选用 知识同享「署名-非商业性运用-禁止演绎 4.0 国际」答应协议

  咱们能够经过d T A s g K 分类 查看更多关于 Springu / _ B Cloud 的文章。

  

   您的点赞转发是对我最大的支撑。

   扫码重视 哈喽沃德先生「文档 + 视频」每篇文章都配有专门视频解说,学习更轻松噢 ~

Spring Cloud 系列之 Gateway 服务网关(三)
Spring Cloud 系列之 Gateway 服务网关(三)

发表评论

提供最优质的资源集合

立即查看 了解详情