实现springmvc返回json内容。

[b]1.指定视图类型[/b]
新增JsonController类,代码如下:

package com.sunbin.test.testSpring.web.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.sunbin.test.testSpring.service.TestService;
import org.springframework.stereotype.Controller;

@Controller
@RequestMapping(value = "/json")
public class JsonController {
	@Autowired
	public TestService testService;

	@RequestMapping(value = "/y", method = { RequestMethod.GET })
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		// TODO Auto-generated method stub
		ModelAndView view = new ModelAndView(new MappingJackson2JsonView());
		view.addObject("status", "y");
		view.addObject("info", "success");
		return view;
	}

}



类中指定了使用MappingJackson2JsonView视图,该视图会将view中的各个对象转换为json的属性返回,并指定响应ContentType为application/json;charset=UTF-8。


重新部署后,访问http://localhost:8080/testSpringWeb/json/y返回内容为:


{"status":"y","info":"success"}



[b]2.配置默认ResponseBody转换器[/b]


如果项目中大量使用ajax请求和json格式,并考虑以后可能更改返回格式,就不需要在每个方法中去指定视图名称,直接配置默认的ResponseBody转换器即可。


在servlet-context.xml中配置如下:


<!-- @ResponseBody -->
<bean
	class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
	<property name="messageConverters">
		<list>
			<bean
				class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
		</list>
	</property>
</bean>



使用MappingJackson2HttpMessageConverter作为默认解析器。


JsonController中新增方法如下:


@RequestMapping(value = "/n", method = { RequestMethod.GET })
	@ResponseBody
	public Map testJson(HttpServletRequest request, HttpServletResponse arg1)
			throws Exception {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("status", "n");
		map.put("info", "failure");
		return map;
	}



控制器Controller只需返回业务模型Model提供的数据map即可,视图View会自动处理。


重新部署后,访问[url]http://localhost:8080/testSpringWeb/json/n[/url]可以看到结果: 

{"status":"n","info":"failure"}



个人感觉这种方式更适合mvc三层分离的设计。



[b]3.引用静态资源[/b]


因在web.xml中配置了springmvc的servlet拦截/下所有请求,因此对静态资源的访问也会被springmvc拦截,不能直接访问。需要映射静态资源至某个地址。


在servlet-context.xml中配置如下:


<mvc:resources location="/resources/" mapping="/resources/**" />



