Spring Cloud Gateway 之动态uri 自定义过滤器

背景:第三方公司 请求本公司入参和出参一样的同一个接口,根据业务类型不一样需要不同业务微服务处理 ,和第三方公司协商在请求头中加入业务类型方便我公司在网关成分发请求。

1:在spring cloud gateway yml 中加入路由 重点是 - id: hello_route

复制代码
server:
  port: 7101
  servlet:
    context-path: /
spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true   #开启Eureka服务发现
          lower-case-service-id: true
      routes:
        - id: baidu_route
          uri: http://www.baidu.com
          predicates:
            - Path=/baidu/**
          filters:
            - StripPrefix=1
        - id: hello_route
          uri: http://localhost:7002
          predicates:
            - Path=/hello
          filters:
            - CustomRewriteRouteFilter=true     # ##自定义过滤器必须有

eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
  instance:
    prefer-ip-address: true

logging:
  level:
    org.springframework.cloud.gateway: debug

2:过滤器实现

复制代码
package tigee.filter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.List;

import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;

@Component
public class CustomRewriteRouteFilter extends AbstractGatewayFilterFactory {
    private static final Log log = LogFactory.getLog(CustomRewriteRouteFilter.class);

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            //获取url地址
            ServerHttpRequest request = exchange.getRequest();
            String rawPath = request.getURI().getRawPath();
            //请求头
            HttpHeaders headers = request.getHeaders();
            //请求方法
            HttpMethod method = request.getMethod();
            //请求参数
            MultiValueMap < String, String > queryParams = request.getQueryParams();

            List<String> serveqp = queryParams.get("serve");
            log.info("serveqp--->:"+serveqp);
            List<String> servehd = headers.get("serve");
            String serve = "";
            if(!CollectionUtils.isEmpty(serveqp)){
                serve =serveqp.get(0);
            }else if(!CollectionUtils.isEmpty(servehd)){
                serve =servehd.get(0);
            }
            log.info("serve--->:"+serve);
            URI uri = UriComponentsBuilder.fromUriString("lb://"+serve).queryParams(queryParams).build().toUri();
            //替换新的url地址
            ServerHttpRequest serverHttpRequest = request.mutate().uri(uri).path(request.getPath().value()).method(method).headers(
                    httpHeaders -> httpHeaders=headers).build();
            Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
            //从新设置Route地址
            Route newRoute =
                    Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId())
                            .order(route.getOrder()).uri(uri).build();
            exchange.getAttributes().put(GATEWAY_ROUTE_ATTR,newRoute);
            return chain.filter(exchange.mutate().request(serverHttpRequest).build());
        };
    }
}

3:user-service 和 order-service 创建hellocontroller

复制代码
@RestController
public class HelloController{

    @Value("${server.port}")
    private int port;
    @Value("${spring.application.name}")
    private String serve;

    @RequestMapping("hello")
    public String hello(String name){
        return "你好:"+serve+":"+port+":"+name;
    }
}

4:启动服务

5:验证

postman 请求 http://localhost:7101/hello?name=name2

header中加入 serve = user-service 或者 order-service

6:成功

相关推荐
椰椰椰耶20 小时前
[SpringCloud][12]Nacos配置中心详解,快速上手,Nacos和Eureka的区别
spring·spring cloud·eureka
半旧夜夏1 天前
【保姆级】微服务组件环境搭建(Docker Compose版)
java·linux·spring cloud·微服务·云原生·容器
Devin~Y2 天前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
西凉的悲伤2 天前
Spring Boot 、Spring Cloud 微服务架构认证授权方案
spring boot·spring cloud·微服务·架构·认证授权
西凉的悲伤3 天前
Spring Cloud Gateway介绍
java·spring cloud·gateway
JAVA社区3 天前
Java高级全套教程(十)—— SpringCloudAlibaba超详细实战详解
java·开发语言·spring cloud·面试·职场和发展
JAVA社区4 天前
Java高级全套教程(九)—— SpringCloud超详细实战详解
java·开发语言·后端·spring cloud·面试·职场和发展
Devin~Y4 天前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 可观测性 + RAG/Agent(小Y翻车版)
java·spring boot·redis·spring cloud·kafka·kubernetes·mybatis
菜萝卜子4 天前
【Docker】Harbor 代理缓存(Pull-Through Cache)配置与使用指南
spring cloud·云原生·eureka