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:成功

相关推荐
Rain的Java大神之路2 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
需要8262 天前
MySQL 索引 B+ 树与“查询为什么变慢了
java·spring boot·spring·spring cloud·tomcat
需要8262 天前
Arthas 一个命令排查线上问题
java·jvm·spring·spring cloud
苏渡苇3 天前
Spring Insight 里如何把 Span 画成瀑布时间线
后端·spring·spring cloud·springboot·监控·apm
叶总没有会3 天前
Nacos—注册中心
spring cloud·微服务
苏渡苇4 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring·spring cloud·系统监控·apm
叶总没有会4 天前
微服务--分布式基础
java·spring·spring cloud·微服务
孙启超5 天前
【AI开发之Rust】第 7 课:错误处理 —— panic、Result 与 `?`
人工智能·分布式·后端·爬虫·spring cloud·架构·rust
行百里er6 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring cloud·监控
砍材农夫7 天前
spring|spring web|拦截器、过滤器、aop
java·spring boot·spring·spring cloud