您好,登錄后才能下訂單哦!
Tomcat是如何處理請求參數的,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
url請求中帶參數的形式(即我們常說的GET請求),是在請求目標后以問號開始,后面是參數名值對,多個名值對間以和號(&)分隔。
通過URL傳遞的參數,在Tomcat中是怎么解析出來的呢?
我們一般在Servlet中要獲取某個參數,一般通過如下的方式
String value = request.getParameter("paramName");
我們在需要的時候通過參數名直接取,這個值又是什么設置的?名值對又是如何對應起來的?
我們順著getParameter方法這個藤,來摸摸實現這個瓜。
我們在使用HttpServletRequest這個對象時,其實一直在使用的是其一個門面對象(RequestFacade),此對象使用了設計模式中的門面模式,封裝了HttpServletRequest中的一些細節,只暴露出一些必要的API。
實際請求處理時,則調用其封裝的request對象。
getParameter方法的代碼是下面這個樣子:
/ * Return the value of the specified request parameter, if any; otherwise,
* return <code>null</code>. If there is more than one value defined,
* return only the first one.
* @param name Name of the desired request parameter
*/
public String getParameter(String name) {
if (!parametersParsed) {
parseParameters();
}
return coyoteRequest.getParameters().getParameter(name);
}
每次請求時,會先判斷參數是否已經解析過,如果已經解析過就直接返回。
protected void parseParameters() {
parametersParsed = true; //注意這里,解析之后就設為true了。
Parameters parameters = coyoteRequest.getParameters();
boolean success = false;
try {
// Set this every time in case limit has been changed via JMX
parameters.setLimit(getConnector().getMaxParameterCount());
}
...
parameters.handleQueryParameters();
}
所以,這個名值對的配置,初始化,是發生在第一次調用getParameter方法時。
再向下,這個handleQueryParameters是具體處理的方法。這里我們假設請求如下url:
http://localhost:8080/test?abc=1&def=2
在handleQueryParameters方法中,我們通過debug界面觀察。
此處parameters包含一個屬性queryMB,其值剛好是我們傳進來的字符串。所以后面的參數處理,是基于這個屬性進行的。
再之后,在Parameter這個類的processParameter方法中,
我們看到,基本是遍歷字符串中的各個char,遇到特定字符=和&之后,再從各個index獲取等號前后的名和值。
中間特別的一個地方是,遇到%和+時,是出現了像漢字一類的,其實是需要轉義的,所以處理也是在此進行的。
解析后,名值對是存放在ArrayList這樣一個數據結構中。看下面的代碼,
public void addParameter( String key, String value ) {
ArrayList<String> values = paramHashValues.get(key);
if (values == null) {
values = new ArrayList<>(1);
paramHashValues.put(key, values);
}
values.add(value);
}
是執行完上面的方法后,代碼向下執行,看到的parameters這個對象,值已經變成了這樣:
abc=1,\n def=2,\n
注意上面代碼標紅加粗的這兩行,
你是否還記得上面提到,如果多個參數,對于重名的只返回第一個符合的項這件事?
具體request的參數請求中,如果不涉及初次處理,那執行的是下面的代碼,很簡單,就是直接從Map里取對應key的ArrayList,有值的話就從中取第一個值。
public String getParameter(String name ) {
handleQueryParameters();
ArrayList<String> values = paramHashValues.get(name);
if (values != null) {
if(values.size() == 0) {
return "";
}
return values.get(0); //注意這里,就是在兌現只返回第一個的承諾!!!
} else {
return null;
}
}看完上述內容,你們掌握Tomcat是如何處理請求參數的的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。