Jquery JSONP问题
作为学习JSONP的一部分,我将进行如下ajax调用:Jquery JSONP问题,jquery,json,spring,jsonp,Jquery,Json,Spring,Jsonp,作为学习JSONP的一部分,我将进行如下ajax调用: var jsonp_url = "http://localhost:8080/test/ad"; $.getJSON(jsonp_url, function(data) { $('#example-widget-container').html(data.html); }); 当我点击时,它返回: ? ( {'html': '<strong>Hello World!</strong>' } ) ?({'ht
var jsonp_url = "http://localhost:8080/test/ad";
$.getJSON(jsonp_url, function(data) {
$('#example-widget-container').html(data.html);
});
当我点击时,它返回:
? ( {'html': '<strong>Hello World!</strong>' } )
?({'html':'你好,世界!'})
返回此消息的Spring代码为:
@RequestMapping(method = RequestMethod.GET, value = "ad")
public void getAd(HttpServletResponse response){
PrintWriter out = null;
response.setContentType("text/javascript");
try {
out = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
out.write("? ( {'html': '<strong>Hello World!</strong>' } )");
}
@RequestMapping(method=RequestMethod.GET,value=“ad”)
public void getAd(HttpServletResponse){
PrintWriter out=null;
setContentType(“text/javascript”);
试一试{
out=response.getWriter();
}捕获(IOE异常){
e、 printStackTrace();
}
out.write(“({'html':'你好,世界!'}”);
}
在执行中,我期待你好,世界将显示在
中,但不会显示,因为回调没有发生
我遗漏了什么?难道你不想
返回“{'html':'hello world'”代码>?您是否只想返回“{'html':'hello world'}”代码>?callme函数在做什么?如果您返回“callme({'html':'helloworld'})”;那么在你的js代码中,警报将不会警报“Hellow world”。您需要data(),即运行callme函数callme函数在做什么?如果您返回“callme({'html':'helloworld'})”;那么在你的js代码中,警报将不会警报“Hellow world”。您需要有data(),即运行callme函数$。getJSON除了正确的JSON fomat和callme({'html':'hello world')不是JSON格式之外
正确的json格式是
{'html':'hello world'}$。除了正确的JSON fomat和callme({'html':'hello world'})之外,getJSON不是JSON格式
正确的json格式是
{'html':'helloworld'}如果返回JSONP,请不要获取JSON。。。试试这个
$.get("http://localhost:8080/test/ad", function(data) {
alert(data.html);
}, 'jsonp');
如果返回JSONP,请不要获取JSON。。。试试这个
$.get("http://localhost:8080/test/ad", function(data) {
alert(data.html);
}, 'jsonp');
我发现很多人对JSONP和JSON感到困惑。所以我分享我发现正确的答案:
爪哇
我发现很多人对JSONP和JSON感到困惑。所以我分享我发现正确的答案:
爪哇
使用Spring3.0及更高版本实际上非常容易。但是,在查看上面的示例时,我很困惑,为什么您将spring控制器视为一个普通的servlet,并直接打印到响应流。这应该避免。您最好只返回一个表示JSON数组的POJO,并让JSON解析器创建响应
第一个任务是让Spring返回JSON。通过将@ResponseBody添加到控制器,告诉控制器将POJO序列化到客户端,可以很容易地处理这个问题。如果类路径中有Jackson,则会使用MappingJacksonHttpMessageConverter自动将其作为JSON发送,该转换器使用mvc:annotation-driven启用
但JSON还不够。您需要JSON-P,假设客户端希望在跨域场景中使用JSON。这可以通过多种不同的方式实现。您可以使用Spring的DelegatingFilterProxy实现servlet过滤器。过滤器可以确定是否正在请求JSON-P,您可以相应地调整响应
因此,对于我的使用,我更喜欢扩展Spring3.0(+)MappingJacksonJsonView,而不是一个过滤器,并检查请求参数是否包含一个“callback”键。如果需要JSON或JSONP,我可以简单地向*.JSONP添加第二个servlet映射,并根据回调参数的存在发送JSON或JSONP
代码如下:
将以下内容放入控制器中:
@RequestMapping(value="/ad", method=RequestMethod.GET)
public ModelMap getAvailabilityModel(@RequestParam(required = false) String callback) {
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("html", "<strong>Hello World!</strong>");
return modelMap;
}
@RequestMapping(value=“/ad”,method=RequestMethod.GET)
公共模型映射getAvailabilityModel(@RequestParam(required=false)字符串回调){
ModelMap ModelMap=newmodelmap();
addAttribute(“html”,“你好,世界!”;
返回模型图;
}
返回ModelMap甚至ModelAndView允许我基于servlet映射执行不同的操作
以下是处理JSON-p扩展的自定义视图(仅限guts,为简洁起见,省略了一些覆盖):
公共类MappingJacksonJsonpView扩展了MappingJacksonJsonView{
@凌驾
公共void呈现(映射模型、HttpServletRequest请求、HttpServletResponse响应)引发异常{
if(“GET”.equals(request.getMethod().toUpperCase())){
Map params=request.getParameterMap();
if(参数containsKey(“回调”)){
字符串callbackName=params.get(“回调”)[0];
response.getOutputStream().write(新字符串(callbackName+“(”).getBytes());
info(“为.jsonp方法找到了GETTER,回调名称为:”+callbackName);
super.render(模型、请求、响应);
response.getOutputStream().write(新字符串(“);”).getBytes();
setContentType(“应用程序/javascript”);
}
否则{
super.render(模型、请求、响应);
}
}
否则{
super.render(模型、请求、响应);
}
}
}
如果请求被映射到*.jsonp,并且我看到一个带有“callback”键的请求参数,那么我假设为JSON-p,并将带有回调信息的JSON包装在响应流的顶部。我将让Jackson JSON处理器在所有情况下处理将POJO转换为正确JSON的细节。在我的控制器中,我只返回POJO或ModelMap;不要在响应中乱写我自己的JSON。或者,我可以使用模型和视图作为返回类型。这将允许正确处理*.do vs*.json请求。使用Firebug确保在响应头中获得正确的媒体类型,application/json表示json,application/javascript表示json-P
下面是JSON-p的输出,带有一个GET-on(注意带有xyz的包装器,用于JQuery?)
xyz({“html”:“你好,世界!”});
如果不使用Request参数,它只会返回JSON:
{“html”:“你好,世界!”}
最后,确保正确连接新视图:
<!-- Add our new View to the Application Context -->
<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<beans:property name="order" value="1" />
<beans:property name="favorPathExtension" value="true"/>
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="json" value="application/json"/>
<beans:entry key="jsonp" value="application/javascript"/>
</beans:map>
</beans:property>
<beans:property name="defaultViews">
<beans:list>
<beans:bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
<beans:bean class="com.yourpackagename.spring.web.servlet.view.jsonp.MappingJacksonJsonpView"/>
</beans:list>
</beans:property>
</beans:bean>
public class MappingJacksonJsonpView extends MappingJacksonJsonView {
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if("GET".equals(request.getMethod().toUpperCase())) {
Map<String, String[]> params = request.getParameterMap();
if(params.containsKey("callback")) {
String callbackName = params.get("callback")[0];
response.getOutputStream().write(new String(callbackName + "(").getBytes());
log.info("GETTER Found for a .jsonp method, callback name is : " + callbackName);
super.render(model, request, response);
response.getOutputStream().write(new String(");").getBytes());
response.setContentType("application/javascript");
}
else {
super.render(model, request, response);
}
}
else {
super.render(model, request, response);
}
}
}
xyz({"html":"<strong>Hello World!</strong>"});
{"html":"<strong>Hello World!</strong>"}
<!-- Add our new View to the Application Context -->
<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<beans:property name="order" value="1" />
<beans:property name="favorPathExtension" value="true"/>
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="json" value="application/json"/>
<beans:entry key="jsonp" value="application/javascript"/>
</beans:map>
</beans:property>
<beans:property name="defaultViews">
<beans:list>
<beans:bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
<beans:bean class="com.yourpackagename.spring.web.servlet.view.jsonp.MappingJacksonJsonpView"/>
</beans:list>
</beans:property>
</beans:bean>