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

1.使用Gateway路由转发

1.1标题引入依赖

java 复制代码
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-gateway</artifactId>
   </dependency>

1.2添加YML配置

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();
    }
}
复制代码
相关推荐
陌上 烟雨齐2 小时前
Kafka数据生产和发送
java·分布式·kafka
Jinkxs2 小时前
高级15-Java构建工具:Maven vs Gradle深度对比
java·开发语言·maven
有梦想的攻城狮2 小时前
spring中的ApplicationRunner接口详解
java·后端·spring·runner·application
程序视点2 小时前
设计模式之原型模式!附Java代码示例!
java·后端·设计模式
振鹏Dong4 小时前
微服务架构及常见微服务技术栈
java·后端
丶小鱼丶4 小时前
二叉树算法之【中序遍历】
java·算法
摇滚侠5 小时前
Oracle 关闭 impdp任务
java
编程爱好者熊浪6 小时前
RedisBloom使用
java
苇柠6 小时前
Spring框架基础(1)
java·后端·spring
yics.6 小时前
数据结构——栈和队列
java·数据结构