一篇解決springMVC前後端參數傳遞問題

一、先來看一個常見的異常

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

 前端代碼:

  $.ajax({
        type:"post",
        url:"/test",
        data:JSON.stringify({id:1,name:"小明",gender:true}),
        success:function (result) {
            console.log(result);
        }
    });

後端代碼:

    @ResponseBody
    @RequestMapping("/test")
    public Object testJson(@RequestBody User user){
        System.out.println(user);
        return user;
    }

前後端用json字符串做數據交互。一運行就報了上面的異常了。

先說一下解決方法:

ajax中加上一個鍵值對:contentType:"application/json" 就行了。

原因:前端用 JSON.stringify({id:1,name:"小明",gender:true}) 將一個js對象轉換成了json字符串,後端通過@RequestBody註解表示要解析json字符串(相當於fastJson來解析json字符串)並賦值給User對象,我們發送的是http請求,後端在解析請求參數時並不是直接解析內容,若是post請求的話,他會先檢查HTTP請求的Content-type屬性值,根據這個屬性值來判斷請求體中的數據格式。前端我們發的ajax請求默認的contentType屬性值爲:application/x-www-form-urlencoded;charset=UTF-8,這個contentType表示的數據格式是鍵值對格式。所以我後端需要json格式的數據,你給我傳遞個鍵值對格式,我肯定說不支持啊。

所以我們用contentType:"application/json"來改變http請求,表示我發送的數據是json格式的,後端就可以識別了唄。

二、深入研究一下,從根本上解決這個參數傳遞問題

1、請求的數據格式的區別

  1. 因爲content-Type是用來表示請求體的類型的,默認值爲默認爲application/x-www-form-urlencoded; charset=UTF-8,這個稱爲MIME類型。get請求沒有請求體,所以就沒有content-Type屬性;post請求有請求體,所以就會有content-Type屬性。
  2. form表單的默認MIME類型也是application/x-www-form-urlencoded,即enctype="application/x-www-form-urlencoded",如果是文件上傳則enctype="multipart/form-data"
  3. 鍵值對格式:name=www&url=www&checked=true&pId=6

              常見場景

                  1)form表單默認MIME類型時

                  2)serialize()方法

                  3)ajax中的js對象(根據ajax文檔顯示,最終js對象在發送時會被轉化成鍵值對格式)

                  4)get請求

                  5)FormData對象

 

     4.Json格式:{"name":"www","url":"www","checked":true,"pId":6}

       data:JSON.stringify({name:name,url:url,checked:checked,pId:pId}), //將js對象轉換成json字符串格式

       contentType:"application/json" //設置請求的MIME類型爲application/json格式,即json格式

     5.請求體的區別:Form data 和Request Payload

         1、當post請求的content-Type屬性的值爲application/x-www-form-urlencoded; charset=UTF-8時,數據封裝在Form data中,鍵值對格式

         2、當post請求的content-Type屬性的值爲application/json或text/plain時,數據封裝在Request Payload中,json格式

2、獲取請求參數(總結一下)

      鍵值對格式

           1、只要保證請求的參數名和處理器方法的形參名稱一致,自動綁定成功。

           2、獲取單個請求參數

                     1)@RequestParam註解:獲取一個請求參數,並賦值給一個形參

屬性

@RequestParam(value="password",required=false,defaultValue="0") int password

required:設置屬性是否爲必須的,默認爲true。可以設置其值爲false,即當沒有該屬性時也不會報錯。

defaultValue:當required=false時使用,設置請求參數的默認值,不能單獨使用。

                     2)@PathVariable 註解:針對rest風格的url,可以將url的佔位符參數,綁定到處理器方法的入參處

<a href="/springmvc/testPathvariable/12/tom">testPathvariable</a>

@RequestMapping("/testPathvariable/{id}/{name}")

public String testPathVariable(@PathVariable("id") Integer id,@PathVariable("name") String name) {

    System.out.println(id);

    return "success";

}

                     3)@RequestHeader註解:獲取請求頭中的參數。

 

如:@RequestHeader(value="Accept-Language") 這是獲取請求頭中Accept-Language屬性的值。

                     4)@CookieValue註解:獲取cookie中某個鍵值對的值。

@CookieValue("JSESSIONID")獲取JSESSIONID屬性的值。

            3、獲取多個請求參數

     使用POJO(普通的Java類)作爲參數:按照請求參數名(name屬性名)和POJO屬性名進行自動匹配,自動通過setter方法爲該對象填充屬性值,且支持級聯屬性

       json格式

     1.@RequestBody User user(推薦)

             用實體類接收,json的key要和實體類屬性一致。

     2.@RequestBody Map<String,Object> map(次推薦)

             用map接收,json的key要和map的key一致

     3.@RequestBody String str (這樣是將整個json字符串賦值給str,不推薦)

             用字符串接收,然後在自己解析json字符串

 

 

 

ok,結束,喫飯去。

 

 

 

 

 

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