• 【Gateway】基于ruoyi-cloud-plus项目,gateway局部过滤器和过滤返回以及集成nacos


    1.使用Gateway路由转发

    1.1标题引入依赖

       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-gateway</artifactId>
       </dependency>
    
    • 1
    • 2
    • 3
    • 4

    1.2添加YML配置

    spring:
      cloud:
        gateway:
          # 打印请求日志(自定义)
          requestLog: true
          discovery:
            locator:
              #配置服务名使用小写
              lowerCaseServiceId: true
              #开启服务发现功能,从注册中心获取服务列表,(nacos->服务管理->服务列表)
              #默认服务名称需要为大写,可以通过配置lower-case-service-id: true 改变这一规则
              enabled: true
           #spring cloud gateway提供了XForwardedHeadersFilter,用来决定进行路由转发的时候转发哪些X-Forwarded相关的header,同时提供append选项,用来控制是否是追加还是覆盖到header中。
           #如果spring.cloud.gateway.x-forwarded.for-enabled为true,则会写入X-Forwarded-For
    	   #如果spring.cloud.gateway.x-forwarded.proto-enabled为true,则会写入X-Forwarded-Proto
           #如果spring.cloud.gateway.x-forwarded.port-enabled为true,则会写入X-Forwarded-Port
           #如果spring.cloud.gateway.x-forwarded.host-enabled为true,则会写入X-Forwarded-Host
          x-forwarded:
            for-enabled: false
            host-enabled: false
            port-enabled: false
            proto-enabled: false
          routes:
            - id: Test01
              uri: https://127.0.0.1:8080
              predicates:
                - Path=/test01/**
              filters:
                - Test01=true
            - id: Test02
              uri: https://127.0.0.1:8081
              predicates:
                - Path=/test02/**,/test03/**
              filters:
                - Test02=true
            
      # redis 配置
      data:
        redis:
          # 地址
          host: localhost
          # 端口,默认为6379
          port: 6379
          # 数据库索引
          database: 0
          # 密码
          password: yourPassword
          # 连接超时时间
          timeout: 10s
          lettuce:
            pool:
              # 连接池中的最小空闲连接
              min-idle: 0
              # 连接池中的最大空闲连接
              max-idle: 8
              # 连接池的最大数据库连接数
              max-active: 8
              # #连接池最大阻塞等待时间(使用负值表示没有限制)
              max-wait: -1ms    
    mybatis-plus:
      # 不支持多包, 如有需要可在注解配置 或 提升扫包等级
      # 例如 com.**.**.mapper
      mapperPackage: org.dromara.gateway.mapper
      # 对应的 XML 文件位置
      mapperLocations: classpath*:mapper/**/*Mapper.xml
      # 实体扫描,多个package用逗号或者分号分隔
      typeAliasesPackage: org.dromara.**.domain
      global-config:
        dbConfig:
          # 主键类型
          # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
          # 如需改为自增 需要将数据库表全部设置为自增
          idType: ASSIGN_ID
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    1.3 自定义过滤器

    自定义Test01GatewayFilterFactory 过滤器,过滤上述配置的请求路径携带/test01/** 的请求,并转发到https://127.0.0.1:8080 + 请求路径
    例:请求为 http;//127.0.0.1:8088/test01/ceshi 实际转发到 http;//127.0.0.1:8080/test/ceshi
    请求参数内部可以下述过滤器内调整

    @Component
    @Slf4j(topic = "checkToken")
    public class Test01GatewayFilterFactory extends AbstractGatewayFilterFactory<Test01GatewayFilterFactory.Param> {
    
    
        @Override
        public GatewayFilter apply(Param param) {
            return ((exchange, chain) -> {
                Mono<Void> filter = chain.filter(exchange);
                UserMapper mapper = SpringUtils.getBean( UserMapper.class);
                //这是获取请求头信息
                HttpHeaders headers = exchange.getRequest().getHeaders();
                //这是获取请求参数信息
                //MultiValueMap queryParams = exchange.getRequest().getQueryParams();
                //获取传入的授权信息,用于下面解密获取账号和密码
                String authorization = CustomStringUtil.customTrim(headers.getFirst("Authorization"));
                String id,pwd= null;
                try {
                    String[] idAndPwd = new String(Base64.decodeBase64(authorization.substring(6))).split(":");
                    id = idAndPwd [0];
                    pwd = idAndPwd [1];
                } catch (Exception e) {
                    return filter;
                }
                if (StrUtil.isEmpty(id) || StrUtil.isEmpty(pwd) ) {
                    return filter;
                }
                User user= mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, id.trim()));
                    if(user== null){
                        return filter;
                    }
                String key = user.getKey();
                String secret = user.getSecret();
                if (StrUtil.isEmpty(key ) || StrUtil.isEmpty(secret)) {
                    return filter;
                }
                //生成真实的授权信息
                String authorizationReal = "Basic " + Base64.encodeBase64String((key + ":" + secret).getBytes());
                ServerHttpRequest newRequest = exchange.getRequest().mutate()
                    .header("Authorization", authorizationReal)
                    .build();
                ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
                filter = chain.filter(newExchange);
                return filter;
            });
        }
        public Test01GatewayFilterFactory () {
            super(Test01GatewayFilterFactory.Param.class);
        }
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public static class Param {
            private boolean isCheckToken;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    自定义过滤返回信息

    自定义Test02GatewayFilterFactory 过滤器,过滤上述配置的请求路径携带/test02/** ,/test03/**的请求,并转发到https://127.0.0.1:8081 + 请求路径
    例:请求为 http;//127.0.0.1:8088/test02/ceshi或 http;//127.0.0.1:8088/test03/ceshi实际转发到 http;//127.0.0.1:8081/test/ceshi
    请求参数内部可以下述过滤器内调整

    @Component
    @Slf4j(topic = "checkToken")
    public class Test02GatewayFilterFactory extends AbstractGatewayFilterFactory<Test02GatewayFilterFactory.Param> {
    
    
        @Override
        public GatewayFilter apply(Param param) {
            return ((exchange, chain) -> {
                Mono<Void> filter = chain.filter(exchange);
                UserMapper mapper = SpringUtils.getBean( UserMapper.class);
                //这是获取请求头信息
                HttpHeaders headers = exchange.getRequest().getHeaders();
                //这是获取请求参数信息
                //MultiValueMap queryParams = exchange.getRequest().getQueryParams();
                //获取传入的授权信息,用于下面解密获取账号和密码
                String authorization = CustomStringUtil.customTrim(headers.getFirst("Authorization"));
                String id,pwd= null;
                try {
                    String[] idAndPwd = new String(Base64.decodeBase64(authorization.substring(6))).split(":");
                    id = idAndPwd [0];
                    pwd = idAndPwd [1];
                } catch (Exception e) {
                    return filter;
                }
                if (StrUtil.isEmpty(id) || StrUtil.isEmpty(pwd) ) {
                    return filter;
                }
                User user= mapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getId, id.trim()));
                    if(user== null){
                         ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                    String result = getJsonString(token);
                    DataBuffer buffer = response.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
                    return response.writeWith(Flux.just(buffer));
                    }
                String key = user.getKey();
                String secret = user.getSecret();
                if (StrUtil.isEmpty(key ) || StrUtil.isEmpty(secret)) {
                    return filter;
                }
                //生成真实的授权信息
                String authorizationReal = "Basic " + Base64.encodeBase64String((key + ":" + secret).getBytes());
                ServerHttpRequest newRequest = exchange.getRequest().mutate()
                    .header("Authorization", authorizationReal)
                    .build();
                ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
                filter = chain.filter(newExchange);
                return filter;
            });
        }
        public Test02GatewayFilterFactory () {
            super(Test02GatewayFilterFactory.Param.class);
        }
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public static class Param {
            private boolean isCheckToken;
        }
    
     //封装成功的token
        public String getJsonString(String token){
            HashMap<String, Object> map = new HashMap<>();
            ArrayList<Map> objects = new ArrayList<>();
            HashMap<String, String> resultMap = new HashMap<>();
            resultMap.put("token",token);
            objects.add(resultMap);
            map.put("status","-1");
            map.put("message","认证失败");
            map.put("result",objects);
            String jsonString = JSONObject.toJSONString(map);
            return jsonString;
        }
    
    
    
    
    public class CustomStringUtil {
    
        public static String customTrim(String str){
            return Strings.isNullOrEmpty(str) ? str : str.trim();
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    
    
    • 1
  • 相关阅读:
    怎么使用Consul当配置中心和动态刷新配置
    C 学生管理系统 删除指定学生节点(一般情况)
    书客护眼落地灯销量火爆,售罄、补货、又断货、再补货!又成断货王!
    JVM面试题总结
    Minimum Snap闭式求解相关公式推导
    谷粒商城 renren-fast pom文件报红
    windows11中安装curl
    【Python 实战基础】Pandas如何对Categorical类型字段数据统计
    unity操作_Camera c#
    知识图谱和大语言模型的共存之道
  • 原文地址:https://blog.csdn.net/ai_haibin/article/details/134433394