標籤:orm load 通過 color 預設 ade 訊息 html 伺服器
一.認識JSON
JSON是一種輕量級、基於文本、與語言無關的資料交換格式,可以用文字格式設定的形式來儲存或表示結構化的資料。
二.POST請求與Content-Type: application/json
常用的HTTP要求方法有GET, POST, PUT, DELETE等。在提交POST請求時,請求資料放在訊息體(Body)中,請求資料的格式及編碼方式用Content-Type來指定。如我們常用的表單<form>提交,其Content-Type預設為application/x-www-form-urlencoded,提交的資料按照key1=val1&key2=val2進行編碼,伺服器端也能很容易地解析K-V值。
JSON的出現,讓交換的資料不再僅限於簡單的K-V結構,而可以有更加複雜的層級,特別適合於RESTful介面。在發送請求時,指定Content-Type為application/json,即可使用JSON字串作為請求的資料。而在伺服器端接收到該請求後,將按照JSON字串對請求資料進行處理。
三.Struts2接收JSON請求
在Struts2的Action中提取Content-Type為application/x-www-form-urlencoded的POST參數,我們非常熟悉:在Action中定義屬性及其getter, setter方法,接收到請求時,預設會將與屬性同名的參數值賦予該屬性。
但是對Content-Type為application/json的請求資料,Struts2預設無法解析。因為請求的JSON資料需從輸入資料流中讀取出來,無法直接從ServletRequest的請求參數中解析。因此很容易想到,要讀取JSON請求資料,最直接的方式就是從輸入資料流讀取。而Struts2的strus2-json-plugin也提供了攔截器,對JSON請求資料進行解析。下面將對兩種方案進行分析:
1.從輸入資料流中讀取JSON請求資料,以下是在Action中實現的一個讀取輸入資料流資料的方法
1 //解析請求的Json資料 2 private String getRequestPostData(HttpServletRequest request) throws IOException { 3 int contentLength = request.getContentLength(); 4 if(contentLength<0){ 5 return null; 6 } 7 byte buffer[] = new byte[contentLength]; 8 for (int i = 0; i < contentLength;) { 9 int len = request.getInputStream().read(buffer, i, contentLength - i);10 if (len == -1) {11 break;12 }13 i += len;14 }15 return new String(buffer, "utf-8");16 }
在Action的execute方法中調用該方法,即可擷取到請求的JSON資料。
2.使用struts2-json-plugin配置
- 添加struts2-json-plugin的依賴,以maven配置為例:
<dependencies> ... <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>STRUTS_VERSION</version> </dependency> ...</dependencies>
- struts.xml設定檔添加JSON配置(粗體部分)
<package name="example" extends="struts-default,json-default"> ... <interceptor-ref name="json"/> ... </package>
- 在Action中指定JSON資料中各個key及getter, setter,如請求的JSON資料如下,則在Action中定義名為type, message, code的屬性及其getter, setter
{ "type":10, "message": "this is a test msg", "code": 200}
這樣,在接收到以上JSON請求資料時,Struts會預設將type, message, code的值解析出來。
3.struts2-json-plugin解析JSON請求資料的分析
經過分析,struts2-json-plugin解析JSON請求資料,最核心的一個類是JSONIntercepter類。該攔截器的主要工作就是:讀取JSON請求資料,將JSON資料提取出K-V值並設定到Action的屬性中。步驟如下:
1 String contentType = request.getHeader("content-type");2 ...3 if ((contentType != null) && contentType.equalsIgnoreCase("application/json")) {4 // load JSON object5 Object obj = JSONUtil.deserialize(request.getReader());6 ...7 }
- 如果資料類型為JSON,從輸入資料流中讀取JSON資料,以下為JSONUtil類的deserialize方法
1 public static Object deserialize(Reader reader) throws JSONException { 2 // read content 3 BufferedReader bufferReader = new BufferedReader(reader); 4 String line; 5 StringBuilder buffer = new StringBuilder(); 6 7 try { 8 while ((line = bufferReader.readLine()) != null) { 9 buffer.append(line);10 }11 } catch (IOException e) {12 throw new JSONException(e);13 }14 15 return deserialize(buffer.toString());16 }
- 解析得到JSON對象後,遍曆JSON對象,取出K-V,通過反射的V設定給予K相同的屬性
開發人員可根據自己的需求進行選擇:從輸入資料流直接讀取JSON請求資料,或使用struts2-json-plugin對JSON請求資料進行處理。
參考資料:
四種常見的 POST 提交資料方式(https://imququ.com/post/four-ways-to-post-data-in-http.html)
JSON Plugin(https://struts.apache.org/docs/json-plugin.html)
Struts2 Action接收POST請求JSON資料及其實現解析