HttpMessageConverter 是一個對請求信息進行直接轉換的一個接口,就是說不通過resolver直接將對象直接響應並進行轉換,而且HttpMessageConverter接口也可以對請求進行對象的直接轉換。有興趣的同學可以細心研究其接口的方法並去實現自己的MessageConverter,但是Spring所提供的HttpMessageConverter已經足夠強大。以下就列出以下Spring所提供的MessageConverter。
以下是接口的內容,這個來之於官網文檔
public interface HttpMessageConverter<T> { // Indicate whether the given class and media type can be read by this converter. boolean canRead(Class<?> clazz, MediaType mediaType); // Indicate whether the given class and media type can be written by this converter. boolean canWrite(Class<?> clazz, MediaType mediaType); // Return the list of MediaType objects supported by this converter. List<MediaType> getSupportedMediaTypes(); // Read an object of the given type from the given input message, and returns it. T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; // Write an given object to the given output message. void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
StringHttpMessageConverter ----> 將請求信息轉換爲字符串 [可讀取所有媒體類型,通過設置supportedMediaTypes屬性指定媒體類型]
FormHttpMessageConverter -----> 將表達數據讀取到MultiValueMap中。 [讀寫支持類型application/x-www-form-urlencoded 寫支持multipart/form-data]
XmlAwareFormHttpMessageConverter ----> 擴展FormHttpMessageConverter,如果部分表單屬性爲XML數據,可用該轉換器進行讀取。
ResourceHttpMessageConverter ----> 讀寫 org.springframework.core.io.Resource 對象
BufferedImageHttpMessageConverter ----> 讀寫BuffereImage對象
ByteArrayHttpMessageConverter ---> 讀寫二進制數據將請求信息 [可讀取所有媒體類型,通過設置supportedMediaTypes屬性指定媒體類型]
SourceHttpMessageConvert ----> 讀寫javax.xml.transform.Source類型數據 [讀寫支持類型text/xml application/xml]
MarshallingHttpMessageConvert ----> 通過Spring的org.springframework.oxm.Marshaller 和 Unmarshaller 讀寫XML消息 [讀寫支持類型text/xml application/xml]
Jaxb2RootElementHttpMessageConvert ----> 通過JAXB2讀寫XML消息,將請求消息轉換到標籤XmlRootElement和XmlType [讀寫支持類型text/xml application/xml]
MappingJacksonHttpMessageConvert ---> 利用jackson開源包的ObjectMapping讀寫JSON數據 [讀寫application/json]
RssChannelHttpMessageConverter ----> 能夠讀寫RSS種子消息 [讀寫application/rss+xml]
AtomFeedHttpMessageConverter ----> 和RssChannelHttpMessageConverter能夠讀寫RSS種子信息 [讀寫application/atom+xml]
其實AnnotationMethodHandlerAdapter 默認已經裝配了很多converter了,所以其實並沒有必要自己定義messageConverter列表,這裏還是寫一下何如定義messageConverter列表:
<mvc:annotation-driven > <mvc:message-converters> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter" /> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven>
其實如果直接使用默認裝配,只需要這樣:
<mvc:annotation-driven />
需要注意的是Json也是默認支持的,但是我們需要自己添加jackson的包,POM的dependency如下:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.1.4</version> </dependency>
使用也是非常簡單通過@RequestBody進行請求轉換 和 @ResponseBody進行相應對象的轉換,以下就是幾個比較常用的例子,包括轉JSON 轉字符串 轉二進制 轉圖片:
JSON轉換
@RequestMapping("/getRequestUser.json") public @ResponseBody User getRequestUser(@RequestBody User user){ System.out.println(user.toString()); return user; }請求類型爲JSON,accept類型也是JSON 請求和返回如下:
請求:
POST /springreview/user/getRequestUser.json HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Connection: close
User-Agent: Paw/2.3.4 (Macintosh; OS X/10.12.5) GCDHTTPRequest
Content-Length: 50
{"userId":"123","username":"tony","pwd":"tonypwd"}
返回:
{"userId":"123","username":"tony","pwd":"tonypwd"}
返回二進制類型和bufferedImage類型,使用瀏覽器可以返回一張圖片
@RequestMapping("/test.jpeg") @ResponseBody public byte[] testbyteArray() throws IOException { Resource resource = new ClassPathResource("timg.jpeg"); return FileCopyUtils.copyToByteArray(resource.getInputStream()); } @RequestMapping("/test_second.jpeg") @ResponseBody public BufferedImage test() throws IOException { Resource resource = new ClassPathResource("timg.jpeg"); BufferedImage image = ImageIO.read(resource.getInputStream()); return image; }
RestTemplate 是Spring3的新增模板,可以在客戶端應用程序使用該類進行WEB服務的調用,它支持REST風格的URL。它和AnnotationMethodHandlerAdapter一樣默認就會添加一堆的MessageConverter所以使用非常方便:
public void testUserJson(){ RestTemplate rest = new RestTemplate(); HttpHeaders entityHeader = new HttpHeaders(); entityHeader.setContentType(MediaType.APPLICATION_JSON_UTF8); entityHeader.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8)); User user = new User(); user.setUserId(123); user.setUsername("tony"); user.setPwd("tonypwd"); HttpEntity<User> requestEntity = new HttpEntity<User>(user,entityHeader); String url = "http://localhost:8080/springreview/user/getRequestUser.json"; ResponseEntity<User> responseEntity = rest.exchange(url, HttpMethod.POST,requestEntity,User.class); System.out.println(responseEntity.getBody().toString()); }
需要注意的是,我們使用了HttpEntity 這兩個類主要的作用是對請求頭進行描述,當然我們這裏返回了一個responseEntity對象用戶直接獲得對象。然而我們在controller同樣可以定義HttpEntity和ResponseEntity 去獲得客戶端的請求頭部信息和其他返回信息,如果我們使用了responseEntity,HttpEntity 就不用打上annotation標記了:
@RequestMapping("/getRequestUser.json") public ResponseEntity<User> getRequestUser(RequestEntity<User> entity){ System.out.println(entity.getHeaders().toString()); System.out.println(entity.getBody().toString()); ResponseEntity<User> responseEntity = new ResponseEntity<User>(entity.getBody(), HttpStatus.OK); return responseEntity; }
以下是關於字符串的例子:
@RequestMapping("/string.txt") @ResponseBody public String testStringConverter(String request){ System.out.println("request : " + request); return request; }
使用restTemplate:
public void testParam(){ RestTemplate restTemplate = new RestTemplate(); MultiValueMap<String,Object> multiValueMap = new LinkedMultiValueMap<String, Object>(); multiValueMap.add("request","TESTING"); String url = "http://localhost:8080/springreview/test/string.txt"; String response = restTemplate.postForObject(url,multiValueMap,String.class); System.out.println(response); }