spring-cloud-gateway 动态切换routes下的uri 用于多场景切换请求地址(GET请求)

本文介绍如何在Spring Cloud Gateway中配置自定义过滤器,实现URL重定向和基于请求头参数的动态路由选择,通过具体代码示例,展示了如何根据不同请求头值将请求转发到不同的后端服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.配置文件:

# 服务名称
spring:
  application:
    name: spring-cloud-gateway
  # 开启 Gateway 服务注册中心服务发现
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      default-filters:
        - CustomRewriteRouteFilter=true     ###自定义过滤器必须有
      routes:
        - id: search
          uri: http://11.11.111.1111:1111  ###这个随便写个,不能为空
          order: 0
          predicates:
            - Path=/search/**
# Eureka Server 配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
# 配置Gateway日志等级,输出转发细节信息
logging:
  level:
    org.springframework.cloud.gateway: debug

2.自定义过滤器

package org.lexue.gateway.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.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.InetSocketAddress;
import java.net.URI;

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

/**
 *  @ClassName CustomRewriteRouteFilter
 *  @Author ShuYu Liu
 *  @Description 重置url
 *  @Date 2020/6/20 15:27
 */
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();
            String appid = headers.get("appid").get(0);
            URI uri;
            boolean isTrue = appid.equals("a1");
            log.info(isTrue);
            if (isTrue){
               log.info("201");
                uri = UriComponentsBuilder.fromHttpUrl("http://110.110.200.201:10000"+rawPath).queryParams(queryParams).build().toUri();
            }else if (appid.equals("a2")){
                log.info("211");
                uri = UriComponentsBuilder.fromHttpUrl("http://110.110.200.211:10000"+rawPath).queryParams(queryParams).build().toUri();
            }else {
                throw new NullPointerException("找不到");
            }
            //替换新的url地址
            ServerHttpRequest serverHttpRequest = request.mutate().uri(uri).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.过滤工厂,注入过滤器

package org.lexue.gateway.config;

import org.lexue.gateway.filter.CustomRewriteRouteFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *  @ClassName FilterFactory
 *  @Author ShuYu Liu
 *  @Description 过滤工厂
 *  @Date 2020/6/20 15:52
 */
@Configuration
public class FilterFactory {
    @Bean()
    public CustomRewriteRouteFilter buildCustomRewriteRouteFilter() {
        return new CustomRewriteRouteFilter();
    }
}

 

### Spring Cloud Gateway 中使用 GlobalFilter 添加自定义请求头 在 Spring Cloud Gateway 中,可以通过实现 `GlobalFilter` 接口来创建全局过滤器,并为所有请求添加自定义的请求头。以下是具体的实现方法: #### 实现 GlobalFilter 的代码示例 通过继承 `AbstractGatewayFilterFactory` 或直接实现 `GlobalFilter` 接口,可以轻松地为每个请求动态添加请求头。 ```java import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class CustomRequestHeaderFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest().mutate() .header("X-Custom-Header", "CustomValue") // 自定义请求头名称和值 .build(); return chain.filter(exchange.mutate().request(request).build()); } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; // 设置优先级以确保此过滤器先运行 } } ``` 在此代码中,实现了 `GlobalFilter` 和 `Ordered` 接口。通过重写 `filter` 方法,在其中修改了传入的 `ServerHttpRequest` 对象并为其添加了一个名为 `"X-Custom-Header"` 的新头部字段[^1]。 #### 配置文件中的支持 虽然上述方式是在 Java 代码层面完成的,但如果希望通过 YAML/Properties 文件的方式配置默认过滤器,则可按照如下方式进行设置: ```yaml spring: cloud: gateway: default-filters: - AddRequestHeader=X-Custom-Configured-Header, ConfiguredValue ``` 这种方式适用于简单的场景下统一管理某些固定的请求头信息[^2]。 #### 使用 RequestRateLimiter 进一步增强功能 (可选) 对于更复杂的业务需求,比如基于速率限制条件下的动态调整请求头逻辑,还可以利用官方提供的 `RequestRateLimiter` 工厂类扩展更可能性[^3]: ```java @Bean public RateLimiter<Object> rateLimiter() { return new FixedWindowRateLimiter(); } @Configuration public static class RouteConfiguration { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.path("/limited/**") .filters(f -> f.requestRateLimiter(c -> c.setKeyResolver(new PrincipalNameKeyResolver()))) .uri("http://example.com")) .build(); } } ``` 以上片段展示了如何结合限流机制与特定路径匹配规则共同作用于请求处理流程之中[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值