@responsebody表示該方法的返回結果直接寫入HTTP response body中
一般在異步獲取數據時使用,在使用@RequestMapping后,返回值通常解析為跳轉路徑,加上@responsebody后返回結果不會被解析為跳轉路徑,而是直接寫入HTTP response body中。比如異步獲取json數據,加上@responsebody后,會直接返回json數據。
Spring3 MVC的@ResponseBody 的作用是把返回值直接寫到HTTP response body里。
Spring MVC 中的 REST 支持
@Controller
使用 @Controller 注釋對將成為 MVC 中控制器的類進行注釋並處理 HTTP 請求。
@RequestMapping
使用 @RequestMapping 注釋對函數進行注釋,該函數處理某些 HTTP 方法、URI 或 HTTP 頭。此注釋是 Spring REST 支持的關鍵。可以更改 method 參數以處理其他 HTTP 方法。
HttpMessageConverter
HTTP 請求和響應是基於文本的,意味着瀏覽器和服務器通過交換原始文本進行通信。但是,使用 Spring,controller 類中的方法返回純 ‘String’ 類型和域模型(或其他 Java 內建對象)。如何將對象序列化/反序列化為原始文本?這由HttpMessageConverter 處理。
Http請求和響應報文本質上都是一串字符串,當請求報文來到java世界,它會被封裝成為一個ServletInputStream的輸入流,供我們讀取報文。響應報文則是通過一個ServletOutputStream的輸出流,來輸出響應報文。
我們從流中,只能讀取到原始的字符串報文,同樣,我們往輸出流中,也只能寫原始的字符。而在java世界中,處理業務邏輯,都是以一個個有業務意義的對象為處理維度的,那么在報文到達SpringMVC和從SpringMVC出去,都存在一個字符串到java對象的阻抗問題。這一過程,不可能由開發者手工轉換。我們知道,在Struts2中,采用了OGNL來應對這個問題,而在SpringMVC中,它是HttpMessageConverter機制。我們先來看兩個接口。
對消息轉換器最高層次的接口抽象,描述了一個消息轉換器的一般特征,我們可以從這個接口中定義的方法,來領悟Spring3.x的設計者對這一機制的思考過程。
public interface HttpMessageConverter<T> { boolean canRead(Class<?> clazz, MediaType mediaType); boolean canWrite(Class<?> clazz, MediaType mediaType); List<MediaType> getSupportedMediaTypes(); T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
HttpMessageConverter接口的定義出現了成對的canRead(),read()和canWrite(),write()方法,MediaType是對請求的Media Type屬性的封裝。舉個例子,當我們聲明了下面這個處理方法。
@RequestMapping(value="/string", method=RequestMethod.POST) public @ResponseBody String readString(@RequestBody String string) { return "Read string '" + string + "'"; }
在SpringMVC進入readString方法前,會根據@RequestBody注解選擇適當的HttpMessageConverter實現類來將請求參數解析到string變量中,具體來說是使用了StringHttpMessageConverter類,它的canRead()方法返回true,然后它的read()方法會從請求中讀出請求參數,綁定到readString()方法的string變量中。
當SpringMVC執行readString方法后,由於返回值標識了@ResponseBody,SpringMVC將使用StringHttpMessageConverter的write()方法,將結果作為String值寫入響應報文,當然,此時canWrite()方法返回true。
我們可以用下面的圖,簡單描述一下這個過程。
在我們對SpringMVC源碼分析的過程中,我們可以從HttpMessageConverter機制中領悟到類似的道理。在SpringMVC的設計者眼中,一次請求報文和一次響應報文,分別被抽象為一個請求消息HttpInputMessage和一個響應消息HttpOutputMessage。
處理請求時,由合適的消息轉換器將請求報文綁定為方法中的形參對象,在這里,同一個對象就有可能出現多種不同的消息形式,比如json和xml。同樣,當響應請求時,方法的返回值也同樣可能被返回為不同的消息形式,比如json和xml。
在SpringMVC中,針對不同的消息形式,我們有不同的HttpMessageConverter實現類來處理各種消息形式。但是,只要這些消息所蘊含的“有效信息”是一致的,那么各種不同的消息轉換器,都會生成同樣的轉換結果。至於各種消息間解析細節的不同,就被屏蔽在不同的HttpMessageConverter實現類中了。
表 1. HttpMessageConverter 示例:
配置 HttpMessageConverter。要生成多個具象,自定義幾個 HttpMessageConverter 實例,以將對象轉換為不同的媒體類型。此部分包括 JSON、ATOM 和 XML 媒體類型。
JSON
從最簡單的示例開始。JSON 是一個輕量型的數據交換格式,人們可輕松地進行讀取和編寫。清單 1 顯示了配置 JSON converter 的代碼。
清單 1. 配置 rest-servlet.xml 中的 HttpMessageConverter
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jsonConverter" /> <ref bean="marshallingConverter" /> <ref bean="atomConverter" /> </list> </property> </bean> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json" /> </bean>
MappingJacksonHttpMessageConverter 用於將對象轉換為 JSON,反之亦然。此內置轉換程序使用 Jackson 的 ObjectMapper 將 JSON 映射到 JavaBean,因此您必須將下列 Jackson JAR 文件添加到類路徑。
org.codehaus.jackson.jar
org.codehaus.jackson.mapper.jar
下一步是編寫一個方法,處理請求 JSON 具象的請求。清單 2 顯示了詳細信息
清單 2. 處理在 EmployeeController 中定義的 JSON 請求
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}", headers="Accept=application/json") public @ResponseBody Employee getEmp(@PathVariable String id) { Employee e = employeeDS.get(Long.parseLong(id)); return e; } @RequestMapping(method=RequestMethod.GET, value="/emps", headers="Accept=application/json") public @ResponseBody EmployeeListinggetAllEmp() { List<Employee> employees = employeeDS.getAll(); EmployeeListinglist = new EmployeeList(employees); return list; }
@ResponseBody 注釋用於將返回對象(Employee 或 EmployeeList)變為響應的正文內容,將使用 MappingJacksonHttpMessageConverter 將其映射到 JSON。
使用 HttpMessageConverter 和 @ResponseBody,您可以實現多個具象,而無需包含 Spring 的視圖技術 — 這是使用 ContentNegotiatingViewResolver 所不具有的一個優勢。
Spring3 MVC的@ResponseBody 的作用是把返回值直接寫到HTTP response body里。 使用AnnotationMethodHandlerAdapter的handleResponseBody方法, AnnotationMethodHandlerAdapter使用request header中”Accept”的值和messageConverter支持的MediaType進行匹配,然后會用”Accept”的第一個值寫入 response的”Content-Type”。
AnnotationMethodHandlerAdapter將會初始化7個轉換器,可以通過調用AnnotationMethodHandlerAdapter的getMessageConverts()方法來獲取轉換器的一個集合
————————————————
版權聲明:本文為CSDN博主「21989939」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_21989939/article/details/46739567