Struts2 Action接收POST請求JSON數據及其實現解析

一.認識JSONhtml

JSON是一種輕量級、基於文本、與語言無關的數據交換格式,能夠用文本格式的形式來存儲或表示結構化的數據。apache

二.POST請求與Content-Type: application/jsonjson

經常使用的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字符串對請求數據進行處理。app

三.Struts2接收JSON請求maven

在Struts2的Action中提取Content-Type爲application/x-www-form-urlencoded的POST參數,咱們很是熟悉:在Action中定義屬性及其getter, setter方法,接收到請求時,默認會將與屬性同名的參數值賦予該屬性post

可是對Content-Type爲application/json的請求數據,Struts2默認沒法解析。由於請求的JSON數據需從輸入流中讀取出來,沒法直接從ServletRequest的請求參數中解析。很容易想到,要讀取JSON請求數據,最直接的方式就是從輸入流讀取。而同時,Struts2的strus2-json-plugin也提供了有關的攔截器,對JSON請求數據進行解析。下面將對兩種方案進行分析:ui

1.從輸入流中讀取JSON請求數據,如下是在Action中實現的一個讀取輸入流數據的方法this

 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的屬性中。步驟以下:

  • 判斷當前請求數據類型是否爲JSON類型
1 String contentType = request.getHeader("content-type");
2 ...
3 if ((contentType != null) && contentType.equalsIgnoreCase("application/json")) {
4     // load JSON object
5     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)

相關文章
相關標籤/搜索