1、本文內容
我們在Web項目開發過程中,一般來說訪問一個處理器,然后會返回一個視圖,或者跳轉到另外的處理器。但是隨着項目越來越復雜,需求越來越復雜,對於處理器返回數據的類型要求也越來越多。比如要求能夠返回JSON類型的數據、或者能夠返回XML格式的數據,或者返回二進制的數據流等等。
SpringMVC提供了這樣的一個機制,允許控制器返回的數據不經過正常的視圖處理流程,而是直接將返回的數據寫入響應體中(response body)。
當然HTTP協議支持的各種數據類型與我們程序運行中產生的各種數據類型是不一樣的,因此需要有一個機制將處理器返回的數據轉換成某種類型的HTTP協議支持的數據類型。
下面介紹相關的機制。
2、設置處理器返回值直接寫入響應體
SpringMVC框架提供了一種十分簡單的方式來配置控制器中的某個處理器的返回值直接寫入響應體,只需要在處理器方法上添加 @ResponseBody 注解即可
@Controller public class HomeController { @RequestMapping("/json") @ResponseBody public Book jsonFun() { Book book = new Book("spring-framework", "12345", "2016-10-12"); return book; } }
3、數據類型轉換
SpringMVC提供了一種數據轉換機制,這種機制可以根據預先設定的media type,調用合適的轉換器將數據轉換成合適的類型。
3.1、默認包含的轉換器
SpringMVC默認包含一系列的數據轉換器,此處不一一列舉,就介紹幾種常用的。
MappingJackson2XmlHttpMessageConverter 基於Jackson的XML轉換器,能夠將對象轉換成XML格式的數據
MappingJackson2HttpMessageConverter 基於 Jackson 的JSON轉換器,能夠將對象轉換成JSON格式的數據
GsonHttpMessageConverter 基於Gson的JSON轉換器,能夠將對象轉換成JSON格式數據
對於系統中默認包含的轉換器,只要我們在項目中加入轉換器所依賴的JAR包,相關轉換器就會被加載。
3.2、設置數據轉換類型 media type
現在我們明確了如何允許控制器直接將返回結果寫入響應體中,並且明確了處理器將返回的數據寫入響應體之前會進行相應的轉換。
但是根據我們前面一節的了解,我們發現SpringMVC中默認攜帶的轉換器不止一種,那么我們如何確定處理器返回的數據交給合適的轉換器,轉換成我們想要的數據類型呢?
只需要使用 @ReuqestMapping注解的一個參數進行設置即可
@RequestMapping(value="/json", produces={"application/json; charset=UTF-8"}) @ResponseBody public Book abc() { Book book = new Book("spring-framework", "12345", "2016-10-12"); return book; }
如上面這個例子,我們將原本使用@RequestMapping設置的路徑設置為 value屬性的值,此外另外設置一個屬性 produces,這個屬性接受一個字符串數組。接受的數據類型是 media type。上面這個例子就是標明這個方法的返回結果要轉換成UTF-8編碼的JSON數據。
3.3、系統默認的設置的 media type[4]
在一些簡單的環境中,比如項目返回的數據類型只需要JSON格式,可能就不需要設置 produces的類型,來指定 media type,也能夠按照要求返回正常的JSON數據,這是為什么?
因為SpringMVC在項目初始化時,會去掃描系統中的JAR包,然后根據掃描到的JAR包設置默認的轉換類型,大概的掃描過程是:
1)檢查系統中是否存在jackson-xml的JAR包,如果存在,就將數據轉換類型列表中設置XML類型,以及其對應的轉換器
2)檢查系統中是否存在jackson-json的JAR包,如果存在,就在數據轉換類型列表中設置JSON類型,以及其對應的轉換器
因為是先檢測的XML,因此XML排在JSON前面,如果系統兩者的JAR包都存在,那么默認情況下數據會被轉換成XML格式
4、設置JSON數據示例
4.1、導入相關JAR包
導入jackson的三個核心包
jackson-annotations-2.8.5.jar jackson-core-2.8.5.jar jackson-databind-2.8.5.jar
4.2、編寫控制器
編寫控制器中的方法,注意以下兩個方面:
1)這個方法需要使用 @ResponseBody注解標注
2)這個方法的返回類型就是需要被轉換成JSON數據的類型
@RequestMapping(value="/json", produces={"application/json; charset=UTF-8"}) @ResponseBody public Book abc() { Book book = new Book("spring-framework", "12345", "2016-10-12"); return book; }
當然,如果你的系統中只導入了JSON的包,那么默認就是JSON類型的,因此也可以寫成這樣
@RequestMapping("/json") @ResponseBody public Book abc() { Book book = new Book("spring-framework", "12345", "2016-10-12"); return book; }
4.3、運行測試
觀察返回的內容,可以發現book對象被正確的轉換成了一個JSON字符串
5、設置XML數據示例
5.1、引入相關JAR包
jackson中有包含轉XML的包
jackson-dataformat-xml-2.8.5.jar
不過它依賴於下列一系列的包
jackson-annotations-2.8.5.jar jackson-core-2.8.5.jar jackson-databind-2.8.5.jar jackson-module-jaxb-annotations-2.8.5.jar stax2-api-3.1.4.jar woodstox-core-5.0.3.jar
5.2、編寫控制器
@RequestMapping(value="/xml", produces={"application/xml; charset=UTF-8"}) @ResponseBody public Book abc() { Book book = new Book("spring-framework", "12345", "2016-10-12"); return book; }
前面說過如果同時有XML和JSON的JAR包的話,默認XML的優先級會高一些,這里可以進行一下測試,看看如果不設置 produces,獲取的數據是JSON還是XML。
5.3、測試結果
參考