SpringMVC之HttpMessageConverter&RestTemplate筆記(二)

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);
}



發佈了53 篇原創文章 · 獲贊 65 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章