1. 程式人生 > >【原】Http-用getInputStream()或者getParameterMap()獲得Post請求的數據

【原】Http-用getInputStream()或者getParameterMap()獲得Post請求的數據

數據 clas data ons 找到 clu 類的屬性 瀏覽器 比較

【前言】

最近在寫一個接口,寫好以後想測試,自己寫ajax(Post方法)來調用接口倒是可以用action所在類的屬性的get/set方法獲得數據。但是不只是頁面的ajax會調用這個接口,還有外系統會調用,所以我就自己寫普通的Java代碼(不是web項目)來調用,之後我就瞎了,因為收不到傳來的參數啊!!【萬一連不通怎麽辦?各種找原因以及看項目裏其他的代碼,我發現了一些細節。。項目裏其他的代碼有的是使用httpServletRequest的實例用getParameterMap()來獲得信息內容的,但是我用的是getInputStream(),這之中到底有什麽玄機?

【獲得的知識】

其實之前還經過了很多迷糊的時刻,才終於知道應該查什麽知識了,中間的曲折因為沒有學到什麽就不扯淡了。直奔主題。
搜了這兩種方法名,看到了csdn上面一個帖子有人問了這個問題,回答中有一個比較清晰的(我在這直接就抄過來了):

根據Servlet規範,如果同時滿足下列條件,則請求體(Entity)中的表單數據,將被填充到request的parameter集合中(request.getParameter系列方法可以讀取相關數據):
1 這是一個HTTP/HTTPS請求
2 請求方法是POST(querystring無論是否POST都將被設置到parameter中)
3 請求的類型(Content-Type頭)是application/x-www-form-urlencoded
4 Servlet調用了getParameter系列方法

如果上述條件沒有同時滿足,則相關的表單數據不會被設置進request的parameter集合中,相關的數據可以通過request.getInputStream()來訪問。反之,如果上述條件均滿足,相關的表單數據將不能再通過request.getInputStream()來讀取。

Servlet Specifiaction 3.0:
3.1.1 When Parameters Are Available
The following are the conditions that mustbe met before post form data will be
populated to the parameter set:
1. The request is an HTTP or HTTPS request.
2. The HTTP method is POST.
3. The content type is application/x-www-form-urlencoded.
4. The servlet has made an initial call of any of the getParameterfamily of methods on the request object. If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request object’s input stream. If the conditions are met, post form data will no longer be available
for reading directly from the request object’s input stream.

類似的例子,還有response.getOutputStream和getWriter,它們往往也是一對矛盾體 。

從這可以看出是四個條件缺一不可的時候才能使用getParameterMap()方法來獲得內容的,如果有一條不滿足,就不能用這個方法。
然後我查了一下”請求的類型Content-Type“是個什麽東東。於又找到一個帖子 還有很多哈,但是大概了解了一些就是:
form 中Enctype=multipart/form-data 的作用
表單中enctype=”multipart/form-data”的意思,是設置表單的MIME編碼。默認情況,這個編碼格式是application/x-www-form-urlencoded,不能用於文件上傳;
只有使用了multipart/form-data,才能完整的傳遞文件數據,進行下面的操作.
在Form元素的語法中,EncType表明提交數據的格式,用 Enctype 屬性指定將數據回發到服務器時瀏覽器使用的編碼類型。
下邊是說明:
(1) application/x-www-form-urlencoded:窗體數據被編碼為名稱/值對。這是標準的編碼格式,具體的數據例子如下所示。

custname=蘇林&elecontid=elecontid0001&idtype=0&idno=411303198802190512&custage=30&education=20

(2) multipart/form-data:窗體數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分。
(3) text/plain:窗體數據以純文本形式進行編碼,其中不含任何控件或格式字符。

ENCTYPE=”multipart/form-data”用於表單裏有圖片上傳。

<form name="userInfo" method="post" action="first_submit.jsp" ENCTYPE="multipart/form-data">

表單標簽中設置enctype=”multipart/form-data”來確保匿名上載文件的正確編碼。
如下

<tr>
<td height="30" align="right">上傳企業營業執照圖片:</td>
<td><INPUT TYPE="FILE" NAME="uploadfile" SIZE="34"    onChange="checkimage()"></td>
</tr>

就得加ENCTYPE=”multipart/form-data”。

表單中enctype=”multipart/form-data”的意思,是設置表單的MIME編碼。默認情況,
這個編碼格式是application/x-www-form-urlencoded,不能用於文件上傳;
只有使用了multipart/form-data,才能完整的傳遞文件數據,進行下面的操作。
enctype=”multipart/form-data”是上傳二進制數據; form裏面的input的值以2進制的方式傳過去。
form裏面的input的值以2進制的方式傳過去,所以request就得不到值了。

也就是說加了這段代碼,用request就會傳遞不成功,取表單值加入數據庫時,用到下面的:

SmartUpload su = new SmartUpload();//新建一個SmartUpload對象
su.getRequest().getParameterValues();取數組值
su.getRequest().getParameter( );取單個參數單個值

後來又查才發現如果是指上傳數據的內容的話,對於不同的文件,有很多種文件,會對應各種不同的類型。只是request默認的是application/x-www-form-urlencoded,所以用getParameterMap()能獲得,用getInputStream()獲得不了。

【還沒解決的問題】

其實還有一個問題就是用項目裏封裝的httpClient傳過來的數據,是能夠用get流的方式接收到的,但是我沒看懂httpClient的工作原理。。。還得接著學。

【原】Http-用getInputStream()或者getParameterMap()獲得Post請求的數據