HttpMessageConverter<T>是Spring3的一個重要接口,它負責將請求信息轉換爲一個對象(類型爲T),將對象(類型爲T)輸出爲響應信息。web
DispatcherServlet默認已安裝了RequestMappingHandlerAdapter做爲HandlerAdapter的組件實現類,HttpMessageConverter即由RequestMappingHandlerAdapter使用,將請求信息轉換爲對象,或將對象轉換爲響應信息。spring
HttpMessageConverter<T>接口定義如下幾個方法:json
/** * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses. */ public interface HttpMessageConverter<T> { /** * Indicates whether the given class can be read by this converter. */ boolean canRead(Class<?> clazz, MediaType mediaType); /** * Indicates whether the given class can be written by this converter. */ boolean canWrite(Class<?> clazz, MediaType mediaType); /** * Return the list of {@link MediaType} objects supported by this converter. */ List<MediaType> getSupportedMediaTypes(); /** * Read an object of the given type form the given input message, and returns it. */ T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; /** * Write an given object to the given output message. */ void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
Spring爲HttpMessageConverter提供了衆多的實現類mvc
RequestMappingHandlerAdapter默認已經註冊瞭如下HttpMessageConverter:app
private List<HttpMessageConverter<?>> messageConverters; public RequestMappingHandlerAdapter() { StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); stringHttpMessageConverter.setWriteAcceptCharset(false); // see SPR-7316 this.messageConverters = new ArrayList<HttpMessageConverter<?>>(4); this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(stringHttpMessageConverter); this.messageConverters.add(new SourceHttpMessageConverter<Source>()); this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); }
若是須要裝配其餘類型的HttpMessageConverter,能夠在Spring的web容器(Spring子容器)上下文中自行定義一個RequestMappingHandlerAdapter,註冊若干HttpMessageConverter。dispatcher-servlet.xmlthis
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters" ref="messageConverters"/> </bean> <!--HttpMessageConverter列表--> <util:list id="messageConverters"> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"/> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </util:list>
若是在Spring web容器中顯式定義了一個RequestMappingHandlerAdapter,則Spring MVC將使用它覆蓋默認的AnnotationMethodHandlerAdapter(默認配置就沒有了)。spa
如何使用 HttpMessageConverter<T> 將請求信息轉換並綁定到處理方法的入參中或將響應結果轉爲對應類型的響應信息,Spring MVC提供了兩種途徑:code
1. 使用@RequestBody/@ResponseBody 對處理方法進行標註orm
2. 使用HttpEntity<T>/ResponseEntity<T> 做爲處理方法的入參或返回值xml
示例1:
@RequestMapping(value = "/handle41") public String handle41(@RequestBody String requestBody){ //將請求-報文體-轉換爲字符串綁定到requestBody入參中
} @ResponseBody @RequestMapping("/handle42") public byte[] handle42(){ // }
handle41()處Spring MVC將根據requestBody的類型(String)查找匹配的HttpMessageConverter,因爲StringHttpMessageConverter的泛型類型對應String,因此StringHttpMessageConverter將會被Spring MVC選中,用它將請求體(POST)信息進行轉換而且將結果綁定到requestBody入參上!
handle42()處,因爲方法的返回值類型爲byte[],因此Spring MVC根據類型匹配的查找規則將使用ByteArrayHttpMessageConverter對返回值進行處理。
和@RequestBody/@ResponseBody相似,HttpEntity<?>不但能夠訪問請求和響應報文頭的數據,還能夠訪問請求和響應報文體的數據(也就是HttpEntity中不但有頭數據還有體數據),Spring MVC根據HttpEntity的泛型類型查找對應的HttpMessageConverter。
在接收到一個http請求的時候,處理方法如何知道請求消息的格式,在處理完成以後又根據什麼肯定響應消息的格式?答案很簡單,根據請求消息頭的"Content-Type"及Accept屬性肯定。
Content-Type表示本次請求的報文內容格式。
Accept表示接受的MIME類型。
@ResponseBody @RequestMapping( "/getEmployeesForJson") public Collection<Employee> getEmployees() { return employeeDao .getAll(); }