Jquery JSONP问题

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

作为学习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>' } )
?({'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>