前言 This project provides a library for building an API Gateway on top of Spring WebFlux. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.(官网 )
引入依赖 pom.xml
1 2 3 4 <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-gateway</artifactId > </dependency >
将网关加入到Eureka注册中心 添加依赖 pom.xml
1 2 3 4 <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-eureka-client</artifactId > </dependency >
添加注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient @SpringBootApplication public class GatewayApplication { public static void main (String[] args) { SpringApplication.run(GatewayApplication.class, args); } }
修改配置 src/main/resources/application.yml
1 2 3 4 5 6 7 8 9 server: port: 8100 spring: application: name: gateway eureka: client: service-url: defaultZone: http://127.0.0.1:8000/eureka
实现请求的路由 添加配置
当请求的路径符合路由的断言规则时,将请求转发到路由的目标路径
spring.cloud.gateway.default-filters
:默认过滤器,对所有路由都生效(DefaultFilter)spring.cloud.gateway.routes.id
:路由的idspring.cloud.gateway.routes.uri
:路由的目标路径
lb://服务名
:根据服务名发送请求http://ip地址
:根据ip地址发送请求spring.cloud.gateway.routes.predicates
:对指定路由的断言spring.cloud.gateway.routes.filters
:对指定路由的过滤器
src/main/resource/application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 spring: cloud: gateway: routes: - id: eureka-service-user uri: lb://eureka-service-user predicates: - Path=/users/** - id: eureka-service-user uri: http://127.0.0.1:8082 predicates: - Path=/orders/** filters: - AddRequestHeader=key, value default-filters: - AddRequestHeader=key, value
路由的断言
spring.cloud.gateway.routes.predicates.After
:指定时间之后spring.cloud.gateway.routes.predicates.Before
:指定时间之前spring.cloud.gateway.routes.predicates.Between
:指定时间之间spring.cloud.gateway.routes.predicates.Cookie
:指定符合条件的Cookiespring.cloud.gateway.routes.predicates.Header
:指定符合条件的Headerspring.cloud.gateway.routes.predicates.Host
:指定符合条件的请求域名spring.cloud.gateway.routes.predicates.Method
:指定符合条件的请求方式spring.cloud.gateway.routes.predicates.Path
:指定符合条件的请求地址spring.cloud.gateway.routes.predicates.Query
:指定符合条件的请求参数spring.cloud.gateway.routes.predicates.RemoteAddr
:指定符合条件的请求IP范围spring.cloud.gateway.routes.predicates.Weight
:指定符合条件的组和权重
src/main/resource/application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 spring: cloud: gateway: routes: - predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] - Before=2017-01-20T17:42:47.789-07:00[America/Denver] - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00 [America/Denver ] - Cookie=chocolate, ch.p - Header=X-Request-Id, \d+ - Host=**.somehost.org,**.anotherhost.org - Method=GET,POST - Path=/red/{segment},/blue/{segment} - Query=green - RemoteAddr=192.168.1.1/24 - Weight=group1, 2
路由的过滤器
spring.cloud.gateway.routes.filters.AddRequestHeader
:添加请求头spring.cloud.gateway.routes.filters.RemoveRequestHeader
:移除请求头spring.cloud.gateway.routes.filters.SetRequestHeader
:设置请求头
spring.cloud.gateway.routes.filters.AddRequestParameter
:添加请求参数spring.cloud.gateway.routes.filters.RemoveRequestParameter
:移除请求参数
spring.cloud.gateway.routes.filters.AddResponseHeader
:添加响应头spring.cloud.gateway.routes.filters.RemoveResponseHeader
:移除响应头spring.cloud.gateway.routes.filters.SetResponseHeader
:设置响应头spring.cloud.gateway.routes.filters.RewriteResponseHeader
:重写响应头spring.cloud.gateway.routes.filters.RewriteLocationResponseHeader
:重写响应头中的Location
spring.cloud.gateway.routes.filters.PrefixPath
:请求路径添加前缀spring.cloud.gateway.routes.filters.StripPrefix
:请求路径修剪前缀
spring.cloud.gateway.routes.filters.SetPath
:设置请求路径spring.cloud.gateway.routes.filters.RewritePath
:重写请求路径
spring.cloud.gateway.routes.filters.RequestHeaderSize
:请求头大小spring.cloud.gateway.routes.filters.RedirectTo
:请求转发spring.cloud.gateway.routes.filters.SaveSession
:保存Sessionspring.cloud.gateway.routes.filters.SetStatus
:设置状态码
src/main/resource/application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 spring: cloud: gateway: routes: - filters: - AddRequestHeader=key, value - AddRequestParameter=red, blue - AddResponseHeader=X-Response-Red, Blue - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin - PrefixPath=/mypath - RedirectTo=302, https://acme.org - RemoveRequestHeader=X-Request-Foo - RemoveResponseHeader=X-Response-Foo - RemoveRequestParameter=red - RequestHeaderSize=1000B - RewritePath=/red/?(?<segment>.*), /$\{segment} - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, , - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=*** - SaveSession - SetPath=/{segment} - SetRequestHeader=X-Request-Red, Blue - SetResponseHeader=X-Response-Red, Blue - SetStatus=401 - StripPrefix=2
全局过滤器(GlobalFilter) 通过注解指定优先级
@Order()
:指定过滤器在过滤器链上的优先级,数字越小,优先级越高,范围是[-214783647,214783647],默认值为最大值,优先级最低
src/main/java/com/filter/AuthorizeFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.annotation.Order;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.stereotype.Component;import org.springframework.util.MultiValueMap;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;@Order(0) @Component public class AuthorizeFilter implements GlobalFilter { @Override public Mono<Void> filter (ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> params = request.getQueryParams(); String param = params.getFirst("key" ); if ("value" .equals(param)) { return chain.filter(exchange); } exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } }
通过实现接口指定优先级
通过重写getOrder()
方法指定过滤器在过滤器链上的优先级,在返回值中指定,数字越小,优先级越高
src/main/java/com/filter/AuthorizeFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.stereotype.Component;import org.springframework.util.MultiValueMap;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;@Component public class AuthorizeFilter implements GlobalFilter , Ordered { @Override public Mono<Void> filter (ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> params = request.getQueryParams(); String param = params.getFirst("key" ); if ("value" .equals(param)) { return chain.filter(exchange); } exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } @Override public int getOrder () { return 0 ; } }
过滤器的排序规则
过滤器有三种类型,分别是:全局过滤器、默认过滤器、路由过滤器
在配置文件中定义过滤器时,先配置的过滤器默认权值从1开始依次递增
先比较权值,权值越小,优先级越高
相同权值的过滤器,再比较类型,类型的优先级是:默认过滤器 > 路由过滤器 > 全局过滤器
举例
1 默认过滤器1 > 路由过滤器1 > 全局过滤器1 > 默认过滤器2 > 路由过滤器3
跨域处理
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping
:解决OPTIONS请求被拦截的问题spring.cloud.gateway.globalcors.cors-configurations.''
:指定哪些请求被跨域处理spring.cloud.gateway.globalcors.cors-configurations.''.allowedOrigins
:指定允许跨域请求的网站spring.cloud.gateway.globalcors.cors-configurations.''.allowedMethods
:指定允许跨域请求的请求类型spring.cloud.gateway.globalcors.cors-configurations.''.allowedHeaders
:指定允许跨域请求的请求头携带信息spring.cloud.gateway.globalcors.cors-configurations.''.allowCredentials
:是否允许携带Cookiespring.cloud.gateway.globalcors.cors-configurations.''.maxAge
:本次跨域检测的有效期
src/main/resources/application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 spring: cloud: gateway: globalcors: add-to-simple-url-handler-mapping: true cors-configurations: '[/**]' : allowedOrigins: - "http://simple.com" allowedMethods: - "GET" - "POST" - "DELETE" - "PUT" - "OPTIONS" allowedHeaders: "*" allowCredentials: true maxAge: 360000
踩坑
启动失败,报错:Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
原因
解决问题
去除spring-boot-starter-web
依赖
完成 参考文献 哔哩哔哩——黑马程序员