Gateway
Gateway 网关,同以前学的过滤器,拦截器的作用基本一样,拦截,过滤 鉴权,记录日志 等功能
过滤器,拦截器?
过滤器:他是servlet 中的内容,接口,作用可以拦截所有的servlet
拦截器:他是springmvc 中的,作用拦截 DispatchServlet中的内容
使用设计模式:责任链模式
什么是 Spring Cloud Gateway?
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流,路由等。
安全:鉴权
监控/埋点:记录日志
限流:限制流量
路由:路径重写,提供统一的接口规范
功能特征
-
基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
-
动态路由
-
Predicates 和 Filters 作用于特定路由
-
集成 Hystrix 断路器 和 sentinel 类似
-
集成 Spring Cloud DiscoveryClient
-
易于编写的 Predicates 和 Filters
-
限流( Hystrix )
-
路径重写
1.创建一个springcloud-alibaba-gateway工程
<dependencies>
<!--
gate way 依赖 和 spring-boot-starter-web 依赖是 互斥关系,两者不可以共存
网关中 不可以有 spring-boot-starter-web依赖
-->
<!--alibaba.cloud 相关-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
2.创建启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
3.配置文件
spring:
application:
name: springcloud-alibaba-gateway
cloud:
gateway:
routes:
- id: springcloud-alibaba-cursom #设置id
uri: lb://springcloud-alibaba-cursom #设置服务名 注意设置成自己的
predicates:
- Method=GET,POST #设置请求方法
- Path=/api1/* #设置匹配路径的网关
filters:
- StripPrefix=1 #去掉前缀offer
- id: springcloud-alibaba-fegin-consumer
uri: lb://springcloud-alibaba-fegin-consumer
predicates:
- Method=GET,POST
- Path=/api2/*
filters:
- StripPrefix=1
server:
port: 9000
logging:
level:
org.springframework.cloud.gateway: debug
运行,进行访问

负载均衡
spring:
application:
name: springcloud-alibaba-gateway
cloud:
gateway:
routes:
- id: springcloud-alibaba-cursom #设置id
uri: lb://springcloud-alibaba-cursom #设置服务名
predicates:
- Method=GET,POST #设置请求方法
- Path=/api1/* #设置匹配路径的网关
- Weight=g1,2 #设置分组的流量的分配
filters:
- StripPrefix=1 #去掉前缀offer
- id: springcloud-alibaba-fegin-consumer
uri: lb://springcloud-alibaba-fegin-consumer
predicates:
- Method=GET,POST
- Path=/api2/*
- Weight=g1,8
filters:
- StripPrefix=1
server:
port: 9000
logging:
level:
org.springframework.cloud.gateway: debug

基于filter 实现拦截鉴权功能
拦截鉴权的路径,一般都是去检查 token ,路径中必须携带token
http://localhost:9000/api/test1?token=xxxxxx
token:就是令牌,就是通行证,包含了该用户的个人信息,我们可以看到一长串字符串,但是能解析出来 该用户的信息,权限,账户等内容,
在登录的时候生成,返回给前端,前端后续发起的请求都要携带token ,需要验证,所以我门需要创建过滤器
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Component
public class TokenFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取请求路径中的 token ,如果没有传递token 则拦截该请求
// ServerWebExchange exchange 包含了 所有的请求数据
ServerHttpRequest request = exchange.getRequest();
String token = request.getQueryParams().getFirst("token");
if (StringUtils.isEmpty(token)){ // 拦截
// 返回前端 说 没有传递token
//固定写法 返回json
ServerHttpResponse response = exchange.getResponse();
Map<String,Object> responseData = new HashMap<>();
responseData.put("code",401);
responseData.put("message","非法请求,请传递token");
try {
// 将信息转换为 JSON
ObjectMapper objectMapper = new ObjectMapper();
byte[] data = objectMapper.writeValueAsBytes(responseData);
// 输出错误信息到页面
DataBuffer buffer = response.bufferFactory().wrap(data);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
// 放行 不拦截
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
没有传入token参数,被拦截

传入token参数,放行

2658

被折叠的 条评论
为什么被折叠?



