一、说明

JSON数据交换格式在Restful WebService中发挥了很大作用,也使得Restful WebService称为WebService事实上的标准,取代了重量级SOAP。

可以这么理解JSON在spring mvc中的意义:spring mvc中模型数据,可以被html网页通过某形式进行展示,也可以被App通过JSON格式进行展示,也就是说:模型数据存在不同的表现形式,JSON是其中一种

spring mvc中,是通过一种ViewResolver处理JSON:ContentNegotiatingViewResolver

通过ContentNegotiatingViewResolver可以将相同的数据以不同的呈现格式请求进行返回(这里是服务端返回JSON格式)

ContentNegotiatingViewResolver是此类需求通用的处理方式

二、使用

1、在spring mvc配置文件mvc-dispatcher-servlet.xml中配置

<!-- 6、配置ViewResolver,可以配合多个ViewResolver,多个ViewResolver使用order属性排序。 InternalResourceViewResolver放在最后。因为:请求必定会返回一个对象,这个对象可能不是我们想要的,所以使用InternalResourceViewResolver进行兜底 -->
	<bean
		class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<property name="order" value="1" />
		<property name="mediaTypes">
			<map>
				<entry key="json" value="application/json" />
				<entry key="xml" value="application/xml" />
				<entry key="htm" value="text/html" />
			</map>
		</property>

		<property name="defaultViews">
			<list>
				<!-- JSON View :这里的配置实现将模型数据通过jackson工具转换成JSON格式,同时需要项目引入jackson依赖-->
				<bean
					class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
				</bean>
			</list>
		</property>
		<property name="ignoreAcceptHeader" value="true" />
	</bean>

2、添加上述配置依赖的jackson到项目工程依赖

<jackson.version>2.5.4</jackson.version>
<!--jackson-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

3、增加controller方法

/**
  * 本方法将处理:/courses/view4/{courseId}的URL的Get类型请求,如:http://localhost:8080/courses/view4/123
  *
  * method = RequestMethod.GET:GET类型请求
  * 使用@PathVariable关联查询参数
  *
  * 通过@ResponseBody注解在方法的返回值上可以以最简单的方式将返回的模型数据呈现成JSON格式
  *
  * @param courseId
  * @return
  */
 @RequestMapping(value = "/view4/{courseId}",method = RequestMethod.GET)
 public @ResponseBody Course getCourseInJSON(@PathVariable Integer courseId){
     return courseService.getCoursebyId(courseId);
 }

其中:

  • 本方法将处理:/courses/view2/{courseId}的URL的Get类型请求,如:http://localhost:8080/courses/view2/123
  • method = RequestMethod.GET:GET类型请求
  • 使用@PathVariable关联查询参数
  • 通过@ResponseBody注解在方法的返回值上可以以最简单的方式将返回的模型数据呈现成JSON格式(还有其他方式)

4、启动服务器,输入地址:http://localhost:8080/courses/view4/123

5、结果:

js获取springmvc的model_json

6、可以通过JSON文本查看器查看,这里使用notepad++的插件JSON viewer查看

js获取springmvc的model_js获取springmvc的model_02

7、上面例子是通过@ResponseBody注解在方式将模型数据转换成JSON格式返回,也可以使用spring mvc提供的ResponseEntity<T>

1)controller

/**
     * 本方法将处理:/jsontype/{courseId}的URL的Get类型请求,如:http://localhost:8080/courses/jsontype/123
     * <p>
     * method = RequestMethod.GET:GET类型请求
     * <p>
     * 使用@PathVariable关联查询参数
     * <p>
     * 通过定义方法返回值为:ResponseEntity<Course>,其中ResponseEntity是spring mvc为我们抽象的实体,通过泛型的方式包装我们的业务实体,此时不需要通过@ResponseBody对返回值进行修饰,这样就可以向浏览器返回一个JSON的数据
     *
     * @param courseId
     * @return
     */
    @RequestMapping(value = "/jsontype/{courseId}", method = RequestMethod.GET)
    public ResponseEntity<Course> getCourseInJSON2(@PathVariable Integer courseId) {
        Course course = courseService.getCoursebyId(courseId);
        return new ResponseEntity<Course>(course, HttpStatus.OK);
    }
  • 本方法将处理:/jsontype/{courseId}的URL的Get类型请求,如:http://localhost:8080/courses/jsontype/123
  • 通过定义方法返回值为:ResponseEntity<Course>,其中ResponseEntity是spring mvc为我们抽象的实体,通过泛型的方式包装我们的业务实体,此时不需要通过@ResponseBody对返回值进行修饰,这样就可以向浏览器返回一个JSON的数据

2)启动服务器,输入URL:http://localhost:8080/courses/jsontype/123

3)结果相同

三、单页面开发模式中应用

