SpringMVC接受JSON參數詳解及常見錯誤總結

在SpringMVC中我們可以選擇數種接受JSON的方式,在說SpringMVC如何接受JSON之前,我們先聊聊什麼是JSON。具體的定義我也不贅述了,在JavaScript中我們經常這樣定義JSON 對象

var jsonObject = {
    "username":"admin",
    "password":123
}

這種形式的我們叫它JSON對象,同時還有一個概念叫做JSON字符串,字符串呢,顧名思義,是由’ ‘或者” “包裹起來的一個整體,我們稱之爲字符串。我們知道字符串是可以直接輸出的,而對象不能直接輸出。所以在JavaScript中,我們可以

// 定義一個對象 jsonObject
var jsonObject = {
    "username":"admin",
    "password":123
};
alert(jsonObject);

此時,會顯示[object Object]而不會輸出JSON對象的內容,JavaScript向我們提供了兩個工具

// 用於將一個 JSON 字符串轉換爲 JavaScript 對象。 
JSON.parse();
// 用於將 JavaScript 值轉換爲 JSON 字符串。
JSON.stringify();

所以當我們輸入

alert(JSON.stringify(jsonObject));

就會顯示 {“username”:”admin”,”password”:123};

好了 對於JSON的講解就到這裏了 下面我們說一說SpringMVC

既然JSON有着上述兩種存在方式,那我們通過ajax向SpringMVC傳值的時候,我們該傳哪一種呢? 
我們首先嚐試直接發送JSON對象

// 定義json對象
var username = $("#username").val();
var password = $("#password").val();
var json = {
    "username" :username,
    "password" :password
};


// Jquery Ajax請求
$.ajax({
    url :"jsontest",
	type :"POST",
	async :true,
	data :json,
	dataType :'json',
	success :function(data) {
		if (data.userstatus == = "success") {
			$("#errorMsg").remove();
		} else {
			if ($("#errorMsg").length <= 0) {
				$("form[name=loginForm]").append(errorMsg);
			}
		}
	}
});

我們首先想想SpringMVC提供了什麼給我們,有一個@RequestParam的註解,對於這個註解,它的作用和我們Servlet中的request.getParameter是基本相同的。我們首先使用這個註解來獲取

@RequestMapping("/jsontest")
public void test(@RequestParam(value = "username", required = true) String username,
                 @RequestParam(value = "password", required = true) String password) {
	System.out.println("username: " + username);
	System.out.println("password: " + password);
}

後臺成功輸出的我們的參數,成功接收! 
SpringMVC如此智能,如果我們去除@RequestParam註解,直接將兩個值放入會有什麼後果?

@RequestMapping("/jsontest")
public void test(String username, String password) {
	System.out.println("username: " + username);
	System.out.println("password: " + password);
}

竟然同樣成功了,原理我這裏就不多贅述了,有興趣的朋友們可以打斷點看看。

SpringMVC提供了一個@RequestBody,它是用來處理前臺定義發來的數據Content-Type: 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等; 
細心的朋友們或許發現了,在之前的Ajax中,我們沒有定義Content-type的類型,Jquery默認使用application/x-www-form-urlencoded類型。那麼意思就是SpringMVC的@RequestParam註解,Servlet的request.getParameter是可以接受到以這種格式傳輸的JSON對象的。

爲什麼呢!?GET請求想必大家都不陌生,它將參數以url?username=”admin”&password=123這種方式發送到服務器,並且request.getParameter可以接收到這種參數,我們在瀏覽器地址欄上也可以看到這一點。而我們Ajax使用的POST,並且發送的是JSON對象,那麼後臺是如何獲取到的呢?答案就在於這個Content-Type x-www-form-urlencoded的編碼方式把JSON數據轉換成一個字串,(username=”admin”&password=123)然後把這個字串添加到url後面,用?分割,(是不是和GET方法很像),提交方式爲POST時候,瀏覽器把數據封裝到HTTP BODY中,然後發送到服務器。所以並不會顯示在URL上。(這段可能有點繞口,希望大家用心理解一下。) 
終於說完了,長吐一口氣。所以說我們使用@RequestBody註解的時候,前臺的Content-Type必須要改爲application/json,如果沒有更改,前臺會報錯415(Unsupported Media Type)。後臺日誌就會報錯Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported,這些錯誤Eclipse下Tomcat是不會顯示錯誤信息的,只有使用了日誌纔會顯示,如何配置日誌大家可以看我上一篇文章。接下來我們正確配置一下,上面說到了 Content-Type需要更改,同時我們的data也要更改了,這種註解方式只接受JSON字符串而不是JSON對象

$.ajax({
    url:"jsontest",
    type :"POST",
    async :true,
    contentType :"application/json",
    data :JSON.stringify(json),
    dataType :'json',
    success :function(data) {
        if (data.userstatus == = "success") {
            $("#errorMsg").remove();
        } else {
            if ($("#errorMsg").length <= 0) {
                $("form[name=loginForm]").append(errorMsg);
            }
        }
    }
});

後臺也更改一下,json其實可以理解爲鍵值對嘛,所以我們用Map接收,然後對字符串或者其他數據類型進行進一步處理。

@RequestMapping("/jsontest")
public void test(@RequestBody(required = true) Map<String, Object> map) {
	String username = map.get("username").toString();
	String password = map.get("password").toString();
	System.out.println("username: " + username);
	System.out.println("password: " + password);
}

同時,我又想起了神奇的SpringMVC,所以我決定去掉註解試試,好的,果斷被爆了一個空指針錯誤…嘗試就此打住。 
SpringMVC還提供了參數直接和POJO綁定的方法,我們來嘗試一下。前臺一樣,就不貼出來了。

@RequestMapping("/jsontest")
public void test(@RequestBody User user) {
	String username = user.getUsername();
	String password = user.getPassword();
	System.out.println("username: " + username);
	System.out.println("password: " + password);
}

OK,這次是可以取到值的,我個人對於登錄這類小數據量的上傳來說不太喜歡這種方法,User裏面的變量很多,我只用了其中兩個,沒有必要去創建一個User對象,一般數據量小的時候我還是比較喜歡使用單獨取值出來的。我們再想一想,如果是在上傳JSON對象的情況下,我們可不可以綁定POJO呢,答案是可以的,不要使用@RequestParam註解,否則會報Required User parameter ‘user’ is not present錯誤。到此講解基本結束了,下面來總結一下。

注意: 
(1)當Ajax以application/x-www-form-urlencoded格式上傳即使用JSON對象,後臺需要使用@RequestParam 或者Servlet獲取。 
(2) 當Ajax以application/json格式上傳即使用JSON字符串,後臺需要使用@RquestBody獲取。

 

 

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/sanpangouba/article/details/84853104

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/sanpangouba/article/details/84853104

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/sanpangouba/article/details/84853104

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