我们在 Rails 服务(我们称之为
mailbox
)前面使用 Spring Cloud Gateway(MVC 版本),并且当查询参数的值包含 +
(加号)字符时,我们会遇到困难。这是一个例子:
[email protected]
+
变成空格。mailbox
之前,它会编码回值,从而产生 email=bob%[email protected]
mailbox
将其解码为email=bob [email protected]
,这会导致失败另一种方法是在客户端中编码
+
,但是我们有:
?email=bob%[email protected]
%2B
变成+
。mailbox
之前,它会编码回值,但由于 +
不被视为特殊字符,因此它保持为 [email protected]
mailbox
将其解码为email=bob [email protected]
,这会导致失败我找不到一种方法来告诉网关不要解码原始请求或强制它在将请求发送到
+
之前对 mailbox
进行编码。有什么办法可以做到这一点吗?还有其他解决办法吗?我想不出什么。就好像采取的所有步骤都没有问题(先解码,然后编码),但最终结果是错误的。我需要 mailbox
才能收到包含 +
的电子邮件,但我不能。
感谢您的帮助!
我们遇到了同样的问题,并且能够通过在现有编码器运行后在转发的请求中手动编码
+
来解决该问题。
这是通过使用自定义的
ClientHttpRequestFactory
来实现的,如下所示:
@Configuration
class WebMvcConfiguration {
@Bean
fun clientHttpRequestFactory(): ClientHttpRequestFactory =
CustomClientHttpRequestFactory()
}
class CustomClientHttpRequestFactory : JdkClientHttpRequestFactory() {
override fun createRequest(uri: URI, httpMethod: HttpMethod): ClientHttpRequest {
val encodedURI = URI(customUriEncode(uri.toString()))
return super.createRequest(encodedURI, httpMethod)
}
private fun customUriEncode(str: String): String =
str.replace(oldValue = "+", newValue = "%2B")
}
我们相信这是安全的,因为原始请求中的
+
和%20
在到达请求工厂之前都被解码为
(空格),因此不会被重新编码回%2B
.