SpringMVC 傳遞參數過程當中 RquestBody,RequestParam 區別

最近面試遇到問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獲取

相關文章
相關標籤/搜索