Spring Cloud Gateway基础

介绍

技术 特性 适用场景 说明
Spring Cloud Gateway - 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 动态路由
- Predicates 和 Filters 作用于特定路由
- 集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- 限流
- 路径重写
- 微服务网关
- 蓝绿部署
- 官网
- Github
- Doc

基本概念

Predicate

Predicate 来源于 Java 8,是 Java 8 中引入的一个函数。
Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与(and)、或(or)、非(negate))。
可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。

Spring Cloud Gateway 内置 Predicate 规则

Spring Cloud Gateway 内置 Predicate 规则 说明
After Route Predicate 在某个时间之后的请求的请求都进行转发
Before Route Predicate 在某个时间之前的请求的请求都进行转发
Cookie Route Predicate 通过 Cookie 匹配。可以接收两个参数:
- Cookie name
- 正则表达式
Header Route Predicate 通过 Header 属性匹配。可以接收两个参数:
- header属性名称
- 正则表达式
Host Route Predicate 通过 Host 匹配。
接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。
通过请求方式匹配 可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由
Path Route Predicate 通过请求路径匹配。接收一个匹配路径的参数来判断是否走路由。
Query Route Predicate 通过请求参数匹配。支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。
RemoteAddr Route Predicate 通过请求 ip 地址进行匹配
组合使用 可以将各种 Predicate 组合起来一起使用

过滤器类型

过滤器类型 说明
GlobalFilter 全局过滤器
GatewayFilter 局部过滤器

常见问题

配置跨域

CustomWebFluxConfig.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
38
39
40
41
42
43
44
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;

@Configuration
public class CustomWebFluxConfig implements WebFluxConfigurer {

/**
* 全局跨域配置,根据各自需求定义
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*")
.exposedHeaders(HttpHeaders.SET_COOKIE);
}

/**
* 也可以继承CorsWebFilter使用@Component注解,效果是一样的
* @return
*/
@Bean
CorsWebFilter corsWebFilter(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addExposedHeader(HttpHeaders.SET_COOKIE);
CorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
((UrlBasedCorsConfigurationSource) corsConfigurationSource).registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(corsConfigurationSource);
}
}

CorsResponseHeaderFilter.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
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.ArrayList;

@Component("corsResponseHeaderFilter")
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
// 指定此过滤器位于NettyWriteResponseFilter之后
// 即待处理完响应体后接着处理响应头
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
}

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.defer(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
.forEach(kv -> {
kv.setValue(new ArrayList<String>() {{
add(kv.getValue().get(0));
}});
});

return chain.filter(exchange);
}));
}
}

禁止白页(Whitelabel Error Page)

1
2
3
4
server:
error:
whitelabel:
enabled: false

常见错误

常见错误

'org.springframework.http.codec.ServerCodecConfigurer' that could not be found

问题描述

1
Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.

问题分析

依赖冲突,spring-cloud-starter-gateway与spring-boot-starter-web和依赖冲突。 所以,用spring-boot-starter-webflux替换掉spring-boot-starter-web

解决办法

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

参考

开源

文章

坚持原创技术分享,您的支持将鼓励我继续创作!
0%