解析方法在org.apache.tomcat.util.http.Parameters#processParameters(byte[], int, int, java.nio.charset.Charset)
搜索思路是
org.apache.catalina.connector.RequestFacade#getParameter——>
org.apache.catalina.connector.Request#getParameter——>
org.apache.tomcat.util.http.Parameters#getParameter
找到底层封装url参数的容器private final Map<String,ArrayList<String>> paramHashValues = new LinkedHashMap<>();
再找到调用它put方法的方法
org.apache.tomcat.util.http.Parameters#addParameter
再从这个方发找调用它的方法org.apache.tomcat.util.http.Parameters#processParameters(byte[], int, int, java.nio.charset.Charset)
当解析到+或%是会进行url解码,源码片段
do {
switch(bytes[pos]) {
case '=':
if (parsingName) {
// Name finished. Value starts from next character
nameEnd = pos;
parsingName = false;
valueStart = ++pos;
} else {
// Equals character in value
pos++;
}
break;
case '&':
if (parsingName) {
// Name finished. No value.
nameEnd = pos;
} else {
// Value finished
valueEnd = pos;
}
parameterComplete = true;
pos++;
break;
case '%':
case '+':
// Decoding required
if (parsingName) {
decodeName = true;
} else {
decodeValue = true;
}
pos ++;
break;
default:
pos ++;
break;
}
} while (!parameterComplete && pos < end);
解码后将添加到key-value值添加到该类这个map中
String name;
String value;
if (decodeName) {
urlDecode(tmpName);
}
tmpName.setCharset(charset);
name = tmpName.toString();
if (valueStart >= 0) {
if (decodeValue) {
urlDecode(tmpValue);
}
tmpValue.setCharset(charset);
value = tmpValue.toString();
} else {
value = "";
}
try {
addParameter(name, value);
} catch (IllegalStateException ise) {
// Hitting limit stops processing further params but does
// not cause request to fail.
UserDataHelper.Mode logMode = maxParamCountLog.getNextMode();
if (logMode != null) {
String message = ise.getMessage();
switch (logMode) {
case INFO_THEN_DEBUG:
message += sm.getString(
"parameters.maxCountFail.fallToDebug");
//$FALL-THROUGH$
case INFO:
log.info(message);
break;
case DEBUG:
log.debug(message);
}
}
break;
}
前端一般需要url编码。
如postman不会在地址中进行对'+'号进行url编码,但会对中文进行url编码,
但会在x-www-form-urlencoded消息体中都进行url编码。
以下从postman发出请求,这里key为 password,value为 +
x-www-form-urlencoded:
在url地址中
不过在JSON消息体中的+号框架一般不加密解码。推测前后端框架一般只默认加密解码key=value形式的,不管在url中还是消息体中 。