application/x- www-form-urlencoded是Post請求默認的請求體內容類型,也是form表單默認的類型。Servlet API規範中對該類型的請求內容提供了request.getParameter()方法來獲取請求參數值。但當請求內容不是該類型時,須要調用request.getInputStream()或request.getReader()方法來獲取請求內容值。java
當請求體內容(注意:get請求沒有請求體)類型是application/x- www-form-urlencoded時也能夠直接調用request.getInputStream()或request.getReader()方法獲取到請求內容再解析出具體都參數,但前提是還沒調用request.getParameter()方法(先寫了getParameter()方法,再用getReader()方法不能取到數據)。此時當request.getInputStream()或request.getReader()獲取到請求內容後,沒法再調request.getParameter()獲取請求內容。即對該類型的請求,三個方法互斥,只能調其中一個。今天遇到一個Controller請求通過Spring MVC 的RequestMapping處理後,只能經過request.getParameter()獲取到參數、沒法經過request.getInputStream()和request.getReader()讀取內容極可能就是由於在請求通過Spring MVC時已調用過request.getParameter()方法的緣由。web
注意:在一個請求鏈中,請求對象被前面對象方法中調用request.getInputStream()或request.getReader()獲取過內容後,後面的對象方法裏再調用這兩個方法也沒法獲取到客戶端請求的內容,可是調用request.getParameter()方法獲取過內容後,後面的對象方法裏依然能夠調用它獲取到參數的內容。ajax
當請求體內容是其它類型時,好比 multipart/form-data或application/json時,沒法經過request.getParameter()獲取到請求內容,此時只能經過request.getInputStream()和request.getReader()方法獲取請求內容,此時調用request.getParameter()也不會影響第一次調用request.getInputStream()或request.getReader()獲取到請求內容。spring
request.getInputStream()返回請求內容字節流,多用於文件上傳,request.getReader()是對前者返回內容的封裝,可讓調用者更方便字符內容的處理(不用本身先獲取字節流再作字符流的轉換操做)。chrome
POST 的三種經常使用 Content-Type (get沒有請求體)json
POST 是平常開發中很是經常使用的數據傳輸方法,請求頭中的 Content-Type 指示了在一次 POST 請求中,服務器端應該如何解析客戶端傳遞過來的數據。對於 web 開發來講, 如下三種 Content-Type 是最爲常見的:瀏覽器
1服務器
application/x-www-form-urlencodedmvc
1.做爲 <form /> 元素的默認 Content-Type 設定(enctype 屬性),application/x-www-form-urlencoded 多是被使用得最爲普遍的一種數據編碼方式。一次application/x-www-form-urlencoded 的 POST 請求內容大體以下:app
名圖HTTP請求報文
中間的空行是請求頭和請求體的分隔符,請求體的形式和 GET 請求的參數(Query String) 同樣,一樣是將內容進行百分比編碼。
在 chrome 調試工具中能看到發送出去的信息以下:
2.接收方式
對於 springmvc 來講,主要經過如下兩種方式來接收 Content-Type 爲 application/x-www-form-urlencoded 的數據:
直接根據參數接收
做爲 domain 接收
看成爲 domain 接收時,springmvc 沒法對 domain 中的複雜數據類型進行解析,在這種狀況下,使用 application/json 是更好的選擇。
2
application/json
空行一樣是請求頭和請求體的分隔符, application/json 的不一樣在於,請求體的內容是 JSON 字符串。
chrome 調試工具中顯示的內容以下:
2.接收方式
對於一個 Content-Type 爲 application/json 的請求, springmvc 中可使用 RequestBody 參數註解,請求體中的 JSON 字符串將被嘗試解析爲指定的對象,同時 RequestBody 也接受參數用於指示解析過程當中是否容許對象爲null。
3
application/x-www-form-urlencoded
1.用於文件上傳的 Content-Type, 比較特殊的是,對於這樣的 Content-Type 設定,瀏覽器會生成一個比較複雜且隨機的boundary,並追加在 Content-Type 以後,用於分割請求體中的文件內容。
request.getParameter()-----post表單/ajax傳對象
request.getInputStream();// 後面這2種能夠獲取post全部提交的數據
request.getReader()
// 方法二 public static void ReadAsChars2(HttpServletRequest request) { StringBuilder sb = new StringBuilder("--------"); InputStream is = null; try { is = request.getInputStream(); sb = new StringBuilder(); byte[] b = new byte[4096]; for (int n; (n = is.read(b)) != -1;) { sb.append(new String(b, 0, n)); } } catch (IOException e) { e.printStackTrace(); } finally { if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("#"+sb); } // 字符串讀取 // 方法一 public static String ReadAsChars(HttpServletRequest request) { BufferedReader br = null; StringBuilder sb = new StringBuilder(""); try { br = request.getReader(); String str; while ((str = br.readLine()) != null) { sb.append(str); } br.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); } }