`
qct
  • 浏览: 5962 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

这里我主要讲怎么样使用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) propertyis true, the mediaTypes property is inspected for a matching media type.
2. If the request contains a parameter defining the extension and if thesetFavorParameter(boolean) property is true, the mediaTypes property is inspected for amatching media type. The default name of the parameter is format and it can be configuredusing the parameterName property.
3. If there is no match in the mediaTypes property and if the Java Activation Framework (JAF) isboth enabled and present on the class path, FileTypeMap.getContentType(String) is usedinstead.
4. If the previous steps did not result in a media type, and ignoreAcceptHeader is false, therequest Accept header is used.
Once the requested media type has been determined, this resolver queries each delegate view resolver for a View and determines if the requested media type is compatible with the view's content type). The most compatible view is returned.

 

1. spring检查setFavorPathExtension(boolean) 如果这个属性为true(默认为true),它检查请求的后缀名,来返回一种 mediaType ,而后缀名和mediaType是通过ContentNegotiatingViewResolver  配置中的mediaTypes指定的,这个我开始也不确定,后来跟踪源码发现确实是这样映射的。

 

2.spring检查 setFavorParameter(boolean) 这个属性是否为true(默认为false),而如果你打开这个属性,那么默认的参数名应为 format ,spring通过你传过去的参数决定返回哪种mediaType。

 

3.如果前两步没有找到合适的mediaType,则启动**机制去找,这个看不懂,也不用管了。

 

4.如果前三步都没有找到合适的mediaType,并且 ignoreAcceptHeader 这个属性为false(默认为false),spring则根据  你请求头里面设置的  ContentType 来找适合的 mediaType。

 

那么现在我们明白了 ContentNegotiatingViewResolver   resolves a view based on the request file name or Accept header.   就是ContentNegotiatingViewResolver  根据文件名和请求头类型来决定返回什么样的View。而mediaTypes这个属性存储了 你请求后缀名 或者 参数 所对应 的mediaType。

 

所以要想返回JSON数据所代表的MappingJacksonJsonView   ,我们要么在请求头中设置contentType为application/json,要么使用 **.json   或者  **?format=json (这是我的猜测,我猜spring接收到format中的参数后也会去那个map中找)这种请求,其中json这个名字你可以任意换,只要在配置文件中统一就可以了。

 

下面是我项目中具体的使用:

 

XML中的配置:

	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">  
		<property name="mediaTypes">  
		  <map>  
		    <entry key="html" value="text/html"/>  
		    <entry key="spring" value="text/html"/>
		    <entry key="json" value="application/json"/>  
		  </map>  
		</property>
		<property name="viewResolvers">  
		  <list>
		    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
		      <property name="prefix" value="/"/>
		      <property name="suffix" value=".jsp"/>
		    </bean>
		  </list>
		</property>
		<property name="defaultViews">
			<list>
				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
			</list>
		</property>
	</bean>

 

 

前台调用:

<script type="text/javascript">
$(function() {
	jQuery.ajax({
		url : 'index.json',
		contentType : "application/json",//application/xml
		processData : true,//contentType为xml时,些值为false
		dataType : "json",//json--返回json数据类型;xml--返回xml
		data : {
			tag : 'tag123'
		},
		success : function(data) {
			document.write(data.applyList.length);
		},
		error : function(e) {
			document.write('error');
		}
	});
});
</script>

 

后台Controller:

 

	@RequestMapping(value = "/index.json")
	public ModelAndView queryAppliesForJson() {
        ModelAndView mav = new ModelAndView("query_list_paginition");
		List<ChangeApply> applyList = changeApplyService.findAllApplies();
		mav.addObject("applyList", applyList);
        return mav;
	}

 

这么前台JavaScript会接收到JSON字符串。 而且这样设计也符合spring提倡的 RESTful 风格。我们在任何地方只要发出对应的请求,服务器就会给我们返回需要的数据。

 

....陆续增加中,下次我可能会写从源码角度去分析。


首先从DispatcherServlet来分析,doService执行快结束的时候会调用doDispatch来执行分发,在doDispatch方法中会完成返回页面的渲染,以及决定返回什么样的格式。

 

0
3
分享到:
评论
3 楼 liudaowo 2012-09-18  
很好很强大
2 楼 zhang_637 2012-09-07  
来龙去脉,清晰明了,
1 楼 tonyyouwei 2012-08-08  
废话太多!真是个垃圾东西!

相关推荐

    spring 3.0配置示例

    在本文中,我们将深入探讨Spring 3.0框架的配置示例,特别是关于文件上传和AJAX(异步JavaScript及XML)的注解使用。Spring框架是Java领域中广泛使用的轻量级应用框架,它提供了丰富的功能来简化企业级开发。在...

    Spring3.0实现REST实例

    在Spring 3.0中,我们可以使用以下技术实现REST服务: **1. @RestController注解:** 这是Spring MVC提供的一个新注解,它将@Controller和@ResponseBody合并在一起,表明控制器方法的返回值将直接转换为HTTP响应体...

    Spring3.0源码2

    5. **REST支持**:Spring 3.0增加了对RESTful服务的支持,`org.springframework.web.bind.annotation.RequestMapping`和`@ResponseBody`注解用于处理HTTP请求并返回JSON或XML响应。 6. **JSR-303/JSR-349 Bean ...

    Spring3.0新特性源码

    `@RequestMapping`、`@ResponseBody`等注解使得处理HTTP请求和返回JSON或XML数据变得非常容易。 6. **数据访问增强**:Spring 3.0强化了对各种持久化技术的支持,包括JDBC、ORM(Hibernate、JPA)和NoSQL数据库。...

    spring 3.0 应用springmvc 构造RESTful URL 详细讲解

    在Spring 3.0框架中,Spring MVC是一个强大的用于构建Web应用程序的模块,它支持构建RESTful风格的URL,使得应用程序更加符合Web服务的最佳实践。REST(Representational State Transfer)是一种设计模式,强调通过...

    Spring3.0 MVC的初次尝试

    4. **MessageConverter**:Spring 3.0 引入了MessageConverter机制,自动处理HTTP请求和响应的序列化,支持JSON、XML等多种数据格式。 5. **Groovy支持**:Spring 3.0 添加了对Groovy的支持,允许在配置中使用...

    spring3.0支持restful的demo

    在本示例中,我们关注的是Spring框架的3.0版本如何支持RESTful风格的Web服务。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,它基于HTTP协议,强调简洁、无状态和可缓存性。...

    spring3.0 mvc 例子

    在Spring 3.0中,MVC框架引入了基于注解的配置,这大大减少了XML配置文件的需求,使得开发更加简洁和高效。以下是一些关键的注解和概念: 1. **@Controller**:这个注解标记一个类作为Spring MVC的控制器。控制器...

    spring3.0 + ibatis+jquery+注解建立dao、service类

    标题 "spring3.0 + ibatis+jquery+注解建立dao、service类" 提供了我们讨论的核心技术栈,这是构建一个基于Java的Web应用程序的常见组合。Spring框架是核心,用于依赖注入(DI)和面向切面编程(AOP),iBatis则作为...

    spring 3.0 mvc实现rest代码

    8. **依赖包**:压缩包中的依赖包可能包含了 Spring 框架、Spring MVC、JSON 库(如 Jackson 或 Gson)以及可能的数据库驱动等。确保正确配置 Maven 或 Gradle 以引入这些依赖。 综上所述,Spring 3.0 MVC 实现 ...

    [spring 3.0] mvc 整合 restful 、maven实例 下载

    在上面的代码中,我们使用了`@RestController`注解,表明这是一个返回JSON响应的控制器。`@RequestMapping`定义了资源的基础路径,而`@GetMapping`、`@PostMapping`等则对应HTTP方法。`@PathVariable`用于从URL路径...

    基于注解的spring_3.0.x_MVC学习笔记

    在本篇基于注解的Spring 3.0.x MVC学习笔记中,我们将深入探讨Spring MVC在3.0版本中的变化,以及如何通过注解实现快速开发。Spring 3.0.x相较于2.5版本有着显著的改进,尤其在MVC模块上,提供了更加灵活和强大的...

    Spring3.0+Hibernate4.0+SpringMVC整合ExtJS4

    5. 接口设计:定义RESTful API,使得Spring MVC的Controller可以处理来自ExtJS的Ajax请求,返回JSON格式的数据。 6. 安全性考虑:可能需要整合Spring Security或其他安全框架,以保护应用程序免受未经授权的访问。 ...

    spring3.0MVC注解(附实例).docx

    Spring 3.0 MVC 注解是Spring框架中用于简化Web应用开发的重要特性,特别是在处理HTTP请求和响应方面。这些注解允许开发者以声明式的方式定义控制器、方法映射以及数据绑定等行为,极大地提高了代码的可读性和可维护...

    springweb3.0MVC注解(附实例)

    - `@RestController`:等同于 `@Controller` 和 `@ResponseBody`,表示该控制器的所有方法都返回 JSON 或 XML 数据,而不是视图。 ##### 2. `@RequestMapping` - 用于类级别:定义请求处理类所映射的 URL。 - 用于...

    J2EE spring mvc mybatis bootstrap HTML5 后台框架 控制台 mysql版本_spring3.0

    【源码】mysql版本_spring3.0 系统模块 1. 组织管理:角色管理,分角色组和成员,有组权限和成员权限。 2. 系统用户:对各个基本的组会员增删改查,单发、群发邮件短信,导入导出excel表格,批量删除 3. 会员管理:...

    J2EE spring mvc mybatis bootstrap HTML5 后台框架 控制台 oracle版本_spring3.0

    【源码】oracle版本_spring3.0 系统模块 1. 组织管理:角色管理,分角色组和成员,有组权限和成员权限。 2. 系统用户:对各个基本的组会员增删改查,单发、群发邮件短信,导入导出excel表格,批量删除 3. 会员管理:...

    spring_3.0_应用springmvc_构造RESTful_URL_详细讲解

    本教程将深入探讨如何在Spring 3.0中应用Spring MVC来构造RESTful URL。 首先,了解REST(Representational State Transfer)的核心概念至关重要。REST是一种架构风格,它的核心思想是通过HTTP方法(如GET、POST、...

    SpringSecurity3.0.x官方参考文档(英文+中文双解版)

    如果失败,Spring Security会抛出异常并返回相应的错误页面或消息。 ### 6. 会话管理 Spring Security 提供了会话管理功能,包括会话固定攻击防护(Session Fixation Protection)、会话超时和会话并发控制等。 #...

Global site tag (gtag.js) - Google Analytics