日期:2014-05-16  浏览次数:20283 次

spring3.0中返回Json

这里我主要讲怎么样使用spring3.0 返回JSON数据,至于怎么解析JSON请求本文不涉及。可能后续我会写。

最近由于需求改变,我想使用JSON数据作为返回值,折腾了两天,研究spring源码以及作者blog,终于弄明白了个中原委。

首先问了google大神之后,发现了这篇文章:http://blog.anthonychaves.net/2010/02/01/spring-3-0-web-mvc-and-json/

而在Spring Framework Reference Documentation中,15.5章节也详细介绍了Resolving views,这一章详细介绍了spring可以把你的视图层解析成各种主流技术,包括JSPs, Velocity emplates and XSLT views等等。

spring在解析视图的时候有两个重要的接口:ViewResolver View
ViewResolver 中只有一个方法 resolveViewName ,提供 view name 和 实际 view的映射;
View 中两个方法 getContentType 和 render ,解析请求中的参数并把这个请求处理成某一种 View.

说白了,就是ViewResolver 负责怎么去解析, 而View只代表一种 视图层的技术。

对于一个请求,应该返回什么样的视图是 ViewResolver 来决定的,spring3.0提供的 ViewResolver 包括 AbstractCachingViewResolver,XmlViewResolver,ResourceBundleViewResolver,UrlBasedViewResolver,InternalResourceViewResolver,VelocityViewResolver/FreeMarkerViewResolver,ContentNegotiatingViewResolver等。从字面意思我们大致就可以猜出起用途。
我们平时使用ResourceBundleViewResolver或者InternalResourceViewResolver来返回JSP页面,他们就是其中的两个 ViewResolver

下面我主要说说ContentNegotiatingViewResolver
根据官方文档:The ContentNegotiatingViewResolver does not resolve views itself but rather delegates to other view resolvers,就是说ContentNegotiatingViewResolver 本身并不自己去解析,他只是分配给其他的ViewResolver 去解析。并选择一个看起来像是客户端请求需要返回的一种? View? 返回。


下面来看看我们想要返回的JSON格式的数据,spring3.0中提供了一种View 来支持 JSON,MappingJacksonJsonView ?,在这个View中我们可以封装数据,属性等等,但是怎么让spring返回这个view呢,还是要通过 ViewResolver 来处理。


我们来看官方文档里的一份关于ContentNegotiatingViewResolver? 的典型配置:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="atom" value="application/atom+xml"/>
      <entry key="html" value="text/html"/>
      <entry key="json" value="application/json"/>
    </map>
  </property>
  <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.MappingJacksonJsonView" />
    </list>
  </property>
</bean>


<bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/>


关于 mediaTypes 这个属性我稍后分析,先看viewResolvers和defaultViews这两个属性,viewResolvers中定义了两个 ViewResolver ,defaultViews定义了一个默认的返回视图。但是ContentNegotiatingViewResolver? 是怎么决定使用哪个ViewResolver 以及 返回什么样的 View呢? 通过跟踪源码和查看API文档可以很容易发现。

?

API中写道:
This view resolver uses the requested media type to select a suitable View for a request. This media type is determined by using the following criteria:

1. If the requested path has a file extension and if the setFavorPathExtension(boolean) property is true, the mediaTypes property is inspected for a matching media type.
2. If the request contains a parameter defining the extension and if the setFavorParameter(boolean) property is true, the mediaTypes property is inspected for a matching media type. The default name of the parameter is format and it can be configured using the parameterName property.
3. If there is no match in the mediaTypes property and if the Java Activation