最近面試遇到問springmvc傳遞參數相關的問題,在網上看到一篇解釋比較詳細的博客,原文連接:https://blog.csdn.net/LostSh/article/details/68923874。面試
這裏copy記錄一下,方便本身之後回顧。ajax
在SpringMVC
中咱們能夠選擇數種接受JSON
的方式,在說SpringMVC
如何接受JSON
以前,咱們先聊聊什麼是JSON
。具體的定義我也不贅述了,在JavaScript
中咱們常常這樣定義JSON
對象。spring
var jsonObject = { "username":"admin", "password":123 }json
這種形式的咱們叫它JSON對象,同時還有一個概念叫作JSON字符串,字符串呢,顧名思義,是由’ ‘或者」 「包裹起來的一個總體,咱們稱之爲字符串。咱們知道字符串是能夠直接輸出的,而對象不能直接輸出。因此在JavaScript中,咱們能夠瀏覽器
//定義一個對象 jsonObjectvar jsonObject = { "username":"admin", "password":123 }; alert(jsonObject);服務器
此時,會顯示[object Object]而不會輸出JSON對象的內容,JavaScript向咱們提供了兩個工具mvc
JSON.parse()
用於將一個 JSON 字符串轉換爲 JavaScript 對象。
JSON.stringify()
用於將 JavaScript 值轉換爲 JSON 字符串。app
因此當咱們輸入async
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錯誤。到此講解基本結束了,下面來總結一下。
當Ajax以application/x-www-form-urlencoded格式上傳即便用JSON對象,後臺須要使用@RequestParam 或者Servlet獲取。 當Ajax以application/json格式上傳即便用JSON字符串,後臺須要使用@RquestBody獲取