一.認識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配置
<dependencies> ... <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>STRUTS_VERSION</version> </dependency> ... </dependencies>
<package name="example" extends="struts-default,json-default"> ... <interceptor-ref name="json"/> ... </package>
{ "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 object 5 Object obj = JSONUtil.deserialize(request.getReader()); 6 ... 7 }
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請求數據,或使用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)