SpringMVC之HttpMessageConverter&RestTemplate笔记(二)

来源:互联网 发布:saas平台数据库设计 编辑:程序博客网 时间:2024/05/24 03:22

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")@ResponseBodypublic byte[] testbyteArray() throws IOException {    Resource resource = new ClassPathResource("timg.jpeg");    return FileCopyUtils.copyToByteArray(resource.getInputStream());}@RequestMapping("/test_second.jpeg")@ResponseBodypublic 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")@ResponseBodypublic 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);}