目录
3.路由断言工厂 Route Predicate Factory
小例子:给所有 进入userservice的请求添加一个请求头: Truth = ceshi tianjia qingqiutou
1.网关的技术实现
在SpringCloud中网关实现包括两种:
- zuul(老)
- Gateway(新)
Zuul是基于 Servlet的实现,属于阻塞式编程。而 Spring CloudGateway则是基于 Spring5中提供的 Webflux(响应式)属于响应式编程的实现,具备更好的性能。
2.搭建网关服务
搭建网关的步骤:
1.创建新的 module,引入 Spring Cloud Gateway的依赖和 nacos的服务发现依赖
<!--网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactid>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupid>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactid>
</dependency>2.编写路由配置及nacos地址
server:
port:10010 #网关端口
sping:
application:
name: gateway #服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes: #网关路由配置
- id: User-service #路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8081 # 第一种是把路由直接写死 固定ip
uri: lb://userservice # 路由的目标地址 lb是负载均衡,后面跟着服务名称 loadBalance
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/user/** #按照这个路径匹配,只要是以/user/开头就符合要求业务图

3.路由断言工厂 Route Predicate Factory
网关路由可以配置的内容包括:
- 路由id:路由唯一标示
- uri:路由目的地,支持lb和http两种
- predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地
- filters:路由过滤器,处理请求或响应

4.路由过滤器---GatewayFilter

过滤器工厂 GatewayFilterFactory
spring提供了31种过滤器工厂

小例子:给所有 进入userservice的请求添加一个请求头: Truth = ceshi tianjia qingqiutou
spring:
cloud:
gateway:
routes: #网关路由配置
-id: userservice
uri: lb://userservice
predicates:
- Path=/user/**
filters: #过滤器
- AddRequestHeader=ceshi tianjia qingqiutou # 添加请求头思考 :如果我想要给所有的请求添加请求头?改怎么办
一、每一个都写一份
二、使用默认过滤器——default

5.全局过滤器——GlobalFilter
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与 Gatewayfilterg的作用一样
区别在于 Gatewayfilterie通过配置定义,处理逻辑是固定的。而 Global Filter的逻辑需要自己写代码实现

小例子——判断用户身份
需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件参数中是否有 authorization,
authorization参数值是否为 admin如果同时满足则放行,否则拦截
@Order(-1) //设置拦截器的执行顺序 值越小越优先级越高 值最大为2147483647
@Component
public class AuthorizeFilter implements GlobalFilter{
@Override
public Mono<Void> filter(ServerwebExchange exchange, GatewayFilterchain chain){
//1.获取诗求参数 exchange.getrequeset可以获取到请求的request
ServerHttpRequest request=exchange.getrequest();
MultivalueMap<String String> params = request.getQueryParams();
//2.获取参数中的 authorizati0n参数 参数中是key value形式 通过key:authorization 拿到vlaue
String auth = params.getFirst("authorization");
//3.判断参数值是否等于admin
if("admin".equals(auth)){
//当调用filter的时候相当于在GatewayFilterchain过滤器链 中找下一个过滤器 就等于是放行
return chain.filter(exchange);
}
//5.否,拦截5.1.设状态码HTTPStatus.UNAUTHORIZED(401) jdk封装的状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//5.2拦截请求
return exchange.getResponse().setComplete();
}状态码:


过滤器的执行顺序
请求进入网关会碰到三类过滤器:当前路由的过滤器、 DefaultFilter、 GlobalFilter请求路由后,会将当前路由过滤器和 DefaultFilter、 GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

路由过滤器和DefaultFilter(默认过滤器)底层是一样的都被AddRequestHeaderGatewayFilterFactory(过滤器工厂)生产为GatewayFilter

思考:但是GlobalFilter(全局过滤器)与他们从名称上就不一样(Global) 这又是怎么融合到一起的呢?
有一个叫过滤器适配器的东西 实现了GatewayFilter 内部又接收了一个GlobalFilter 传入适配器中 这样就把GlobalFilter 做了一个适配 变成了GatewayFilter

- 每一个过滤器都必须指定一个int类型的 order值, order值越小,优先级越高,执行顺序越靠前。
- Globalfilter通过实现 Ordered接口,或者添加@ Order注解来指定 order值,由我们自己指定
- 路由过滤器和 default Filter的 order由 Spring指定,默认是按照声明顺序从1递增。
- 当过滤器的 order值一样时,会按照 defaultfilter > 路由过滤器 > Globalfilter的顺序执行。
原因:

6.网关的跨域处理
跨域:域名不一致就是跨域,主要包括:
- 域名不同:www.taobao.com和www.taobao.org和wwjd.com和miaosha.jd.om
- 域名相同,端口不同: localhost.8080和 localhost8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域aax请求,请求被浏览器拦截的问题
解决方案:CORS
