javaweb和app的前後臺互動與Content-Type理解得出的解決方案
最近在做一個微信小程式,發現後臺獲取前臺傳送的資料,不能通過傳統的springmvc 直接對映獲取,通過參考案列小程式,發現獲取小程式引數是這樣的,程式碼如下。
沒想到獲取前臺請求的還有這種騷操作,帶著困惑,我通過檢視小程式和網頁傳送的請求頭資訊,找到了區別所在,StringBuilder sb = new StringBuilder(); try (BufferedReader reader = request.getReader();) { char[] buff = new char[1024]; int len; while ((len = reader.read(buff)) != -1) { sb.append(buff, 0, len); } result = JSONObject.parseObject(sb.toString()); } catch (IOException e) { e.printStackTrace(); } return result;
小程式請求頭資訊如下
web請求的頭資訊如下由此我發現了區別小程式請求的頭資訊中content-type是 application/json 而web中請求的頭資訊是application/x-www-form-urlencoded;charset-utf-8,我在想問題出在這兒了,在這裡我們用的都是post請求,帶著好奇我測試了下get請求,發現無論在小程式還是在web端都能通過對映獲取引數,於是我也帶著好奇檢視get請求的頭資訊
通過檢視我發現在web端還是在小程式端,都沒有content-type這個頭資訊。由此我分析當頭資訊 content-type:application/json時是無法通過我們傳統的springmvc對映獲取請求的引數。而其它的形式是可以的,還有沒有提到的檔案上傳時,content-type的請求引數是mutilpart/form-data,也是可以通過對映獲取的。
至於原理小左技術不夠,需要深入理解springmvc引數對映的原理也許能解答這個問題,知道的方便給小左一個答案在評論裡,謝謝。
不過我在檢視文件時,發現了這麼一段內容,貼在下面,可以多學點。
request.getParameter() 要根據<form>表單提交資料的編碼方式選擇不同的方法。 request.getParameter()、 request.getInputStream()、request.getReader()這三種方法是有衝突的,因為流只能被讀一次 比如: 當form表單內容採用 enctype=application/x-www-form-urlencoded編碼時,先通過呼叫request.getParameter() 方法得到引數後,再呼叫request.getInputStream()或request.getReader()已經得不到流中的內容,因為在呼叫 request.getParameter()時系統可能對錶單中提交的資料以流的形式讀了一次,反之亦然。 當form表單內容採用enctype=multipart/form-data編碼時,即使先呼叫request.getParameter()也得不到資料,所以這時呼叫request.getParameter()方法對 request.getInputStream()或request.getReader()沒有衝突,即使已經呼叫了 request.getParameter()方法也可以通過呼叫request.getInputStream()或request.getReader()得 到表單中的資料,而request.getInputStream()和request.getReader()在同一個響應中是不能混合使用的,如果混合使用就會拋異常。 |
你以為到這就結束了嗎?no
小左在開發小程式時,用到了swagger作為api介面開發文件,及測試,不知道用過的朋友們發現了這個沒,
我們發現swagger測試時上傳引數也是 application/json這種方式,這種方式提交的引數在springmvc中都是無法直接對映的,既然遇到了這種問題,如果你還想直接對映,是否有解決方案呢?
不知道大家有啥好的法子,反正小左是直接改變content-type的設定。
那麼是如何設定的呢
swagger的解決方案:
非常簡單,我們的swagger有個註解是設定方法操作型別的。
@ApiOperation(value="介面說明(測試)",httpMethod="Post",consumes="application/x-www-form-urlencoded",notes="在沒有會話、沒有簽名的情況下,進入方法體")
解決了swagger,重點是小程式,畢竟swagger是做測試的,不是重點呀!
其實也很簡單,我們只需要在小程式中傳送post的請求中設定頭資訊就可以了
header: {
"Content-Type":"application/x-www-form-urlencoded"
},
至此,小左的理解就到這兒了,理解 的很淺,希望大佬們多給點見解!