前言
An API Gateway built on Spring Framework and Spring Boot providing routing and more.(Github)
添加依赖
pom.xml1 2 3 4
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
|
将网关加入到Eureka注册中心
添加依赖
pom.xml1 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.yml1 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:路由的id
spring.cloud.gateway.routes.uri:路由的目标路径
lb://服务名:根据服务名发送请求
http://ip地址:根据ip地址发送请求
spring.cloud.gateway.routes.predicates:对指定路由的断言
spring.cloud.gateway.routes.filters:对指定路由的过滤器
src/main/resource/application.yml1 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:指定符合条件的Cookie
spring.cloud.gateway.routes.predicates.Header:指定符合条件的Header
spring.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.yml1 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:保存Session
spring.cloud.gateway.routes.filters.SetStatus:设置状态码
src/main/resource/application.yml1 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.java1 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.java1 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:是否允许携带Cookie
spring.cloud.gateway.globalcors.cors-configurations.''.maxAge:本次跨域检测的有效期
src/main/resources/application.yml1 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依赖
完成
参考文献
哔哩哔哩——黑马程序员