tomcat底层会默认对url地址参数或x-www-form-urlencoded格式的key-value进行url解码

解析方法在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中还是消息体中 。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值