简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。
这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。
nSpring MVC REST是如何决定采用何种方式(视图)来展示内容呢?
一:根据Http请求的header中的Accept属性的值来判读,比如:
Accept: application/xml 将返回xml格式数据
Accept: application/json 将返回json格式数据
缺点:是由于浏览器的差异,导致发送的Accept Header头可能会不一样,从而导致服务器不知要返回什么格式的数据
二:根据扩展名来判断,比如:
/mvc/test.xml 将返回xml格式数据
/mvc/test.json 将返回json格式数据
/mvc/test.html 将返回html格式数据
缺点:丧失了同一URL的多种展现方式。在实际环境中使用还是较多的,因为这种方式更符合程序员的习惯
三:根据参数来判断
/mvc/test?format=xml 将返回xml数据
/mvc/test?format=json 将返回json数据
缺点:需要额外的传递format参数,URL变得冗余繁琐,缺少了REST的简洁风范
n
n使用内容协商的功能,如果不使用第三种方式的话,3.2的版本可以什么都不用配置,默认就能支持前面两种。下面还是看看怎么配置,示例如下:
n需要在spring的配置文件中做配置,示例如下:
<!--1、检查扩展名(如my.pdf);2、检查Parameter(如my?format=pdf);3、检查Accept Header-->
<bean id=
"contentNegotiationManager" class=
"org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- 扩展名至mimeType的映射,即 /user.json => application/json -->
<property name=
"favorPathExtension" value=
"true" />
<!-- 用于开启 /userinfo/123?format=json 的支持 -->
<property name=
"favorParameter" value=
"true" />
<property name=
"parameterName" value=
"format"/>
<!-- 是否忽略Accept Header -->
<property name=
"ignoreAcceptHeader" value=
"false"/>
<property name=
"mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用 -->
<value>
ccjson=application/json
ccxml=application/xml
html=text/html
</value>
</property>
<!-- 默认的content type -->
<property name=
"defaultContentType" value=
"text/html" />
</bean>
<!-- ========================= VIEW定义 ========================= -->
<!-- 内容协商视图解析器;根据客户端不同的请求决定不同的view进行响应 -->
<!-- 会自动根据解析的contentType来决定使用哪个视图解析器(默认使用整个web应用中的viewResolver) -->
<bean class=
"org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order=
"0">
<!-- 内容协商管理器 用于决定media type -->
<property name=
"contentNegotiationManager" ref=
"contentNegotiationManager"/>
<!-- 默认视图 放在解析链最后 -->
<property name=
"defaultViews">
<list>
<bean class=
"org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean class=
"org.springframework.web.servlet.view.xml.MarshallingView">
<property name=
"marshaller">
<bean class=
"org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name=
"packagesToScan" value=
"cn.javass"></property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
<!-- bean name view resolver-->
<bean class=
"org.springframework.web.servlet.view.BeanNameViewResolver" p:order=
"1"/>
<!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用
html)- -->
<bean id=
"defaultViewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver" p:order=
"2">
<property name=
"viewClass" value=
"org.springframework.web.servlet.view.JstlView"/>
<property name=
"contentType" value=
"text/html"/>
<property name=
"prefix" value=
"/WEB-INF/jsp/"/>
<property name=
"suffix" value=
".jsp"/>
</bean>
n在mvc:annotation-driven里面配置使用内容协商
<mvc:annotation-driven
validator=
"validator"
conversion-service=
"conversionService"
content-negotiation-manager=
"contentNegotiationManager"
>
</mvc:annotation-driven>