欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring mvc(四)返回json

程序员文章站 2022-06-07 10:39:45
...
实现springmvc返回json内容。

1.指定视图类型
新增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"}

2.配置默认ResponseBody转换器
如果项目中大量使用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会自动处理。
重新部署后,访问http://localhost:8080/testSpringWeb/json/n可以看到结果:
{"status":"n","info":"failure"}
个人感觉这种方式更适合mvc三层分离的设计。

3.引用静态资源
因在web.xml中配置了springmvc的servlet拦截/下所有请求,因此对静态资源的访问也会被springmvc拦截,不能直接访问。需要映射静态资源至某个地址。
在servlet-context.xml中配置如下:
<mvc:resources location="/resources/" mapping="/resources/**" />

该配置会将/resources/目录映射成/resources/**地址,因此对/resources/**的访问会直接进入web工程的/resources/目录下查找并返回。
添加jquery.js至/resources/js目录,访问http://localhost:8080/testSpringWeb/resources/js/jquery.js可看到js文件内容。

4.访问ajax+json
附带记录下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

5.jsonp支持
如果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;
		}
	}
}

访问http://localhost:8080/testSpringWeb/jsonp会返回json:
{"status":"y"}
访问http://localhost:8080/testSpringWeb/jsonp?callback=yes会返回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的方式:
  • document创建script标签,src为jsonp地址
  • 创建iframe,src为jsonp地址
  • 使用jquery新建ajax请求,callback为匿名函数。jquery将自动生成随机的callback名如jQuery191015429333912171872_1494838463136
  • 使用jquery新建ajax请求,指定jsonpCallback参数

访问http://127.0.0.1:8080/testSpringWeb/jsonp.jsp可看到弹出提示:
iframe.callback:y
document.callback:status=y
ajax.jsonp:y
ajax.callback:status=y
ajax.done:y