- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Spring 应用程序,它接收类似 http://localhost/foo?email=foo+bar@example.com
的请求。这会触发一个 Controller ,大致如下所示:
@RestController
@RequestMapping("/foo")
public class FooController extends Controller {
@GetMapping
public void foo(@RequestParam("email") String email) {
System.out.println(email)
}
}
当我可以访问电子邮件
时,它已转换为foo bar@example.com
,而不是原来的foo+bar@example.com
。根据When to encode space to plus (+) or %20?这应该只发生在内容为 application/x-www-form-urlencoded
的请求中。我的请求的内容类型为 application/json
。请求的完整 MIME header 如下所示:
=== MimeHeaders ===
accept = application/json
content-type = application/json
user-agent = Dashman Configurator/0.0.0-dev
content-length = 0
host = localhost:8080
connection = keep-alive
为什么 Spring 将加号解码为空格?如果这是它应该工作的方式,why isn't it encoding pluses as %2B
when making requests ?
我发现了这个错误报告:https://jira.spring.io/browse/SPR-6291这可能意味着这在版本 3.0.5 上已修复,并且我正在使用 Spring > 5.0.0。我可能会误解有关错误报告的某些内容。
我还发现了有关 RestTemplate 对这些值的处理的讨论:https://jira.spring.io/browse/SPR-5516 (我的客户正在使用 RestTemplate)。
所以,我的问题是,Spring 为什么要这样做?我怎样才能禁用它?我应该禁用它还是应该在客户端上对 pluses 进行编码,即使请求是 json?
澄清一下,我在这里没有使用 HTML 或 JavaScript。有一个 Spring Rest Controller,客户端是 Spring 的 RestTemplate
和 UriTemplate
或 UriComponentsBuilder
,它们都不会按照 Spring 解码的方式对加号进行编码。
最佳答案
原始答案
您正在混合两件事,请求正文中的 +
意味着当 header 具有 application/x-www-form-urlencoded
时有一个空格。请求的正文或内容取决于 header ,但请求可以只有 url
,没有 headers
,也没有 body
。
因此 URI 的编码不能由任何 header 控制
请参阅 https://en.wikipedia.org/wiki/Query_string 中的 URL 编码
部分。
Some characters cannot be part of a URL (for example, the space) and some other characters have a special meaning in a URL: for example, the character # can be used to further specify a subsection (or fragment) of a document. In HTML forms, the character = is used to separate a name from a value. The URI generic syntax uses URL encoding to deal with this problem, while HTML forms make some additional substitutions rather than applying percent encoding for all such characters. SPACE is encoded as '+' or "%20".[10]
HTML 5 specifies the following transformation for submitting HTML forms with the "get" method to a web server.1 The following is a brief summary of the algorithm:
Characters that cannot be converted to the correct charset are replaced with HTML numeric character references[11]SPACE is encoded as '+' or '%20'Letters (A–Z and a–z), numbers (0–9) and the characters '*','-','.' and '_' are left as-isAll other characters are encoded as %HH hex representation with any non-ASCII characters first encoded as UTF-8 (or other specified encoding)The octet corresponding to the tilde ("~") is permitted in query strings by RFC3986 but required to be percent-encoded in HTML forms to "%7E".
The encoding of SPACE as '+' and the selection of "as-is" characters distinguishes this encoding from RFC 3986.
您也可以从下面的屏幕截图中看到 google.com
上的相同行为
您也可以在其他框架中看到相同的行为。下面是Python Flask的示例
所以您所看到的是正确的,您只是将其与引用请求正文内容而不是 URL 的文档进行比较
编辑 1:5 月 22 日
调试后似乎在 Spring 中甚至没有发生解码。我发生在 package org.apache.tomcat.util.buf;
和 UDecoder
类
/**
* URLDecode, will modify the source.
* @param mb The URL encoded bytes
* @param query <code>true</code> if this is a query string
* @throws IOException Invalid %xx URL encoding
*/
public void convert( ByteChunk mb, boolean query )
throws IOException
{
int start=mb.getOffset();
下面是转换实际发生的地方
if( buff[ j ] == '+' && query) {
buff[idx]= (byte)' ' ;
} else if( buff[ j ] != '%' ) {
这意味着它是一个嵌入式 tomcat 服务器来执行此转换,而 spring 甚至不参与此操作。如类代码中所示,没有配置可以更改此行为。所以你必须忍受它
关于spring - 为什么Spring在application/json get请求上解码+(加号字符)?我该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50270372/
我是一名优秀的程序员,十分优秀!