搭建网关服务
1.新建一个module,引入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>2.1.0</version> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
|
2.编写路由配置以及nacos配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| server: port: 10010 logging: level: cn.ezio: debug pattern: dateformat: MM-dd HH:mm:ss:SSS spring: application: name: gateway cloud: nacos: server-addr: localhost:8848 gateway: routes: - id: user-service uri: lb://userservice predicates: - Path=/user/** - id: order-service uri: lb://orderservice predicates: - Path=/order/**
|
路由的过滤器配置 GatewayFilter
在配置用添加过滤器配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| spring: application: name: gateway cloud: nacos: server-addr: localhost:8848 gateway: routes: - id: user-service uri: lb://userservice predicates: - Path=/user/** - id: order-service uri: lb://orderservice predicates: - Path=/order/** default-filters: - AddRequestHeader=Truth,Java is Best!
|
自定义路由断言工厂
继承 AbstractRoutePredicateFactory 类
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
| @Component @Slf4j public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() { super(Config.class); }
@Override public Predicate<ServerWebExchange> apply(Config config) { return exchange -> { if (config.getName().equals("ylw")) { log.info("路由失败"); return false; } return true; }; }
@Override public List<String> shortcutFieldOrder() { return Collections.singletonList("name"); }
public static class Config {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
}
|
自定义过滤器工厂
继承 AbstractGatewayFilterFactory 或 AbstractNameValueGatewayFilterFactory 类,两者区别在于接受参数的个数,前者一个,后者可接受两个。
- Pre 类型过滤器,逻辑处理在 chain.filter() 之前。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Component @Slf4j public class PreGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override public GatewayFilter apply(NameValueConfig config) { return (exchange, chain) -> { log.info("调用PreGatewayFilterFactory===" + config.getName() + ":" + config.getValue()); ServerHttpRequest request = exchange.getRequest(); HttpHeaders headers = request.getHeaders(); System.out.println("请求头:" + headers); return chain.filter(exchange); }; } }
|
- Post 类型过滤器,逻辑处理在 chain.filter() 执行后。
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 45
| @Component @Slf4j public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() { super(Config.class); }
@Override public GatewayFilter apply(Config config) { return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("调用PostGatewayFilterFactory===" + config.getName() + ":" + config.getValue()); })); }
@Override public List<String> shortcutFieldOrder() { return Arrays.asList(GatewayFilter.NAME_KEY, GatewayFilter.VALUE_KEY); }
public static class Config {
private String name;
private String value;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; } }
}
|
自定义全局过滤器 GlobalFilter
实现GlobalFilter接口,自定义处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Component @Slf4j public class MyGlobalFilter implements GatewayFilter, Ordered {
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info(exchange.getRequest().getPath().value()); return chain.filter(exchange); }
@Override public int getOrder() { return -1; } }
|
过滤器执行链顺序
请求进入网关,会经过三种过滤器:局部路由过滤器、DefaultFilter、GlobalFilter。
请求路由后,会将当 局部路由过滤器、DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器。

Order值相同时:
1.两个GlobalFilter类型的过滤器Order值相同时,根据文件名字母排序,文件名靠前的优先更高。
原因是包扫描时是按照文件的顺序扫描的,然后封装到List集合的,通过Order值排序时如果Order值相同,文件名在前名的依然会排在前面。
2.GlobalFilter类型和GatewayFilter类型的过滤器Order值相同时,GlobalFilter类型优先更高。
原因是这两种过滤器最终会合并到一个过滤器集合中形成过滤器调用链,源码是通过list.addAll();方法将GatewayFilter类型的过滤器加到了GlobalFilter过滤器集合中,addAll()是末尾添加方式,所以Order值相同时GatewayFilter类型的过滤器会排在后面。
Order值生成规则:
1.GlobalFilter类型过滤器,通过实现Ordered接口的getOrder()方法设置。
2.GatewayFilter类型过滤器,通过配置文件中配置的过滤器顺序自动生成,固定从1开始封装,例如配置了三个过滤器,则按照从上往下顺序Order值依次为1、2、3。
网关跨域问题处理
跨域:域名不一致或端口不同,浏览器的同源策略导致的跨域问题。浏览器禁止请求的发起者与服务端发生跨域的ajax请求,请求被浏览器拦截。
