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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章