我正在寫一個HTTP代理,它是測試/驗證 系統的一部分。代理過濾來自客戶端設備 的所有請求,並將它們引導至各種被測系統。servlet中的問題讀取請求體
該代理被實現爲一個servlet,其中每個請求被轉發 到目標系統,它同時處理GET和POST。有時,目標系統的響應被改變以適應各種測試條件,但這不是問題的一部分。
轉發請求時,除了作爲實際HTTP傳輸的一部分的那些 (例如Content-Length和 連接標頭)之外,將複製所有標頭。
如果請求是一個HTTP POST,那麼請求的實體主體也會被轉發到 ,這裏有時它不起作用。
的代碼從servlet請求讀取實體正文如下:
URL url = new URL(targetURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
String method = request.getMethod();
java.util.Enumeration headers = request.getHeaderNames();
while(headers.hasMoreElements()) {
String headerName = (String)headers.nextElement();
String headerValue = request.getHeader(headerName);
if (...) { // do various adaptive stuff based on header
}
conn.setRequestProperty(headerName, headerValue);
}
//這裏失敗
char postBody[] = new char[1024];
int len;
if(method.equals("POST")) {
logger.debug("guiProxy, handle post, read request body");
conn.setDoOutput(true);
BufferedReader br = request.getReader();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
do {
logger.debug("Read request into buffer of size: " + postBody.length);
len = br.read(postBody, 0, postBody.length);
logger.debug("guiProxy, send request body, got " + len + " bytes from request");
if(len != -1) {
bw.write(postBody, 0, len);
}
} while(len != -1);
bw.close();
}
的一部分,所以什麼happends是第一次POST -1 字符是從請求閱讀器讀取的,wireshark trace顯示 包含URL編碼後參數的實體正文 並且它位於一個TCP段中,因此存在n個o網絡相關 的差異。
第二次,br.read成功返回 POST請求實體主體中的232個字節,並且每個即將發出的請求也都能正常工作。
第一個和即將發佈的POST請求之間的唯一區別是 ,第一個不存在cookie,但在第二個 中存在映射到JSESSION的cookie。
它可能是實體主體不可用的副作用,因爲在servlet容器中的 請求處理已經讀取POST 參數,但它爲什麼會對即將發生的請求起作用。
相信溶液當然是忽略在含有URL編碼數據 POST請求實體主體和代替使用的getParameter從servlet請求獲取所有參數 和重新插入 詮釋傳出請求。
雖然這是棘手的,因爲POST請求可能包含GET 參數,而不是現在我們的應用程序中,但正確執行它 是一些工作。
所以我的問題基本上是:爲什麼一些讀者對 request.getReader()返回-1閱讀時和實體主體是 出現在請求時,如果實體身體不適用於 閱讀,然後getReader應該拋出非法狀態異常。 I 也嘗試使用getInputStream()與InputStream結果相同的 。
所有這些都在apache-tomcat-6.0.18上測試過。
似乎cookie的存在阻止了servlet容器讀取POST主體。這解釋了爲什麼後面的帖子請求能夠工作,因爲當cookie被設置時它就起作用了。 現在,我的解決方案,雖然有點尷尬,但是手動將所有POST參數傳遞給代理請求實體主體,但它現在可行。我相信構建代理的正確方法是使用servlet過濾器,然後可以控制整個請求。 – Ernelli 2010-08-09 14:01:51