SpringMVC中JSONP的基本使用

本文介绍如何在SpringMVC中使用JSONP解决跨域问题。通过改造Ajax请求和控制器方法,使用JSONPObject和MappingJacksonValue简化开发流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言
在第一次写博文的时候,写的是JSONP的基本原理,因为是第一次写可能有些不足。这一篇博文是简单的介绍在SpringMVC中JSONP的基本使用。(要是有不足,请各位指出,(~ ̄▽ ̄)~)。

1、回顾

1.1、当遇到跨域请求的时候,也就是以下错误的时候,怎么解决:

XMLHttpRequest cannot load http://www.a.com/foo. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://www.b.com’ is therefore not allowed access. 

1.2、只要简单的两步就可以解决跨域问题:
1.2.1、对原有的Ajax(就是产生跨域的Ajax)的进行改造,主要是将dataType 设置为jsonp:

$.ajax({
    url : "http://www.a.com/foo",
    type : "GET",
    dataType : "jsonp", //只要将dataType设置为jsonp即可,其他的参数设置不需要修改
    success : function(data){
        alert(data.name);
    }
});

1.2.2、Controller中的方法的改造:

@RequestMapping(value = "foo", method = RequestMethod.GET)
@ResponseBody
public String foo(String callback) {
    try {
        // 构造返回的数据data
        Map<String, String> data = new HashMap<String, String>();
        data.put("name", "LinHenk");
        // 将data对象序列化为JSON对象,此处使用的是jackson中提供的ObjectMapper将data对象序列化为JSON对象
        String json = objectMapper.writeValueAsString(data);
        // 判断请求是否是josnp请求
        if (StringUtils.isNotBlank(callback)) {
            // jsonp请求,使用字符串拼接的方式,生成一段js脚本片段
            return callback + "(" + json + ");";
        }
        // 非jsonp请求
        return json;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

2、代码改善

2.1、跨域问题是解决了,但是代码看起来不怎么好,看以下代码:

return callbackName + "(" + json + ");"

以上代码,使用了字符串拼接,看起来不怎么好,而且在字符串拼接时也可能写错,可能写少了个括号什么的(PS:个人认为这样的字符串拼接,更容易让初学者理解ヾ(o◕∀◕)ノヾ)。

2.2、使用JSONPObject进行代码改善
JSONPObject该类是jackson提供的(com.fasterxml.jackson.databind.util.JSONPObject),该类使用起来也是相当的简单,请看代码:

@RequestMapping(value = "foo", method = RequestMethod.GET)
@ResponseBody
public Object foo(String callback) {
    try {
        // 构造返回的数据data
        Map<String, String> data = new HashMap<String, String>();
        data.put("name", "LinHenk");
        // 判断请求是否是josnp请求
        if (StringUtils.isNotBlank(callback)) {
            // jsonp请求
            //参数一(String类型):回调函数名,参数二(Object类型):需要返回的数据
            JSONPObject jsonpObject = new JSONPObject(callback, data);
            return jsonpObject;
        }
        // 非jsonp请求
        return data;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

说说为什么要使用JSONPObject来进行数据返回吧,个人的理解比较浅显,主要由以下两点:
1、避免了字符串拼接问题,防止拼接过程中出错。
2、当返回的数据含有中文时,不需要手动指定Content-Type:application/json;charset=UTF-8 。PS:使用字符串拼接的方式,如果返回的数据包含中文,需要使用@RequestMapping,通过produces进行指定Content-Typeapplication/json;charset=UTF-8(否则会出现乱码),如下代码:

@RequestMapping(produces=MediaType.APPLICATION_JSON_VALUE+";charset=UTF-8")

其实我主要想说的是,使用JSONPObject会简化我们的开发,提高开发效率

2.3、使用MappingJacksonValue进行代码改善
MappingJacksonValue是Spring4.1及以上版本所提供的类,看下图:
这里写图片描述

MappingJacksonValue使用起来和JSONPObject一样的简单,如下代码:

@RequestMapping(value = "foo", method = RequestMethod.GET)
@ResponseBody
public Object foo(String callback) {
    try {
        // 构造返回的数据data
        Map<String, String> data = new HashMap<String, String>();
        data.put("name", "LinHenk");
        // 判断请求是否是josnp请求
        if (StringUtils.isNotBlank(callback)) {
            // jsonp请求
            MappingJacksonValue jacksonValue = new MappingJacksonValue(data);
            jacksonValue.setJsonpFunction(callback);
            return jacksonValue;
        }
        // 非jsonp请求
        return data;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

再次提醒,MappingJacksonValue需要在Spring4.1及以上的版本才能使用。

3、小小的小结

使用JSONPObject和MappingJacksonValue都可以使得我们在遇到JSONP跨域请求的时候,开发相对简便,但是要使用这两个类都需要满足相应的条件
1、使用JSONPObject,需要添加jackson的相关依赖
2、使用MappingJacksonValue,需要在Spring4.1及以上版本才能使用(并且也需要jackson的相关依赖)
本文中主要讲解的是SpringMVC中JSONP的基本使用,还有其他的基本使用方式,也希望可以留言告诉我!为什么强调基本,因为除了以上两个比较基本的解决方法(我所接触过的比较简单的方法),其实也可以通过自定义MessageConverter来实现,但是感觉对SpringMVC使用不是很了解的朋友来说,使用该种方法,相对来说会比较有难度一点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值