HttpMessageConverter<T>是Spring3的一个重要接口,它负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息。

DispatcherServlet默认已安装了RequestMappingHandlerAdapter作为HandlerAdapter的组件实现类,HttpMessageConverter即由RequestMappingHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。

HttpMessageConverter<T>接口定义以下几个方法:

/**
* 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提供了众多的实现类

RequestMappingHandlerAdapter默认已经注册了以下HttpMessageConverter:

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.xml

<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(默认配置就没有了)。

如何使用 HttpMessageConverter<T> 将请求信息转换并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,Spring MVC提供了两种途径:

1. 使用@RequestBody/@ResponseBody 对处理方法进行标注

2. 使用HttpEntity<T>/ResponseEntity<T> 作为处理方法的入参或返回值

示例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();
}
 请求时的目标类型:
方法的实际返回值为:Employee 的集合
SpringMVC 发现需要返回的是JSON类型,但实际返回的是Employee的集合。此时@ResponseBody查找有没有把结果转为JSON的HttpMessageConverter,如果有,则调用其对应的方法,把结果转为JSON类型。
结论:
1.只有当处理器方法使用到@RequestBody/@ResponseBody 或HttpEntity<T>/ResponseEntity<T> 时,SpringMVC才使用注册的HttpMessageConverter 对请求响应消息进行处理。
2.当控制器处理方法使用到 @RequestBody/@ResponseBody 或HttpEntity<T>/ResponseEntity<T> 时,Spring 首先根据请求头或响应头的 Accept 属性选择匹配的 HttpMessageConverter, 然后根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的HttpMessageConverter 将报错
3.@RequestBody 和 @ResponseBody 不需要成对出现。如果方法入参使用到了@RequestBody,SpringMVC将会选择匹配的HttpMessageConverter 将请求信息转换并绑定到该入参中。如果处理方法标注了@ResponseBody,SpringMVC选择匹配的HttpMessageConverter 将方法返回值转换并输出响应消息。

HttpMessageConverter的更多相关文章

  1. no suitable HttpMessageConverter found for request type [java.lang.Integer]

    今天在使用Spring Template的时候遇到了这个异常: no suitable HttpMessageConverter found for request type [java.lang.I ...

  2. SpringMVC 中HttpMessageConverter简介和Http请求415 Unsupported Media Type的问题

    一.概述: 本文介绍且记录如何解决在SpringMVC 中遇到415 Unsupported Media Type 的问题,并且顺便介绍Spring MVC的HTTP请求信息转换器HttpMessag ...

  3. HttpMessageConverter用法

    HttpMessageConverter接口定义 * Strategy interface that specifies a converter that can convert from and t ...

  4. 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务

    原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...

  5. 将SpringMVC中的HttpMessageConverter替换为Gson

    读者们看到这个标题也许会感到奇怪,SpringMVC中默认的HttpMessageConverter不是Jackson吗,但是我在使用的过程中发现Jackson并不好用,如果有一些复杂的嵌套类型,当然 ...

  6. springboot学习(三)——http序列化/反序列化之HttpMessageConverter

    以下内容,如有问题,烦请指出,谢谢! 上一篇说掉了点内容,这里补上,那就是springmvc的http的序列化/反序列化,这里简单说下如何在springboot中使用这个功能. 使用过原生netty ...

  7. springboot学习(三)————使用HttpMessageConverter进行http序列化和反序列化

    以下内容,如有问题,烦请指出,谢谢! 对象的序列化/反序列化大家应该都比较熟悉:序列化就是将object转化为可以传输的二进制,反序列化就是将二进制转化为程序内部的对象.序列化/反序列化主要体现在程序 ...

  8. 【Spring】HttpMessageConverter的作用及替换

    相信使用过Spring的开发人员都用过@RequestBody.@ResponseBody注解,可以直接将输入解析成Json.将输出解析成Json,但HTTP 请求和响应是基于文本的,意味着浏览器和服 ...

  9. RestTemplate 微信接口 text/plain HttpMessageConverter

    一.背景介绍 使用 Spring Boot 写项目,需要用到微信接口获取用户信息. 在 Jessey 和 Spring RestTemplate 两个 Rest 客户端中,想到尽量不引入更多的东西,然 ...

  10. HttpMessageConverter 专题

    配置HttpMessageConverterHttpMessageConverter是对http的request和response进行自动转换配置HttpMessageConverter可重载下面两个 ...

随机推荐

  1. (转)看懂UML类图

    转自:http://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html 这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关 ...

  2. Ajax与传统Web开发的区别

    基本概念 1.1,Ajax AJAX:即“Asynchronous Javascript And XML”(异步的JavaScript和XML),是指一种创建交互式网页应用的网页开发技术,尤其是在一种 ...

  3. python抓包模块

    pcapy模块 安装 yum install -y epel-release yum install -y pip gcc    gcc-c++   libpcap-devel python-deve ...

  4. hihocoder 1866 XOR

    题面在这里 拆位分析一下就OK啦 /* y + (y xor x) */ #include<bits/stdc++.h> #define ll long long using namesp ...

  5. 【漏洞预警】方程式又一波大规模 0day 攻击泄漏,微软这次要血崩

    一大早起床是不是觉得阳光明媚岁月静好?然而网络空间刚刚诞生了一波核弹级爆炸!Shadow Brokers再次泄露出一份震惊世界的机密文档,其中包含了多个精美的 Windows 远程漏洞利用工具,可以覆 ...

  6. 【BZOJ】4260: Codechef REBXOR【Trie树】【前后缀异或最大】

    4260: Codechef REBXOR Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2218  Solved: 962[Submit][Stat ...

  7. Gunicorn配置部分的翻译

    写在前面,虽然翻译得很烂,但也是我的劳动成果,转载请注明出处,谢谢. Gunicorn版本号19.7.1 Gunicorn配置 概述 三种配置方式 优先级如下,越后的优先级越大 1.框架的设置(现在只 ...

  8. Codeforces Round #356 (Div. 2) C. Bear and Prime 100 水题

    C. Bear and Prime 100 题目连接: http://www.codeforces.com/contest/680/problem/C Description This is an i ...

  9. java中write(byte[] b)与write(byte[] b,int off,int len)区别

    public static void copyInputStreamT0OutputStream(InputStream in, OutputStream out) { byte[] buffer = ...

  10. CGI 、PHP-CGI、FASTCGI、PHP-FPM

    CGI是干嘛的? CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者.web server(比如说nginx)只是内容的分发者.比如,如果请求的是/index/ht ...