HttpMessageConverter详解

在springMVC的设计中,HttpMessageConverter接口扮演着重要的角色,我们知道springmvc可以接收不同的消息形式,也可以将不同的消息形式响应回去(最常见的是json);这些消息所蕴含的“有效信息”是一致的,那么各种不同的消息转换器,都会生成同样的转换结果。至于各种消息间解析细节的不同,就被屏蔽在不同的HttpMessageConverter实现类中了。

HttpMessageConverter接口负责将请求信息转换成T类型对象,将对象输出为响应信息。

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

HttpMessageConverter接口方法

Boolean canRead(Class clazz,MediaTypemediaType)指定转换器可以读取的对象类型,同时指定支持MIME类型。

Boolean canWriter(Class clazz,MediaTypemediaType)指定转换器可以将clazz类型的对象写到响应流中,响应流支持类型在mediaType中定义

List getSupportMediaTypes()该转换器支持的媒体类型

T read(classclazz,HttpInputMessageinputMessage)将请求信息流转换成T类型的对象

void write(T t,MediaType contentType,HttpOutputMessageoutputMessage)将T类型的对象写到响应流中,同时指定响应媒体类型为contentType



HttpMessageConverter实现类

StringHttpMessageConverter:将请求信息转换为字符串,T为String,可读取所有媒体类型(*/*),可通过supportedMediaTypes属性指定媒体类型



ByteArrayHttpMessageConverter:读写二进制数据,T为byte[]类型,可读取*/*,可通过supportedMediaTypes属性指定媒体类型,响应信息媒体类型为application/octer-stream



MarshallingHttpMessageConverter:T为Object,可读取text/xml和application/xml媒体类型请求,响应信息的媒体类型为text/xml或application/xml



Jaxb2RootElementHttpMessageConverter:通过JAXB2读写XML信息,将请求消息转换到标注XmlRootElement和XmlType注解的类中,T为Object,可读取text/xml和application/xml媒体类型请求,响应信息的媒体类型为text/xml或application/xml



MappingJacksonHttpMessageConverter:利用jackson的ObjectMapper读写Json数据,T为Object,可读取application/json,响应媒体类型为application/json



FormHttpMessageConverter/XmlAwareFormHttpMessageConverter/ResourceHttpConverterMessage/BufferedImageHttpMessageConverter/SourceHttpMessageConverter/RssChannelHttpMessageConverter/AtomFeedHttpMessageConverter



AnnotationMethodHandlerAdapter默认已安装一下HttpMessageConverter

StringHttpMessageConverter、ByteArrayHttpMessageConverter、sourceHttpMessageConverter、XmlAwareFormHttpMessageConverter,如需要装配其它类型HttpMessageConverter,可在spring的web容器上下文中自定义AnnotationMethodHandlerAdapter

如:

"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"”>

"messageConverters" ref="messageConverters"/>





"org.springframework.http.converter.BufferedImageHttpMessageConverter"/>

"org.springframework.http.converter.ByteArrayHttpMessageConverter"/>

"org.springframework.http.converter.StringHttpMessageConverter"/>

"org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>



如果在sring中显示定义了一个AnnotationMethodHandlerAdapter,则spring mvc将使用它覆盖默认的AnnotationMethodHandlerAdapter



使用@RequestBody/@ResponseBody对方法进行标注

使用HttpEntity/ResponseEntity作为处理方法的入参或返回值

实例

@RequestMapping(“/handle41”)

public String handler41(@RequestBody StringrequestBody){

         System.out.pringln(requestBody);

         returnSUCCESS;

}



@ResponseBody

@RequestMapping(“handle42/{imageId}”)

public byte[] handle42(@PathVariable(“imageId”)StringimageId)throw IOException{

         Resourcerec = new ClassPathResource(“/image.jpg”);

         byte[]fileData = FileCopyUtils.copyToByteArray(rec.getInputStream);

         returnfileData;

}

说明:

通过自定义AnnotationMethodHandlerAdapter注册若干个HttpMessageConverter,handler41方法的requestBody标注了@RequestBody,spring mvc 将根据requestBody的类型查找匹配的HttpMessageConverter,由于StringHttpMessageConverter的泛型支持String,StringHttpMessageConverter会被spring mvc选中,用它将请求体信息进行转换并将结果绑定到requestBody入参上

handle42()方法拥有@ResponseBody 注解,方法的返回值类型为byte[],spring mvc会选中ByteArrayHttpMessageConverter 对返回值进行处理,即将图片数据流输出到客户端



和@RequestBody/@ResponseBody类似,spring mvc根据HttpEntity的泛型类型查找对应的HttpMessageConverter

@RequestMapping(“/handle43”)

pubic String handle43(HttpEntity httpEntity){

         long contentLen = httpEntity.getHeaders().getContentLength();

         return SUCCESS;

}

当控制器处理方法使用到@RequestBody/@ResponseBody或HttpEntity/ReponseEntity时,spring mvc使用注册的HttpMessageConverter对请求/响应信息进行处理,spring会根据请求头或响应头的Accepter属性匹配HttpMessageConverter,进而根据参数类型或泛型类型过滤得到匹配的HttpMessageConverter,如找不到则报错



处理XML和Json

Spring mvc提供

MarshallingHttpMessageConverter、

Jaxb2RootElementHttpMessageConverter(JAXB)、

MappingJacksonHttpMessageConverter(Jackson)来处理XML/JSON格式

实例:

"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"”>

"messageConverters" ref="messageConverters"/>





"org.springframework.http.converter.BufferedImageHttpMessageConverter"/>

"org.springframework.http.converter.ByteArrayHttpMessageConverter"/>

"org.springframework.http.converter.StringHttpMessageConverter"/>

class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>

"org.springframework.http.converter.xml.MarshallingHttpMessageConverter">

         p:marshaller-ref=”xmlMarshaller”

         p:unmarshaller-ref=”xmlMarshaller”



"org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>



class="xmlMarshaller"class="org.springframework.oxm.xstream.XStreamMarshaller">

"streamDriver">

"com.thoughtworks.xstream.io.xml.StaxDriver"/>



"annotatedClasses">

com.xxx.User





装配好处理XML和JSON的HttpMessageConverter后,在控制器

@RequestMapping(value=”handle51”)

pubic ResponseEntity handle51(HttpEntity requestEntity){

         User user =requestEntity.getBody();

         user.setUserId(1000);

         return newResponseEntity(user,HttpStatus.OK);

}

客户端通过设置Content-Type及Accept属性,服务端会自动转换

你可能感兴趣的:(HttpMessageConverter详解)