SpringCloudAlibaba - Gateway 自定义路由谓词工厂
前言
Route
(路由)是Spring Cloud Gateway
的基础元素,就是一个转发规则,其包含ID
、目标URL
、Predicate
集合以及Filter
集合
环境
Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE
路由配置示例
- 如果访问
gateway的/baidu
这个路径就会进入该路由,会用AddRequestHeader
这个过滤器去处理,再将请求转发到http://www.baidu.com
spring:
cloud:
gateway:
routes:
- id: some_route
uri: http://www.baidu.com
predicates:
- Path=/baidu
filters:
- AddRequestHeader=X-Request-Foo, Bar
路由配置的两种形式
路由到指定URL
通配
- 访问
GATEWAY_URL/**
会转发到http://www.baidu.com/**
spring:
cloud:
gateway:
routes:
- id: {唯一标识}
uri: http://www.baidu.com
精确匹配
- 访问
GATEWAY_URL/user-center/user/
转发到http://www.coisini.club/user-center/user/
spring:
cloud:
gateway:
routes:
- id: {唯一标识}
uri: http://www.coisini.club/user-center/user/
路由到微服务
通配
- 访问
GATEWAY_URL/**
转发到user-center
微服务的/**
spring:
cloud:
gateway:
routes:
- id: {唯一标识}
uri: lb://user-center
精确匹配
- 访问
GATEWAY_URL/user-center/user/name
转发到user-center
微服务的/user/name
spring:
cloud:
gateway:
routes:
- id: {唯一标识}
uri: lb://user-center/user/name
路由谓词工厂
路由谓词工厂(Route Predicate Factories
)是作用在指定路由之上的一堆谓词条件
内置的路由谓词工厂
谓词工厂 | 作用 | 参数 |
---|---|---|
After | 请求时的时间在配置的时间后时转发该请求 | 一个带有时区的具体时间 |
Before | 请求时的时间在配置的时间前时转发该请求 | 一个带有时区的具体时间 |
Between | 请求时的时间在配置的时间段内时转发该请求 | 一个带有时区的具体时间段 |
Cookie | 请求时携带的Cookie名称及值与配置的名称及值相符时转发该请求 | Cookie的名称及值,支持使用正则表达式来匹配值 |
Header | 请求时携带的Header名称及值与配置的名称及值相符时转发该请求 | Header的名称及值,支持使用正则表达式来匹配值 |
Host | 请求时名为Host的Header的值与配置的值相符时转发该请求 | Host的值,支持配置多个且支持使用通配符 |
Method | 请求时所使用的HTTP方法与配置的请求方法相符时转发该请求 | HTTP请求方法,例如GET、POST等 |
Path | 请求时所访问的路径与配置的路径相匹配时转发该请求 | 通配符、占位符或具体的接口路径,可以配置多个 |
Query | 请求时所带有的参数名称与配置的参数名称相符时转发该请求 | 参数名称和参数值(非必须),支持使用正则表达式对参数值进行匹配 |
RemoteAddr | 请求时的IP地址与配置的IP地址相符时转发该请求 | IP地址或IP段 |
Method 谓词工厂示例
Method
谓词工厂示例,当HTTP
请求方法是GET
时才转发
gateway:
discovery:
locator:
# 让gateway通过服务发现组件找到其他的微服务
enabled: true
routes:
- id: method_route
uri: lb://user-center
predicates:
# 当HTTP请求方法是GET时,才会转发用户微服务
# 如请求方法满足条件,访问http://localhost:8040/** -> user-center/**
# eg. 访问http://localhost:8040/test/coisini -> user-center/test/coisini
- Method=GET
GET
请求测试
POST
请求测试
自定义路由谓词工厂
- 实现限制服务只能在
09:00 - 17:00
内才可以访问
代码配置
application.yml
spring:
application:
name: core-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: user-center
uri: http://www.baidu.com
predicates:
- TimeBetween=上午9:00,下午5:00
TimeBetweenConfig.java
import lombok.Data;
import java.time.LocalTime;
@Data
public class TimeBetweenConfig {
private LocalTime start;
private LocalTime end;
}
TimeBetweenRoutePredicateFactory.java
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* 自定义路由谓词工厂
* 路由谓词工厂必须以RoutePredicateFactory结尾
*/
@Component
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenConfig> {
public TimeBetweenRoutePredicateFactory() {
super(TimeBetweenConfig.class);
}
/**
* 控制路由的条件
* @param config
* @return
*/
@Override
public Predicate<ServerWebExchange> apply(TimeBetweenConfig config) {
LocalTime start = config.getStart();
LocalTime end = config.getEnd();
return exchange -> {
LocalTime now = LocalTime.now();
return now.isAfter(start) && now.isBefore(end);
};
}
/**
* 控制配置类和配置文件的映射关系
* @return
*/
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("start", "end");
}
}
测试
09:00 - 17:00
外访问
09:00 - 17:00
内访问