内容协商

什么是内容协商
简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。
这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。
 
Spring 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的简洁风范
使用内容协商的功能,如果不使用第三种方式的话,3.2的版本可以什么都不用配置,默认就能支持前面两种。下面还是看看怎么配置,示例如下:
 需要在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>
在mvc:annotation-driven里面配置使用内容协商
<mvc:annotation-driven
      validator=   "validator"
      conversion-service=   "conversionService"
        content-negotiation-manager=   "contentNegotiationManager"
      >
</mvc:annotation-driven>
 
测试文件的变化:
1:dataType: ‘json’, 这句话可以注掉了
2:在请求的url上添加 后缀,还有参数试试看,注意,前面配置的映射格式是ccjson、ccxml哦,例如:
url:'/mvcexample/hello?format=ccxml',
url:'/mvcexample/hello?format=ccjson',
url:‘/mvcexample/hello.ccxml',
url:‘/mvcexample/hello.ccjson',
 
应该可以看到根据不同的请求,服务端回返回不同格式的数据。

你可能感兴趣的:(springMVC)