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

news/2024/7/24 2:21:07 标签: gateway, java

1.使用Gateway路由转发

1.1标题引入依赖

java">   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-gateway</artifactId>
   </dependency>

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.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
请求参数内部可以下述过滤器内调整

java">@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<String, String> 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;
    }

自定义过滤返回信息

自定义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
请求参数内部可以下述过滤器内调整

java">@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<String, String> 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();
    }
}




http://www.niftyadmin.cn/n/5185037.html

相关文章

杭电oj 2037 今年暑假不AC C语言

贪心算法是一种解决优化问题的算法。其基本思想是将整个问题分解成一系列子问题&#xff0c;并为每个子问题找到最优解决方案&#xff0c;最终通过组合子问题的解来得到整个问题的解。 本题&#xff1a;1.先对结束时间进行排序并将之对应开始时间的储存位置进行对应变更&#…

家用小型洗衣机哪款性价比高?婴儿专用洗衣机推荐

内衣洗衣机是一种专用于内裤清洗的小型洗衣机。对很多人而言&#xff0c;内衣裤是不可或缺的日常衣物的一部分&#xff0c;所以它的洁净与卫生显得尤为重要。而且&#xff0c;要想更好地清洁我们的内衣裤&#xff0c;提高内衣裤的卫生度&#xff0c;那么就得需要用到内衣洗衣机…

PHP写一个 电商Api接口需要注意哪些?考虑哪些?

随着互联网的飞速发展&#xff0c;前后端分离的开发模式越来越流行。编写一个稳定、可靠和易于使用的 API 接口是现代互联网应用程序的关键。本文将介绍在使用 thinkphp6 框架开发 电商API 接口时需要注意的要点和考虑的问题&#xff0c;并提供详细的逻辑步骤和代码案例。 1. …

Python开源项目GPEN——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践

无论是自己、家人或是朋友、客户的照片&#xff0c;免不了有些是黑白的、被污损的、模糊的&#xff0c;总想着修复一下。作为一个程序员 或者 程序员的家属&#xff0c;当然都有责任满足他们的需求、实现他们的想法。除了这个&#xff0c;学习了本文的成果&#xff0c;或许你还…

[Vue 配置] Vite + Vue3 项目配置 Tailwind CSS

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/yqzi9olphko9ity1 Tailwind CSS 官网&#xff1a;https://www.tailwindcss.cn/docs/installation/using-postcss 安装 pnpm i -D tailwindcss postcss autoprefixer生成配置文件 npx tailwindcss init -p配…

还有医学生不知道这个免费好用的在线样本量计算器吗?

相信很多小伙伴都有过这样的经历&#xff1a;做科研设计、撰写论文&#xff0c;设计好主题后摆在眼前的是你最头痛的问题——样本量计算。事实上&#xff0c;样本量计算往往是临床医生做临床研究设计的一大障碍&#xff0c;是临床研究设计、临床知识经验以及统计学知识的结合。…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之进程管理2》(4)

《Linux操作系统原理分析之进程管理2》》&#xff08;4&#xff09; 3 进程管理3.5 P、V操作3.5.1 信号量3.5.2 信号量的应用3.5.3 进程同步机制 3.6 进程通信3.6.1 消息通信3.6.2 信箱通信 3.7 死锁3.7.1 死锁的定义3.7.2 死锁产生的必要条件3.7.3 死锁的预防3.7.4 死锁的避免…

高性能面试八股文之编译流程程序调度

1. C的编译流程 C语言程序的编译过程通常包括预处理&#xff08;Preprocessing&#xff09;、编译&#xff08;Compilation&#xff09;、汇编&#xff08;Assembly&#xff09;、链接&#xff08;Linking&#xff09;四个主要阶段。下面是这些阶段的详细说明&#xff1a; 1.…