该配置会将/resources/目录映射成/resources/**地址,因此对/resources/**的访问会直接进入web工程的/resources/目录下查找并返回。


添加jquery.js至/resources/js目录,访问[url]http://localhost:8080/testSpringWeb/resources/js/jquery.js[/url]可看到js文件内容。



[b]4.访问ajax+json[/b]


附带记录下html页面使用jquery库访问ajax并读取json数据。


在src\main\webapp目录下新建json.jsp,代码如下:


<%@ page language="java" pageEncoding="utf-8"%>
<%@ page contentType="text/html ; charset=UTF-8"%>
<html>
	<head>
		<meta http-equiv="pragma" content="no-cache">
		<meta http-equiv="cache-control" content="no-cache">
		<meta http-equiv="expires" content="0">  
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
		<script type="text/javascript" src ="resources/js/jquery.js"></script>
		<script>
			$(window).load(function(){
				$.ajax({
			        url: 'http://localhost:8080/testSpringWeb/json/y',
			        dataType: 'json'
			    }).done(function (result) {
			    	//TODO
			    	alert("done:"+result+":"+result.status);  
			    }).fail(function (result, textStatus, info) {
			    	//TODO
			    	alert("fail:"+result+":"+textStatus+":"+info);  
			    });
			})
		</script>
	</head>
	<body>
	</body>
</html>



访问后成功后进入done回调函数,弹出对话框提示:


done:[object Object]:y 

出错则进入fail回调提示: 

fail:[object Object]:error:Not Found 


[b]5.jsonp支持[/b]

如果web项目需要提供jsonp方式访问,springmvc也可以支持。


新建JsonpController类如下:


package com.sunbin.test.testSpring.web.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.stereotype.Controller;

@Controller
public class JsonpController {

	@RequestMapping(value = "/jsonp", method = { RequestMethod.GET })
	@ResponseBody
	public Object jsonp(HttpServletRequest request,
			HttpServletResponse response, String callback) throws Exception {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		map.put("status", "y");
		// 如果不存在callback这个请求参数,说明不是跨域请求,直接返回结果json
		if (callback == null || callback.length() == 0) {
			return map;
		} else {
			// 存在callback参数,则需要支持jsonp调用,并设置回调函数
			MappingJacksonValue value = new MappingJacksonValue(map);
			value.setJsonpFunction(callback);
			return value;
		}
	}
}



访问[url]http://localhost:8080/testSpringWeb/jsonp[/url]会返回json: 

{"status":"y"} 

访问[url]http://localhost:8080/testSpringWeb/jsonp?callback=yes[/url]会返回jsonp: 

yes({"status":"y"});


附带页面访问jsonp方法,新建jsonp.jsp:


<%@ page language="java" pageEncoding="utf-8"%>
<%@ page contentType="text/html ; charset=UTF-8"%>
<html>
	<head>
		<meta http-equiv="pragma" content="no-cache">
		<meta http-equiv="cache-control" content="no-cache">
		<meta http-equiv="expires" content="0">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script type="text/javascript" src="resources/js/jquery.js"></script>
		<!-- jquery方法一:不指定回调函数名,jquery随机生成 -->
		<script>
			$(window).load(function(){
				$.ajax({
			        url: 'http://127.0.0.1:8080/testSpringWeb/jsonp',
			        dataType: 'jsonp',
			        success:function (result) {
				    	//TODO
				    	alert("ajax.jsonp:"+result.status);  
				    }
			    });
			})
		</script>
		<!-- jquery方法二:指定回调函数名 -->
		<script>
			$(window).load(function(){
				$.ajax({
			        url: 'http://127.0.0.1:8080/testSpringWeb/jsonp',
			        dataType: 'jsonp',
			        jsonpCallback: 'ajaxCallback', 
			        contentType: 'application/jsonp;charset=UTF-8',
			    }).done(function (result) {
			    	//TODO
			    	alert("ajax.done:"+result.status);  
			    }).fail(function (result, textStatus, info) {
			    	//TODO
			    	alert("ajax.fail:"+result+":"+textStatus+":"+info);  
			    });
			})
		    function ajaxCallback(result) {  
		        //alert(result);  
		        for(var i in result) {  
		            alert("ajax.callback:"+i+"="+result[i]);//循环输出a:1,b:2,etc.  
		        }  
		    } 
		</script>
	</head>
	<body>
		<!-- 通过创建script标签访问   -->
		<script type="text/javascript">
		    function documentCallback(result) {  
		        //alert(result);  
		        for(var i in result) {  
		            alert("document.callback:"+i+"="+result[i]);//循环输出a:1,b:2,etc.  
		        }  
		    }  
		    var JSONP=document.createElement("script");  
		    JSONP.type="text/javascript";  
		    JSONP.src="http://localhost:8080/testSpringWeb/jsonp?callback=documentCallback";  
		    document.getElementsByTagName("head")[0].appendChild(JSONP);  
		</script>
		<!-- 通过iframe访问 -->
		<iframe
			src="javascript:'<script>function iframe(o){alert(\'iframe.callback:\'+o.status);}</script><script src=http://127.0.0.1:8080/testSpringWeb/jsonp?callback=iframe></script>'"></iframe>
	</body>
</html>



四种访问jsonp的方式:

[list] 

[*]document创建script标签,src为jsonp地址 

[*]创建iframe,src为jsonp地址 

[*]使用jquery新建ajax请求,callback为匿名函数。jquery将自动生成随机的callback名如jQuery191015429333912171872_1494838463136 

[*]使用jquery新建ajax请求,指定jsonpCallback参数 

[/list] 

访问[url]http://127.0.0.1:8080/testSpringWeb/jsonp.jsp[/url]可看到弹出提示: 

iframe.callback:y 

document.callback:status=y 

ajax.jsonp:y 

ajax.callback:status=y 

ajax.done:y