????? 在我们实际的开发中,往往需要SpringMVC服务提供多种的格式的数据。如:JSON、XML、HTML
当然我们知道SpringMVC已经提供了很多种转换器,供我们使用将数据转换成我们想要的数据格式。但是服务者怎么知道使用者,想要使用哪种数据格式哪?这就使用到了SpringMVC中的内容协商。
既然是内容协商,那么使用者肯定会告诉服务者,你给我返回什么类型的数据。使用者可以通过如下方式通知服务者。
一、内容协商
??? 1、使用参数
????
/userController/getUser?format=json /userController/getUser?format=xml
??? 2、使用扩展名
?
???
/userController/getUser.html /userController/getUser.json /userController/getUser.xml
??? 3、使用http的Request Headers中的Accpet
?
???
GET /userController/getUser HTTP/1.1 Accept: application/xml //将返回xml格式数据 GET /userController/getUser HTTP/1.1 Accept: application/json //将返回json格式数据
?以上三种方式分析:
?
?? 1、使用参数
???? 现在很多open API是使用这种方式,但可能由于要编写的字符较多。
??? 淘宝的开放平台就是使用的此种方式
?
2、使用扩展名称
?? 丧失了同一url多种展现的方式,但现在这种在实际环境中是使用比较方便的。
3、使用Request Header中Accpet
?? 这种方式是最理想的,但如果你的资源要给用户直接通过浏览器访问(即html展现),那么由于浏览器的差异,发送上来的Accept Header头将是不一样的.?将导致服务器不知要返回什么格式的数据给你. 下面是浏览器的Accept Header:
Chrome:
?
Firefox:
?
IE9:
?我们使用第一种方式和第二种方式,在Spring中如何让配置
?
二、SpringMVC配置
?? 现spring完成内容协商(content negotiation)的工作是由ContentNegotiatingViewResolver来完成的。
它的工作模式支持我上面讲的三种,ContentNegotiatingViewResolver是根据客户提交的MimeType(如 text/html,application/xml)来跟服务端的一组viewResover的MimeType相比较,如果符合,即返回viewResover的数据。
而 /userController/getUser.xml, ContentNegotiatingViewResolver会首先将 .xml 根据mediaTypes属性将其转换成 application/xml,然后完成前面所说的比较。
?
1、我们看下ContentNegotiatingViewResolver的配置:
<!-- 根据客户端的不同的请求决定不同的view进行响应, 如 /user/getUser.json /user/getUser.xml --> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <!-- 设置为true以忽略对Accept Header的支持 --> <property name="ignoreAcceptHeader" value="true" /> <!-- 在没有扩展名时即: "/user/getUser" 时的默认展现形式 --> <property name="defaultContentType" value="text/html" /> <!-- 扩展名至mimeType的映射,即 /getUser.json => application/json --> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </map> </property> <!-- 用于开启 /user/getUser?format=json 的支持 --> <property name="favorParameter" value="false" /> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/page/" /> <property name="suffix" value=".jsp"></property> </bean> </list> </property> <property name="defaultViews"> <list> <!-- for application/json --> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> <!-- for application/xml --> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller"> <!-- xstream.XStreamMarshaller --> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name