实现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