Spring 4.1+JSONP的使用指南
什么是JSONP
JSONP(JSON with padding)是一种跨域数据访问的解决方案。在同源策略限制下,浏览器无法直接访问不同域下的服务器资源,但是可以通过<script>
标签加载资源,因此JSONP的实现原理就是通过在URL后加入一个回调函数名,返回值作为函数的参数,被包裹在函数调用中,从而在客户端得到调用。这种跨域方式只支持GET请求,因为<script>
标签只能发出GET请求。
Spring 4.1中的JSONP支持
Spring 4.1中引入了JSONP支持,可以通过MappingJackson2JsonView
实现。具体来说,我们可以继承MappingJackson2JsonView
,重写renderMergedOutputModel
方法,在返回值前加上回调函数名即可。
以下是一个示例代码:
public class JsonpView extends MappingJackson2JsonView {
@Override
public void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (model.containsKey("callback")) {
response.setContentType("application/javascript");
String callback = (String) model.get("callback");
OutputStream outputStream = response.getOutputStream();
String jsonString = objectMapper.writeValueAsString(model.get("data"));
String jsonpString = callback + "(" + jsonString + ");";
outputStream.write(jsonpString.getBytes());
outputStream.flush();
outputStream.close();
} else {
super.renderMergedOutputModel(model, request, response);
}
}
}
该类继承了MappingJackson2JsonView
,判断请求参数中是否有callback
,如果有,则将返回结果加上回调函数名并返回;否则按照原来的方式返回。
示例说明
1. 使用JSONP获取显示当前时间
例如现在我们需要获取另一台服务器上的时间,可以使用以下方式:
- 在另一台服务器上添加一个接口,返回当前时间(以JSON格式返回)
- 在我们的网站中使用
<script>
标签加载该接口,并指定回调函数名 - 在页面中定义该回调函数,得到返回数据
具体而言,假设另一台服务器上的接口为http://other-server/getTime
,返回格式为{"time": "2021-01-01 00:00:00"}
,我们可以这样编写HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP示例</title>
</head>
<body>
<h1 id="time"></h1>
<script type="text/javascript">
function handleTime(data) {
var time = data.time;
var element = document.getElementById("time");
element.innerHTML = time;
}
var script = document.createElement("script");
script.src = "http://other-server/getTime?callback=handleTime";
document.body.appendChild(script);
</script>
</body>
</html>
该页面会加载http://other-server/getTime?callback=handleTime
,并在页面中定义一个名为handleTime
的回调函数,当接口返回数据时,该回调函数会被自动调用,并将返回值作为参数传入。我们可以在回调函数中处理返回值并显示在页面上。
2. 在Spring MVC中使用JSONP
在Spring MVC中,我们可以通过自定义View
实现JSONP的支持。以下是一个示例代码:
@Controller
public class JsonpController {
@RequestMapping("/getData")
public ModelAndView getData(@RequestParam("callback") String callback) {
List<String> list = new ArrayList<>();
list.add("data1");
list.add("data2");
list.add("data3");
ModelAndView modelAndView = new ModelAndView(new JsonpView());
modelAndView.addObject("callback", callback);
modelAndView.addObject("data", list);
return modelAndView;
}
}
该控制器中定义了一个getData
方法,接收一个callback
参数,并返回一个包含数据的ModelAndView
,其中使用了自定义的JsonpView
来实现JSONP的支持。在返回结果前,JsonpView
会根据请求的callback
参数将结果包装成JSONP格式。
在页面中,我们可以使用以下方式来调用该接口:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP示例</title>
</head>
<body>
<h1 id="data"></h1>
<script type="text/javascript">
function handleData(data) {
var string = data.join(", ");
var element = document.getElementById("data");
element.innerHTML = string;
}
var script = document.createElement("script");
script.src = "/getData?callback=handleData";
document.body.appendChild(script);
</script>
</body>
</html>
该页面会向URL/getData?callback=handleData
发起GET请求,并在接收到返回数据后,将数据显示在页面上。
总结
本文介绍了Spring 4.1中JSONP的实现原理和使用方法,并提供了两个示例说明。希望能对大家理解JSONP和Spring MVC有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring 4.1+JSONP的使用指南 - Python技术站