作用:彻底的将后端的业务逻辑与前端的页面呈现相分离,甚至不需要在后端的某一个方法中组织很多相对独立的业务模型

原理:前端通过javascript可以动态的生成页面,后端只需要提供独立的业务接口即可

实现:

1)controller

上面两个方法均可

2)jsp页面:course_json.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>单页面开发模式测试</title>

<link rel="stylesheet"
	href="<%=request.getContextPath()%>/resources/css/main.css"
	type="text/css" />
<script type="text/javascript"
	src="<%=request.getContextPath()%>/resources/js/jquery-1.11.3.min.js"></script>

</head>
<script>
jQuery(function($){
	var urlStr = "<%=request.getContextPath()%>/courses/view4/<%=request.getParameter("courseId")%>";
	//alert("Before Call:"+urlStr);
	$.ajax({
		method: "GET",
		url: urlStr,
		success:function(data,status,jqXHR){
			//alert("Success:"+data);
			var course = data;
			var path = "<%=request.getContextPath()%>/";	
			$(".course-title").html(course.title);
			$(".course_video").attr("src", path+course.imgPath);
			$("#learningNum").text(course.learningNum);
			$("#duration").text(course.duration);
			$("#levelDesc").text(course.levelDesc);
			$(".course_shortdecription").html(course.descr);
			
			var chapterList = course.chapterList;
			var chapter;
			
			for(var i = 0;i<chapterList.length;i++){
				chapter = chapterList[i];	
				
				var liObj = $("li",$("#chapterTemplate")).clone();				 
				$(".outline_name", liObj).text(chapter.title);
				$(".outline_descr", liObj).text(chapter.descr);				
				liObj.appendTo("#couList");				
			}// ~ end for			
		}
	}); // end ajax
});
</script>
<body>


	<div id="main">

		<div class="newcontainer" id="course_intro">
			<div class="course-title"></div>
			<div class="course_info">
				<div class="course-embed l">
					<div id="js-course-img" class="img-wrap">
						<img width="600" height="340" alt=""
							class="course_video" />
					</div>
					<div id="js-video-wrap" class="video" style="display: none">
						<div class="video_box" id="js-video"></div>
					</div>
				</div>
				<div class="course_state">
					<ul>
						<li><span>学习人数</span> <em id="learningNum"></em></li>
						<li class="course_hour"><span>课程时长</span> <em
							class="ft-adjust"><span id="duration"></span>秒</em></li>
						<li><span>课程难度</span> <em id="levelDesc"></em></li>
					</ul>
				</div>

			</div>
			<div class="course_list">
				<div class="outline">
					<h3 class="chapter_introduces">课程介绍</h3>
					<div class="course_shortdecription"></div>

					<h3 class="chapter_catalog">课程提纲</h3>
					<ul id="couList">
						
					</ul>
				</div>

			</div>
		</div>

	</div>

    <div id="chapterTemplate"  style="display:none">
       <li class="clearfix open"><a href="#">
				<div class="openicon"></div>
				<div class="outline_list l">
						<h5 class="outline_name"></h5>
						<p class="outline_descr"></p>
				</div>
		 </a></li>
    </div>

</body>
</html>

注意这里的jsp页面放在web-inf外面,即webapp下面,因为web-inf下防止的都是私有的,而这个jsp页面需要暴露到外面。

  • 其中jsp页面中标签都是静态的信息、没有任何数据
  • jsp中通过javascript(jquery)的方式,在页面加载完成时通过ajax方法异步访问调用服务器端的请求:

js获取springmvc的model_json_03

请求后,将返回的数据通过jquery动态加载到页面上,进行呈现。

这里访问的URL是:

3)测试,启动服务器,输入URL地址:http://localhost:8080/course_json.jsp?courseId=123

其中这个URL是直接访问上面的JSP页面,并传递后面的courseId参数

4)结果

可以正常显示jsp页面,且通过jquery可以动态获取调用后台请求(CourseController的getCourseInJSON方法)获取json格式数据,并动态设置到jsp页面上

四、总结

  1. spring mvc中通过ContentNegotiatingViewResolver将不同的数据呈现请求转化到不同的view,可以将相同的数据以不同的呈现格式请求进行返回(这里是服务端返回JSON格式)ContentNegotiatingViewResolver是此类需求通用的处理方式。
  2. 在服务端代码中使用了ResponseEntity类来处理返回结果:将我们的模式数据包裹在此类中,就可以完成将模型数据转化成JSON格式
  3. 另一种更加简单的方式是使用@ResponseBody/@RequestBody:
  1. @ResponseBody:将返回数据转换成JSON格式
  2. @RequestBody:获取页面通过JSON格式提交的请求
  3. @ResponseBody/@RequestBody:使得用javascript直接和服务器进行交互成为可能