Gateway(拦截器/路由)入门
Gateway(拦截器/路由)Gateway 核心是一系列的过滤器 主要作用 过滤和路由整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息Geteway本身就是一个微服务,需要注册到Eureka中心不管是来自于客户端(PC或移动端)的请求,还是服务内部调用,一切服务的请求都可以经过网关实现鉴权 动态路由 服务的统一入口1.使用Gateway拦截请求中带 /users/ 的请求拦截http
Gateway(拦截器/路由)
Gateway 核心是一系列的过滤器 主要作用 过滤和路由
整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息
Geteway本身就是一个微服务,需要注册到Eureka中心
不管是来自于客户端(PC或移动端)的请求,还是服务内部调用,一切服务的请求都可以经过网关
实现鉴权 动态路由 服务的统一入口
1.使用Gateway
拦截请求中带 /users/ 的请求
拦截http://localhost:10086/users/2 — 跳转到------->http://localhost:8081
1.添加依赖 pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.在启动类添加注解
@EnableDiscoveryClient //启用Gateway
@SpringBootApplication
@EnableDiscoveryClient //启用Gateway
public class Demo04GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(Demo04GatewayApplication.class,args);
}
}
3.配置.properties文件
拦截的请求类型spring.cloud.gateway.routes[0].predicates[0]=Path=/users/**
# service name
spring.application.name=demo04-gateway
#port
server.port=10086
# 找到Eureka的地址
eureka.client.service-url.defaultZone=http://localhost:8083/eureka,http://localhost:8084/eureka
# 路由id
spring.cloud.gateway.routes[0].id=demo04_gateway_1001
# provider的一个服务地址,就是拦截到之后跳到的地址
spring.cloud.gateway.routes[0].uri=http://localhost:8081
# 拦截的断言 要拦截带有/**的url
spring.cloud.gateway.routes[0].predicates[0]=Path=/users/**
4.测试
输入http://localhost:10086/users/1 转到http://localhost:8081/users/1拿到该provider的返回的结果
2.动态路由(面向服务的路由:之前把服务地址写死是不合理的,所以就要使用动态路由)
以(lb://lb://user-service为例)
原理:Gateway通过LoadBalanceClient把user-service通过Eureka解析成具体的host和端口,并进行负载均衡
使用在Eureka中注册的服务作为路由地址,而不是写死的地址
动态路由(面向服务的路由):在配置文件中指定路由路径类似于:
lb://lb://user-service
3.路由前缀处理 filter(对请求到网关的服务地址添加或者去除前缀)
请求地址与微服务的服务地址如果不一致的时候,可以通过配置路径过滤器实现路径前缀的添加和去除
添加
http://localhost:10086/3->http://localhost:10086/users/3
# 添加前缀
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
# 添加前缀 在客户端的请求地址上添加/users
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users
减少
http://localhost:10086/api/users/3->http://localhost:10086/users/3
# 减少前缀 在客户端的请求地址上减少前缀
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**
# 1表示去除一前缀,2表示两个,一次类推
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1
4.过滤器(请求鉴权、异常处理、记录调用时长)
1.介绍
1.符合条件的请求放行,否则不放行
# 默认过滤器 spring.cloud.gateway.default-filters对所有的路由都生效
spring.cloud.gateway.default-filters[0]=AddResponseHeader=name,rose
spring.cloud.gateway.default-filters[1]=AddResponseHeader=age,34
2.过滤器分为两种
1)局部过滤器
只对当前路由起作用
1)spring.cloud.gateway.routes.filters
2)全局过滤器
作用在所有的路由上
1)spring.cloud.gateway.default-filters + 实现GatewayFilterFactory接口的过滤器
2) 实现GlobalFilter接口,不需要配置
2.自定义全局过滤器(判断url中是否有token参数,可以用于判断user对象是否为空)
1.实现接口
GlobalFilter接口 重写filter方法 拿到token,判断token是否为空,不为空则放行,如果token为null或者不存在则设置返回的状态码为:未授权
Order接口 重写getOrder()方法 系统调用该方法获得过滤器的优先级,返回的数字越小优先级越高
2.编写filter方法中的逻辑
package com.zx.demo04gateway.filter;
@Component
@Slf4j
public class MyParamGlobalFilter implements GlobalFilter , Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//拦截方法,拦截到请求后,自动执行
log.info("filter 拦截方法,拦截到请求后,自动执行 ");
//以后开发中,不会将 user对象存到session,只会在地址上带上token
//根据token是否有空可以判断是否登录
//http://localhost:8001/users/3?token=10001&pageSize=30
String token = exchange.getRequest().getQueryParams().getFirst("token");
if(token == null || "".equals(token)){
//未登录 跳转到登录页
log.info("----跳到登录页面");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
exchange.getResponse().setComplete();
}
return chain.filter(exchange);//2 全部放行
}
@Override
public int getOrder() {
//3:系统调用该方法获得过滤器的优先级
return 1; //数字越小,越优先
}
}
3.自定义局部过滤器(请求鉴权、异常处理、记录调用时长)
1.添加局部过滤器配置
spring.cloud.gateway.routes[0].filters[1]=MyParam=name,address
2.继承AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> 抽象类
重写apply方法
3.编写静态内部类Config 要拦截的参数名
@Data
public static class Config{
private String name;
private String address;
}
4.将config交给父类的构造方法
public MyParamGatewayFilterFactory() {
super(Config.class);
}
5.编写shortcutFieldOrder()方法,定义变量顺序
@Override
public List<String> shortcutFieldOrder() {//定义变量的顺序
List<String> order = new ArrayList<>();
order.add("name");
order.add("address");
return order;
}
6.编写重写的apply方法
因为返回的类型是一个接口 GatewayFilter,所以还要定义一个类(直接实例化接口,重写方法)来实现GatewayFilter接口,重写其中的 filter()方法
public GatewayFilter apply(Config config) {
GatewayFilter gatewayFilter = new GatewayFilter(){
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//http://localhost:10086/api/users/1?token=1&name=jack&address=zs
String name = exchange.getRequest().getQueryParams().getFirst(config.name);
String address = exchange.getRequest().getQueryParams().getFirst(config.address);
log.info("filter ....name"+name);
log.info("filter ....address"+address);
log.info("filter ....拦截了请求");
return chain.filter(exchange);//全部放行
}
};
return gatewayFilter;//返回一个自己定义的过滤器
}
7.全部的MyParamGatewayFilterFactory类
package com.zx.demo04gateway.filter;
@Component
@Slf4j
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {
//5:将config交给父类的构造方法
public MyParamGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
GatewayFilter gatewayFilter = new GatewayFilter(){
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//http://localhost:10086/api/users/1?token=1&name=jack&address=zs
String name = exchange.getRequest().getQueryParams().getFirst(config.name);
String address = exchange.getRequest().getQueryParams().getFirst(config.address);
log.info("filter ....name"+name);
log.info("filter ....address"+address);
log.info("filter ....拦截了请求");
return chain.filter(exchange);//全部放行
}
};
return gatewayFilter;//返回一个自己定义的过滤器
}
//3:定义顺序
@Override
public List<String> shortcutFieldOrder() {//定义变量的顺序
List<String> order = new ArrayList<>();
order.add("name");
order.add("address");
return order;
}
//2:定义config name,address
//http://localhost:10086/api/users/1?token=1&name=jack&address=zs
@Data
public static class Config{
private String name;
private String address;
}
}
更多推荐
所有评论(0)