一、HttpMessageConverter
HttpMessageConverter<T>是Spring3.0后加的一个接口,负责将请求信息转换为对象(类型为T)和将返回的对象转换为响应信息。
HttpMessageConverter<T>接口中定义了如下方法:
1️⃣Boolean canRead(Class<?> clazz,MediaType mediaType):指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为clazz类型的对象,同时指定支持的MIME类型(text/html、application/json)
2️⃣Boolean canWrite(Class<?> clazz,MediaType mediaType):指定转换器是否可将clazz类型的对象写到响应流中,响应流支持的媒体类型在MediaType中指定
3️⃣List<MediaType> getSupportMediaTypes():该转换器支持的媒体类型
4️⃣T read(Class<? extends T> clazz,HttpInputMessage inputMessage):将请求信息流转换为T类型的对象
5️⃣void write(T t,MediaType contentType,HttpOutputMessage outputMessage):将T类型的对象写到响应流中,同时指定响应的媒体类型contentType
二、HttpMessageConverter的实现类
实现类 | 功能 |
---|---|
StringHttpMessageConverter | 将请求信息转换为字符串 |
FormHttpMessageConverter | 将表单数据读取到MultiValueMap中 |
XmlAwareFormHttpMessageConverter | 继承自FormHttpMessageConverter,如果部分表单属性是XML数据,可用转换器进行读取 |
ResourceHttpMessageConverter | 读写org.springframework.core.Resource对象 |
BufferedImageHttpMessageConverter | 读写BufferedImage对象 |
ByteArrayHttpMessageConverter | 读写二进制数据 |
SourceHttpMessageConverter | 读写javax.xml.transform.Source类型的数据 |
MarshallingHttpMessageConverter | 通过Spring的org.springframework.xml.Marshaller和Unmarshaller读写XML消息 |
MappingJacksonHttpMessageConverter | 利用Jackson开源包的ObjectMapper读写JSON数据 |
DispatcherServlet默认装配了RequestMappingHandlerAdapter,RequestMappingHandlerAdapter默认装配了以下消息转换器:
1️⃣ByteArrayHttpMessageConverter
2️⃣StringHttpMessageConverter
3️⃣ResourceHttpMessageConverter
4️⃣SourceHttpMessageConverter<T>
5️⃣AllEncompassingFormHttpMessageConverter
6️⃣Jaxb2RootElementHttpMessageConverter
在加入jackson的相关jar包后RequestMappingHandlerAdapter就会自动装配MappingJackson2HttpMessageConverter,来完成JSON格式数据和对象之间的相互转换
三、消息转换器的使用
使用HttpMessageConverter将请求信息转化并绑定到处理方法的入参中或将响应结果转换为对应类型的响应信息,Spring提供了两种途径:
①使用@RequestBody和@ResponseBody对处理方法进行标注
②使用HttpEntity<T>和ResponseEntity<T>作为方法的入参或返回值
当控制器处理方法使用到@RequestBody和@ResponseBody或HttpEntity<T>和ResponseEntity<T>时,Spring首先根据请求头或响应头的Accept属性选择匹配的HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的HttpMessageConverter,若找不到可用的HttpMessageConverter将会报错。
@RequestBody是将请求的正文信息封装起来赋值给对应的入参,比如:
示例:下载
@RequestMapping("/testResponseEntity")
public ResponseEntity<byte[]> testResponseEntity() throws IOException {
FileInputStream input = new FileInputStream(new File("D:\\44\\a.txt"));
byte[] body = new byte[input.available()];
input.read(body);
input.close();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition","attachment;filename=a.txt");
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode);
return entity;
}