HttpMessageConverter

在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,HttpMessageConverter完成了这种消息转换机制。

HttpMessageConverte接口定义:

package org.springframework.http.converter;

import java.io.IOException;
import java.util.List; import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType; public interface HttpMessageConverter<T> { boolean canRead(Class<?> clazz, MediaType mediaType); boolean canWrite(Class<?> clazz, MediaType mediaType); List<MediaType> getSupportedMediaTypes(); T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException; void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException; }

HttpMessageConverter接口的定义出现了成对的canRead(),read()和canWrite(),write()方法,MediaType是对请求的Media Type属性的封装。举个例子,当我们声明了下面这个处理方法。

@RequestMapping(value="/string", method=RequestMethod.POST)
public @ResponseBody String readString(@RequestBody String string) {
return "Read string '" + string + "'";
}

在SpringMVC进入readString方法前,会根据@RequestBody注解选择适当的HttpMessageConverter实现类来将请求参数解析到String变量中,具体来说是使用了StringHttpMessageConverter类,它的canRead()方法返回true,然后它的read()方法会从请求中读出请求参数,绑定到readString()方法的string变量中。

当SpringMVC执行readString方法后,由于返回值标识了@ResponseBody,SpringMVC将使用StringHttpMessageConverter的write()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true。

将上述过程集中描述的一个类是org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor,这个类同时实现了HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler两个接口。前者是将请求报文绑定到处理方法形参的策略接口,后者则是对处理方法返回值进行处理的策略接口。RequestResponseBodyMethodProcessor这个类,同时充当了方法参数解析和返回值处理两种角色。而在此过程中,以是否有@RequestBody和@ResponseBody为条件,然后分别调用HttpMessageConverter来进行消息的读写。

ContentNegotiatingViewResolver

主要完成同一资源,多种展现的功能。

三种指定资源格式的方式

Http Request Header: Accept
GET /test/123 HTTP/1.1
Accept: application/json //返回json格式数据 GET /test/123 HTTP/1.1
Accept: application/xml //返回xml格式数据

如果你的资源是通过浏览器访问的,那么由于浏览器的差异,传递到服务器的Accept Header是有差异的,将导致服务器不知道返回何种格式的数据给浏览器。下面是各种浏览器的Accept Header:

chrome:
Accept:application/xml,application/xhtml+xml,textml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 firefox:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 IE8:
Accept:image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
使用扩展名
/test/123.xml  //返回xml格式数据
/test/123.json //返回json格式数据

丧失了同一url多种展现的方式,但现在这种在实际环境中是使用最多的,因为更加符合程序员的审美观。

使用参数
/test/123?format=json  //返回json格式数据
/test/123?format=xml //返回xml格式数据

现在很多open API是使用这种方式,但可能由于要编写的字符较多,所以较少使用。

ContentNegotiatingViewResolver配置

内容协商(content negotiation)的工作是由ContentNegotiatingViewResolver来完成的。它的工作模式支持我上面讲的三种,ContentNegotiatingViewResolver是根据客户提交的MimeType(如 text/html,application/xml)来跟服务端的一组viewResover的MimeType相比较,如果符合,即返回viewResover的数据。

ContentNegotiatingViewResolver配置:

<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="format" />
<property name="ignoreAcceptHeader" value="false" />
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
<property name="defaultContentType" value="text/html" />
</bean> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
</bean>

HttpMessageConverter和ContentNegotiatingViewResolver的更多相关文章

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

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

  2. HttpMessageConverter(消息转换器 )和@responsebody使用(转)

    @responsebody表示该方法的返回结果直接写入HTTP response body中 一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@resp ...

  3. 08点睛Spring MVC4.1-Spring MVC的配置(含自定义HttpMessageConverter)

    8.1 配置 Spring MVC的配置是通过继承WebMvcConfigurerAdapter类并重载其方法实现的; 前几个教程已做了得配置包括 01点睛Spring MVC 4.1-搭建环境 配置 ...

  4. springmvc<一>一种资源返回多种形式【ContentNegotiatingViewResolver】

    restful服务中一个重要的特性就是一种资源可以有多种表现形式,在springmvc中可以使用ContentNegotiatingViewResolver这个视图解析器来实现这种方式. 描述资源的三 ...

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

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

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

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

  7. HttpMessageConverter用法

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

  8. Spring ContentNegotiatingViewResolver

    1. Spring 返回视图采用了ViewResolver,如果一般是jsp的话,可以采用InternalResourceViewResolver. 2.还可以通过ContentNegotiating ...

  9. 将SpringMVC中的HttpMessageConverter替换为Gson

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

随机推荐

  1. stl map一对多用法

    // stlMap.cpp : Defines the entry point for the console application.//#pragma warning (disable : 478 ...

  2. MySQL的Query Cache原理分析

    QueryCache(下面简称QC)是根据SQL语句来cache的.一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC.每个Cache都是以SQL文本作为key来存的. 原理 ...

  3. “FPGA+云"助力高性能计算

    用AI防鲨鱼.用AI学写中国书法.用AI预测人类死亡时间.用AI审判罪犯……在人工智能方兴未艾的今天,越来越廉价和普及的AI领域真的是什么都不值钱,除了想象力.那在这无所不能的AI盛世,一定没道理让算 ...

  4. 阿里云安装 virtio 驱动

    为避免部分服务器.虚拟机或者云主机的操作系统在阿里云控制台 导入镜像 后,使用该自定义镜像创建的 ECS 实例无法启动,您需要在导入镜像前检查是否需要在源服务器中安装 Xen(pv)或 virtio ...

  5. node的express中间件之bodyParser

    bodyParser用于解析客户端请求的body中的内容,内部使用JSON编码处理,url编码处理以及对于文件的上传处理. 下面是一个文件上传的例子. 建立一个1.html页面 <!DOCTYP ...

  6. JoinableQueue

    #!/usr/bin/env python # encoding: utf-8  # Date: 2018/6/17import timefrom multiprocessing import Pro ...

  7. Deep Learning 阅读笔记:Convolutional Auto-Encoders 卷积神经网络的自编码表达

    需要搭建一个比较复杂的CNN网络,希望通过预训练来提高CNN的表现. 上网找了一下,关于CAE(Convolutional Auto-Encoders)的文章还真是少,勉强只能找到一篇瑞士的文章. S ...

  8. file_get_content服务器对服务器二进制文件上传

    1.file_get_contents函数可安全用于二进制对象,适用服务器对服务器文件是上传场景 base64_encode(file_get_contents('1268879774AaCl4wIE ...

  9. 2018-2019-2 《网络对抗技术》Exp7 网络欺诈防范 Week10 20165233

    Exp7 网络欺诈防范 目录 一.基础问题 二.实验步骤 实验点一:简单应用SET工具建立冒名网站 实验点二:ettercap DNS spoof 实验点三:结合应用两种技术,用DNS spoof引导 ...

  10. [Z]牛人林达华推荐有关机器学习的数学书籍

    1. 线性代数 (Linear Algebra): 我想国内的大学生都会学过这门课程,但是,未必每一位老师都能贯彻它的精要.这门学科对于Learning是必备的基础,对它的透彻掌握是必不可少的.我在科 ...