解决GET请求中url ×会被转成×的问题
1. 现象
1.1 前端请求地址
https://blog.collmall.com/form/detail?docId=Ch0A8WQ×tamp=1700991665024
1.2 异常信息
org.springframework.web.bind.MissingServletRequestParameterException: Required Long parameter 'timestamp' is not present
java.lang.IllegalStateException: Optional long parameter 'timestamp' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
1.3 分析
后端请求会先通过 SpringCloud-Gateway 路由到对应的服务上,现通过前端请求可以看到对应的
timestamp是带着呢,而通过网关抓取到的log 可以看到
https://blog.collmall.com/form/detail?docId=ex2EGowBhvZGVWh7RMY8%C3%97tamp%3D1701251925038
请求地址,因为Url会对请求地址进行编码,现在对请求地址进行解码查看如下:
https://blog.collmall.com/form/detail?docId=ex2EGowBhvZGVWh7RMY8×tamp=1701251925038
此时发现 ×tamp 变成了×tamp
2.解决方法
2.1 既然是因为× 特殊符号导致的 ,那就不让它形成这种形式
可以把timestamp 参数提到最前变,即?timestamp 这种形式进行传参;
又因为& 是Url的转义特殊符号,此时可以 转义用这样的方式进行传参
×tamp=1701251925038
2.2 既然GET请求转义 ,可以变成POST form 请求
2.3 既然走的网关 ,可以通过设置网关进行调整 (没有验证)
在Spring Cloud Gateway中,URL中的特殊字符,如×
,可能会被错误地解析和转义。这可能是由于网关的某些配置或中间件导致的。要解决这个问题,您可以尝试以下几种方法:
- 配置URL编码:确保您的Spring Cloud Gateway配置中启用了正确的URL编码。您可以在网关的配置文件中添加以下属性:
spring.cloud.gateway.httpclient.request.url-encoder=relaxed
这将使用relaxed
编码策略,它对URL的转义字符进行较为宽松的解析。
- 自定义过滤器:您可以编写自定义过滤器来处理URL中的特殊字符。在过滤器中,您可以获取传入的请求并对其进行必要的修改,以确保URL中的特殊字符不被错误地转义。以下是一个简单的示例:
@Component
public class CustomUrlFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
URI uri = request.getURI();
String queryString = uri.getQuery();
if (queryString != null) {
String decodedQueryString = UriUtils.decodeQueryString(queryString);
if (!decodedQueryString.equals(queryString)) {
// 修改请求的URI并重新设置到请求中
URI newUri = uri.newBuilder()
.query(decodedQueryString)
.build();
exchange.getRequest().setURI(newUri);
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
}
这个过滤器会获取传入的请求并解码URL中的查询字符串,如果解码后的字符串与原始字符串不同,将修改请求的URI并重新设置到请求中。