SpringCloud学习5

目录

Spring Cloud Gateway网关

1. 简介

2. Gateway加入后的架构

3. 核心概念

4.  快速入门

5. 面向服务的路由

6. 路由前缀

7. 过滤器

8. 自定义过滤器

 8.1 自定义局部过滤器

8.2 自定义全局过滤器

9. Gateway跨域配置


Spring Cloud Gateway网关

1. 简介

网关的核心功能是:过滤和路由。

2. Gateway加入后的架构

3. 核心概念

4.  快速入门

 修改heima-gateway\src\main\resources\application.yml文件为:

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由id,可以任意
        - id: user-service-route
          # 代理的服务地址
          #uri: http://127.0.0.1:9091
          # 路由断言: 可以匹配映射路径
          predicates:
            - Path=/user/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

将符合Path 规则的一切请求,都代理到 uri参数指定的地址

本例中,我们将路径中包含有 /user/**开头的请求,代理到http://127.0.0.1:9091

访问的路径中需要加上配置规则的映射路径,我们访问:http://localhost:10010/user/8

5. 面向服务的路由

在刚才的路由规则中,把路径对应的服务地址写死了!如果同一服务有多个实例的话,这样做显然不合理。 应该根据服务的名称,去Eureka注册中心查找 服务对应的所有实例列表,然后进行动态路由!

修改heima-gateway\src\main\resources\application.yml文件如下:

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由id,可以任意
        - id: user-service-route
          # 代理的服务地址;lb表示从eureka中获取具体服务
          uri: lb://user-service
          # 路由断言: 可以匹配映射路径
          predicates:
            - Path=/user/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

路由配置中uri所用的协议为lb时(以uri: lb://user-service为例),gateway将使用 LoadBalancerClient把 user-service通过eureka解析为实际的主机和端口,并进行ribbon负载均衡。

6. 路由前缀

在gateway中可以通过配置路由的过滤器PrefixPath,实现映射路径中地址的添加;

在gateway中可以通过配置路由的过滤器StripPrefix,实现映射路径中地址的去除;

 

7. 过滤器

Gateway作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作往往是通过网关提供的过滤器来实现的。 前面的 路由前缀 章节中的功能也是使用过滤器实现的。

 ​​

 

配置全局默认过滤器

server: 
    port: 10010

spring: 
    application: 
        name: api-gateway
    cloud: 
        gateway: 
        # 默认过滤器,对所有路由都生效
          default-filters:
          # 响应头过滤器,对输出的响应设置其头部属性名称为X-Response-Default-MyName,值为itcast;如果有多个参数多则重写一行设置不同的参数
            - AddResponseHeader=X-Response-Default-MyName, itcast

        routes:
        # 路由id,可以任意
        - id: user-service-route
          # 代理的服务地址;lb表示从eureka中获取具体服务
          uri: lb://user-service
          # 路由断言: 可以匹配映射路径
          predicates:
            - Path=/user/**
          filters: 
          # 表示过滤1个路径,2表示两个路径,以此类推 
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

执行生命周期

Spring Cloud Gateway 的 Filter 的生命周期也类似Spring MVC的拦截器有两个:“pre” 和 “post”。“pre”和 “post” 分别会在请求被执行前调用和被执行后调用

这里的 pre 和 post 可以通过过滤器的GatewayFilterChain执行filter方法前后来实现。

 

8. 自定义过滤器

 8.1 自定义局部过滤器

需求:在application.yml中对某个路由配置过滤器,该过滤器可以在控制台输出配置文件中指定名称的请求参数的 值。

在heima-gateway工程编写过滤器工厂类MyParamGatewayFilterFactory

package com.itheima.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Component
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {

    static final String PARAM_NAME = "param";

    public MyParamGatewayFilterFactory() {
        super(Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARAM_NAME);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // http://localhost:10010/api/user/8?name=itcast   config.param ==> name
            //获取请求参数中param对应的参数名 的参数值
            ServerHttpRequest request = exchange.getRequest();
            if(request.getQueryParams().containsKey(config.param)){
                request.getQueryParams().get(config.param).
                        forEach(value -> System.out.printf("------------局部过滤器--------%s = %s------", config.param, value));
            }
            return chain.filter(exchange);
        };
    }


    public static class Config{
        //对应在配置过滤器的时候指定的参数名
        private String param;

        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }
    }
}

在heima-gateway工程修改heima-gateway\src\main\resources\application.yml配置文件

server:
  port: 10010
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由id,可以任意
        - id: user-service-route
          # 代理的服务地址
          #uri: http://127.0.0.1:9091
          # lb表示从eureka中获取具体服务
          uri: lb://user-service
          # 路由断言: 可以匹配映射路径
          predicates:
            #- Path=/user/**
            #- Path=/**
            - Path=/api/user/**
          filters:
            # 添加请求路径的前缀
            #- PrefixPath=/user
            #1表示过滤1个路径,2表示两个路径,以此类推
            - StripPrefix=1
            - MyParam=name
      # 默认过滤器,对所有路由都生效
      default-filters:
        - AddResponseHeader=abc-myname,test
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true

 过滤器工厂类MyParamGatewayFilterFactory

8.2 自定义全局过滤器

需求:模拟一个登录的校验。基本逻辑:如果请求中有token参数,则认为请求有效,放行。

在heima-gateway工程编写全局过滤器类MyGlobalFilter

package com.itheima.gateway.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("--------------全局过滤器MyGlobalFilter------------------");
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(StringUtils.isBlank(token)){
            //设置响应状态码为未授权
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //值越小越先执行
        return 1;
    }
}

9. Gateway跨域配置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值