GateWay使用手册
好的,下面是优化后的版本。为了提高可读性和规范性,我对内容进行了结构化、简化了部分代码,同时增加了注释说明,便于理解。
1. 引入依赖
在 pom.xml
中添加以下依赖:
<dependencies>
<!-- Spring Cloud Gateway:提供API网关功能 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos Discovery:用于服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Spring Cloud Loadbalancer:提供客户端负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
2. 启动类 (GateApplication.java
)
定义主启动类,启动 Spring Boot 应用:
@SpringBootApplication // 标明这是Spring Boot应用的入口
public class GateApplication {
public static void main(String[] args) {
SpringApplication.run(GateApplication.class, args); // 启动应用
}
}
3. 配置文件 (application.yml
)
配置网关的基本设置、Nacos 服务发现以及路由规则。
server:
port: 8080 # 配置网关监听的端口
spring:
application:
name: gateway # 应用名称,用于 Nacos 等服务发现
cloud:
nacos:
discovery:
server-addr: xiaotianlong.xyz:8848 # 配置 Nacos 服务器地址
gateway:
routes: # 配置网关的路由规则
# 路由规则 1
- id: service_name # 路由的唯一ID
uri: lb://service_name # 使用负载均衡访问注册到 Nacos 中的服务
predicates:
- Path=/user/** # 请求路径以 `/user/` 开头时触发此路由
filters:
- AddRequestHeader=X-Request-Foo, Bar # 添加请求头
# 路由规则 2
- id: service_name2
uri: lb://service_name2
predicates:
- Path=/order/** # 请求路径以 `/order/` 开头时触发此路由
4. 自定义全局过滤器
定义一个全局过滤器,记录请求的时间并打印日志。
@Component // 声明为Spring组件
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 记录请求开始时间
System.out.println("请求开始时间: " + System.currentTimeMillis());
// 放行请求
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> {
// 记录请求结束时间
System.out.println("请求结束时间: " + System.currentTimeMillis());
}));
}
@Override
public int getOrder() {
// 过滤器的执行顺序,数字越小优先级越高
return 0;
}
}
5. 自定义Gateway过滤器
创建一个自定义的 Gateway 过滤器工厂,允许动态配置过滤器的参数。
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {
// 内部配置类,允许用户配置过滤器的参数
@Data
public static class Config {
private String pattern = "yyyy-MM-dd"; // 设置默认日期格式
private String message = "默认日志信息"; // 自定义日志信息
}
public MyGatewayFilterFactory() {
super(Config.class); // 指定配置类类型
}
@Override
public List<String> shortcutFieldOrder() {
return List.of("pattern", "message"); // 设置快捷字段顺序
}
@Override
public GatewayFilter apply(Config config) {
// 创建过滤器逻辑
return new OrderedGatewayFilter((exchange, chain) -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(config.getPattern());
System.out.println("请求开始时间: " + formatter.format(LocalDateTime.now()));
System.out.println(config.getMessage()); // 打印自定义日志信息
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> {
System.out.println("请求结束时间: " + formatter.format(LocalDateTime.now()));
}));
}, 1);//在这里设置顺序
}
}
6. 配置自定义过滤器
在 application.yml
文件中配置自定义的 MyGatewayFilterFactory
过滤器,使其生效:
spring:
cloud:
gateway:
routes:
- id: example_route
uri: lb://some-service
predicates:
- Path=/somepath/** # 路径匹配条件
filters:
- name: My # 使用自定义过滤器
args:
pattern: "yyyy-MM-dd~HH:mm:ss" # 自定义日期格式
message: "这是一个统计时间的gateway过滤器" # 自定义日志信息
或者
spring:
cloud:
gateway:
routes:
- id: example_route
uri: lb://some-service
predicates:
- Path=/somepath/** # 路径匹配条件
filters:
# 由于设置了shortcutfieldorder,所以可以这样写
- My="yyyy-MM-dd~HH:mm:ss", "这是一个统计时间的gateway过滤器"
7.案例:登录检验
@Component
@EnableConfigurationProperties(AuthProperties.class)
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Resource
private AuthProperties authProperties;
@Resource
private JwtTool jwtTool;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取request
ServerHttpRequest request = exchange.getRequest();
//2.判断路径是否需做登录拦截
List<String> excludePaths = authProperties.getExcludePaths();
if (isExclude(request.getPath())) {
//此时不需要拦截,直接放行
return chain.filter(exchange);
}
//3.获得token
String token = request.getHeaders().getFirst("authorization");
//4.检验并解析token
Long userId = null;
try {
userId = jwtTool.parseToken(token);
} catch (Exception e) {
//设置响应状态码为401
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//拦截
return response.setComplete();
}
//todo 5.传递用户信息
//6.放行
return chain.filter(exchange);
}
private boolean isExclude(RequestPath path) {
List<String> excludePaths = authProperties.getExcludePaths();
for (String pattern : excludePaths) {
if (antPathMatcher.match(pattern, path.toString())) {
return true;
}
}
return false;
}
@Override
public int getOrder() {
return 0;
}
}
原文地址:https://blog.csdn.net/qq_42798343/article/details/144096542
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!