SpringMVC中JSONP的基本使用

前言
在第一次寫博文的時候,寫的是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使用不是很瞭解的朋友來說,使用該種方法,相對來說會比較有難度一點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章