pup*_*eno 6 url encoding spring resttemplate
我有一个Spring应用程序接收类似的请求http://localhost/foo?email=foo+bar@example.com.这会触发一个大致如下所示的控制器:
@RestController
@RequestMapping("/foo")
public class FooController extends Controller {
@GetMapping
public void foo(@RequestParam("email") String email) {
System.out.println(email)
}
}
Run Code Online (Sandbox Code Playgroud)
当我可以访问时email,它已被转换为foo bar@example.com而不是原始的foo+bar@example.com.根据何时将空间编码为加号(+)或%20?这应该只发生在内容所在的请求中application/x-www-form-urlencoded.我的请求的内容类型为application/json.请求的完整MIME标头如下所示:
=== 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
Run Code Online (Sandbox Code Playgroud)
为什么Spring会将plus解码为空格?如果这是它应该工作的方式,为什么它不像编写%2B请求时那样编码?
我发现了这个关于它的错误报告:https://jira.spring.io/browse/SPR-6291这可能暗示这是在3.0.5版本上修复的,我使用的是Spring> 5.0.0.我可能会误解错误报告的某些内容.
我还发现了关于这些值的RestTemplate处理的讨论:https://jira.spring.io/browse/SPR-5516(我的客户端正在使用RestTemplate).
所以,我的问题是,为什么Spring这样做?我该如何禁用它?我应该禁用它还是应该在客户端编码加号,即使请求是json?
只是为了澄清,我在这里任何地方都不使用HTML或JavaScript.有一个Spring Rest Controller,客户端是Spring的RestTemplate,UriTemplate或者UriComponentsBuilder都没有像Spring解码它那样编码加号.
原始答案
你正在混合2件事,+请求正文中的a表示标题有空格application/x-www-form-urlencoded.请求的主体或内容将取决于标头,但请求可以只有a url,no headers和no body.
因此,URI的编码不能由任何标头控制
请参阅https://en.wikipedia.org/wiki/Query_string中的URL Encoding部分
某些字符不能是URL的一部分(例如,空格),而其他一些字符在URL中具有特殊含义:例如,字符#可用于进一步指定文档的子部分(或片段).在HTML表单中,character =用于将名称与值分开.URI通用语法使用URL编码来处理此问题,而HTML表单进行一些额外的替换,而不是对所有这些字符应用百分比编码.SPACE编码为"+"或"%20".[10]
HTML 5指定了使用"get"方法向Web服务器提交HTML表单的以下转换.1以下是算法的简要概述:
无法转换为正确字符集的字符将替换为HTML数字字符引用[11] SPACE编码为"+"或"%20"字母(A-Z和a-z),数字(0-9)和字符'*',' - ','.' 并且'_'保持原样所有其他字符编码为%HH十六进制表示,其中任何非ASCII字符首先编码为UTF-8(或其他指定编码)允许对应于波形符("〜")的八位字节在RFC3986的查询字符串中,但需要在HTML表单中将百分比编码为"%7E".
将SPACE编码为"+"并选择"原样"字符将此编码与RFC 3986区分开来.
并且您可以google.com从下面的屏幕截图中看到相同的行为
您也可以在其他框架中看到相同的行为.下面是Python Flask的一个例子
所以你看到的是正确的,你只是将它与一个文档进行比较,该文档引用了请求的正文内容而不是URL
编辑1:5月22日
经过调试后,似乎解码在Spring中都没有发生.我package org.apache.tomcat.util.buf;和UDecode课堂上都有
/**
* 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();
Run Code Online (Sandbox Code Playgroud)
以下是转换实际发生的地方
if( buff[ j ] == '+' && query) {
buff[idx]= (byte)' ' ;
} else if( buff[ j ] != '%' ) {
Run Code Online (Sandbox Code Playgroud)
这意味着它是一个嵌入式tomcat服务器,它执行此转换,而spring甚至不参与此操作.没有配置可以更改此行为,如类代码中所示.所以你必须忍受它
| 归档时间: |
|
| 查看次数: |
4434 次 |
| 最近记录: |