解决 HTTP 请求参数中的加号被替换为空格问题
HTTP Java Tomcat About 2,267 words现象
使用GET请求添加query string(?后的参数)或使用Content-Type为application/x-www-form-urlencoded的POST请求携带参数时,加号(+号)被替换为了空格。
原因
如果URLs中出现了空格,需要用+替换,所以这里解码的时候把+转化回了空格。先有了编码的操作,所以才会有解码的操作。
Control names and values are escaped. Space characters are replaced by '+'
HTML 4.01 第 17.13.4 节,明确指出:当 Content-Type 为 application/x-www-form-urlencoded 时,对 names 和 vaules 进行转义,空格用 + 代替。
原文地址:https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
所以因为规范的原因,上传的+号都在解码阶段转义成了空格。
源码
org.apache.tomcat.util.http.Parameters#processParameters(byte[], int, int, java.nio.charset.Charset)
判断有+号则需要解码。
private void processParameters(byte bytes[], int start, int len, Charset charset) {
...
do {
switch(bytes[pos]) {
...
case '+':
// Decoding required
if (parsingName) {
decodeName = true;
} else {
decodeValue = true;
}
pos ++;
break;
...
}
...
} while (!parameterComplete && pos < end);
...
}
java.net.URLDecoder#decode(java.lang.String, java.lang.String)
可以看到URLDecoder解码时在匹配字符串+号时转换为了空格。
public static String decode(String s, String enc) {
...
while (i < numChars) {
c = s.charAt(i);
switch (c) {
case '+':
sb.append(' ');
i++;
needToChange = true;
break;
...
}
...
}
解决
方式一
前端上传时对+号进行URLEncode处理,或者将+号统一换成%2B。
HTML规范对于GET请求参数和Content-Type为application/x-www-form-urlencoded的POST的请求参数都要进行URLEncode处理。
方式二
使用request.getQueryString()方法代替@RequestParam和request.getParameter()方法。
代码:
@GetMapping("/test")
public String test(@RequestParam("name") String name, HttpServletRequest request) {
System.out.println("request param#" + name);
String name1 = request.getParameter("name");
System.out.println("get parameter#" + name1);
String queryString = request.getQueryString();
System.out.println("request query string#" + queryString);
return name;
}
请求:
http://localhost:8080/test?name=Java+Go&age=13
输出:
request param#Java Go
get parameter#Java Go
request query string#name=Java+Go&age=13
参考
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