You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Spring Cloud Gateway无法处理含'=='的POST请求,求解决方案

解决Spring Cloud Gateway处理含'=='的POST请求时的Internal Server Error问题

从你提供的错误日志和响应信息来看,问题的核心是Spring Cloud Gateway在构建目标请求URL时,将包含==的参数(这里是Base64编码的token结尾)识别为QUERY_PARAM类型,而Spring默认的URL组件校验规则认为未编码的=字符在QUERY_PARAM中非法

下面是几种可行的解决办法,按优先级推荐:


1. 确认请求参数的传递方式并修正编码(最直接)

首先排查你的POST请求参数是放在URL的Query中还是请求体里:

  • 如果是Query参数:请求方需要将参数值中的特殊字符(比如==)进行URL编码,把=替换为%3D。例如原token值ua_...Xg==应编码为ua_...Xg%3D%3D,这样网关在解析时就不会触发非法字符校验。
  • 如果是请求体(JSON):正常情况下JSON里的==不需要编码,这时候要检查你的网关路由配置,是否存在错误的过滤器(比如AddRequestParameter)把请求体中的参数错误同步到Query参数里,导致触发校验。

2. 在网关侧添加自定义过滤器自动编码Query参数

如果无法修改请求端的编码逻辑,可以在Spring Cloud Gateway中添加一个自定义过滤器,在RouteToRequestUrlFilter(网关构建目标URL的核心过滤器)之前执行,对所有Query参数进行重新编码:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;

@Component
public class QueryParamEncodingFilter {

    public GatewayFilter encodeQueryParams() {
        return new OrderedGatewayFilter((exchange, chain) -> {
            ServerHttpRequest originalRequest = exchange.getRequest();
            URI originalUri = originalRequest.getURI();

            // 使用UriComponentsBuilder重新构建URL,自动编码所有Query参数
            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUri(originalUri);
            URI encodedUri = uriBuilder.build(true).toUri(); // build(true)强制编码所有组件

            // 构建新的请求对象
            ServerHttpRequest encodedRequest = originalRequest.mutate()
                    .uri(encodedUri)
                    .build();

            return chain.filter(exchange.mutate().request(encodedRequest).build());
        }, RouteToRequestUrlFilter.ORDER - 1); // 确保在RouteToRequestUrlFilter之前执行
    }
}

然后在你的路由配置中引用这个过滤器即可。


3. 升级Spring Cloud Gateway版本

你当前使用的是spring-cloud-gateway-core-2.0.0.RELEASE,这个早期版本存在一些URL校验的严格限制。升级到较新的稳定版本(比如2.2.x或更高),后续版本对Query参数的字符校验规则做了优化,可能直接解决这个问题。

注意升级时要保持Spring Cloud和Spring Boot版本的兼容性,比如Spring Cloud Hoxton对应Spring Boot 2.2.x,Spring Cloud 2021.0.x对应Spring Boot 2.6.x等。


4. 自定义URL校验规则(不推荐,复杂度高)

如果以上方法都不适用,可以通过自定义HierarchicalUriComponents的校验逻辑来放宽对QUERY_PARAM的字符限制,但这种方法需要深入Spring底层代码,维护成本较高,仅作为最后备选。

内容的提问来源于stack exchange,提问作者wen

火山引擎 最新活动