1. 程式人生 > >javaweb和app的前後臺互動與Content-Type理解得出的解決方案

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()
request.getInputStream()
request.getReader()
這三個方法都是從request物件中得到提交的資料,但是用途不同。

要根據<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"
      },
至此,小左的理解就到這兒了,理解 的很淺,希望大佬們多給點見解!