1. 程式人生 > >java之@RequestBody的使用

java之@RequestBody的使用

基礎知識介紹:

        @RequestBody主要用來接收前端傳遞給後端的json字串中的資料的(請求體中的資料的);GET方式無請求體,所以使用@RequestBody接收資料時,前端不能使用GET方式提交資料,而是用POST方式進行提交。在後端的同一個接收方法裡,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多隻能有一個,而@RequestParam()可以有多個。

注:一個請求,只有一個RequestBody;一個請求,可以有多個RequestParam。

注:當同時使用@RequestParam()和@RequestBody時,@RequestParam()指定的引數可以是普通元素、
       陣列、集合、物件等等(即:當,@RequestBody 與@RequestParam()可以同時使用時,原SpringMVC接收
       引數的機制不變,只不過RequestBody 接收的是請求體裡面的資料;而RequestParam接收的是key-value
       裡面的引數,所以它會被切面進行處理從而可以用普通元素、陣列、集合、物件等接收)。
       即:如果引數時放在請求體中,傳入後臺的話,那麼後臺要用@RequestBody才能接收到;如果不是放在
              請求體中的話,那麼後臺接收前臺傳過來的引數時,要用@RequestParam來接收,或則形參前
              什麼也不寫也能接收。

注:如果引數前寫了@RequestParam(xxx),那麼前端必須有對應的xxx名字才行(不管其是否有值,當然可以通
       過設定該註解的required屬性來調節是否必須傳),如果沒有xxx名的話,那麼請求會出錯,報400。

注:如果引數前不寫@RequestParam(xxx)的話,那麼就前端可以有可以沒有對應的xxx名字才行,如果有xxx名
       的話,那麼就會自動匹配;沒有的話,請求也能正確傳送。
       追注:這裡與feign消費服務時不同;feign消費服務時,如果引數前什麼也不寫,那麼會被預設是
                  @RequestBody的。

如果後端引數是一個物件,且該引數前是以@RequestBody修飾的,那麼前端傳遞json引數時,必須滿足以下要求:

    後端@RequestBody註解對應的類在將HTTP的輸入流(含請求體)裝配到目標類(即:@RequestBody後面的類)時,會根據json字串中的key來匹配對應實體類的屬性,如果匹配一致且json中的該key對應的值符合(或可轉換為),這一條我會在下面詳細分析,其他的都可簡單略過,但是本文末的核心邏輯程式碼以及幾個結論一定要看! 實體類的對應屬性的型別要求時,會呼叫實體類的setter方法將值賦給該屬性。

    json字串中,如果value為""的話,後端對應屬性如果是String型別的,那麼接受到的就是"",如果是後端屬性的型別是Integer、Double等型別,那麼接收到的就是null。

    json字串中,如果value為null的話,後端對應收到的就是null。

    如果某個引數沒有value的話,在傳json字串給後端時,要麼乾脆就不把該欄位寫到json字串中;要麼寫value時, 必須有值,null  或""都行。千萬不能有類似"stature":,這樣的寫法,如:

示例詳細說明

先給出兩個等下要用到的實體類

User實體類:

Team實體類:

@RequestBody直接以String接收前端傳過來的json資料:

後端對應的Controller:

使用PostMan測試:

@RequestBody以簡單物件接收前端傳過來的json資料:

後端對應的Controller:

使用PostMan測試:

@RequestBody以複雜物件接收前端傳過來的json資料:

後端對應的Controller:

使用PostMan測試:

@RequestBody與簡單的@RequestParam()同時使用

後端對應的Controller:

使用PostMan測試:

@RequestBody與複雜的@RequestParam()同時使用

後端對應的Controller:

使用PostMan測試:

@RequestBody接收請求體中的json資料;不加註解接收URL中的資料並組裝為物件

後端對應的Controller:

使用PostMan測試:

注:如果在後端方法引數前,指定了@RequestParam()的話,那麼前端必須要有對應欄位才行(當然可以通過設定
       該註解的required屬性來調節是否必須傳),否者會報錯;如果引數前沒有任何該註解,那麼前端可以傳,也可
       以不傳,如:

上圖中,如果我們傳參中沒有指定token,那麼請求能正常進去,但是token為null;如果在String token前指定了@RequestParam(“token”),那麼前端必須要有token這個鍵時,請求才能正常進去,否者報400錯誤。
 

@RequestBody與前端傳過來的json資料的匹配規則

宣告:根據不同的Content-Type等情況,Spring-MVC會採取不同的HttpMessageConverter實現來進行資訊轉換解析。
          下面介紹的是最常用的:前端以Content-Type 為application/json,傳遞json字串資料;後端以@RequestBody
          模型接收資料的情況。

解析json資料大體流程概述:
        Http傳遞請求體資訊,最終會被封裝進com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring採用CharacterEncodingFilter設定了預設編碼為UTF-8),然後在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通過 public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException方法進行解析。
核心邏輯分析示例:

        假設前端傳的json串是這樣的: {"name1":"鄧沙利文","age":123,"mot":"我是一隻小小小小鳥~"} 後端的模型只有name和age屬性,以及對應的setter/getter方法;給出一般用到的deserializeFromObject(JsonParser p, DeserializationContext ctxt)方法的核心邏輯:

 

小技巧之指定模型中的屬性對應什麼key

這裡簡單介紹,更多的可參考:

           public class BeanPropertyMap implements Iterable<SettableBeanProperty>,java.io.Serializable

給出Controller中的測試類:

給出模型中的屬性(setter/getter方法沒截出來):

 

使用postman測試一下,示例:

相關推薦

java@RequestBody的使用

基礎知識介紹:         @RequestBody主

java對數組排序

ner out mce 冒泡 can scan arr tin r語 一、在運行時輸入數組 import java.util.*; //也可以寫成 import java.util.Scanner; public class px { public static vo

Java路 ——初識Eclipse

cti 文章 啟動 eve 技術分享 win 恢復 高手 復制 零、大綱 一、前言 二、獲取Eclipse 三、運行Eclipse 四、創建及運行第一個Java Project 五、界面介紹 六、如何調試 七、獲取插件 八、Eclipse 快捷鍵 九、總結

javalist源代碼淺析

target lec http 失效 頭節點 就會 ide ctc linked 三大數據結構鏈表、樹和圖,順序表作為當中的一種,能夠說是平時編程中最長使用到的。List接口是順序表在java中的實現。它有非常多子接口和實現類,平時的編程中使用起來非常方便。可是更進一步

Java

-m learn java語言 方便 font style scu 同學 together 省賽結束之後有相當長一段空閑時間,於是就想先提前自學一點Java語言的知識,在這裏紀錄一下學習過程,希望能給自學Java的同學提供一點小幫助!(當然,也能方便我以後的復習用^_^)

Java 變量和常量

family 三種 進行 字符 hello 是個 用途 習慣 起名字 Java中的關鍵字: Java 語言中有一些具有特殊用途的詞被稱為關鍵字。關鍵字對 Java 的編譯器有著特殊的意義,在程序中應用時一定要慎重哦!! Java 中常用關鍵字: 問:這麽多,記不住

Java 常用運算符(3)

註意 sys 有趣的 open size 除法 如果能 都是 pla 什麽是運算符: 運算符是一種“功能”符號,用以通知 Java 進行相關的運算。譬如,我們需要將變量 age 的值設置為 20 ,這時候就需要一個“=”,告

JavaHashtable、HashMap及Properties

們的 行為 重新 用途 values lan 很大的 輕量 實現 HashTable繼承於比較古老的Dictionary,而HashMap是接口Map的實現。 HashMap是HashTable的一個輕量級實現,HashMap不是線程安全的,而HashTable是線程

四:Java字符串操作String、StringBuffer和StringBuilder

equal const wstring str asi 有時 string對象 階段 stringbu string是我們經經常使用到的一個類型,事實上有時候認為敲代碼就是在重復的操作字符串,這是C的特點,在java中。jdk非常好的封裝了關於字符串的操

Java創建對象>5.Avoid creating unnecessary objects

alloc spa color win set 根據 優化 ava 生日 String s = new String("stringette"); // DON‘T DO THIS! The improved version is simply the followin

happy in javaio流簡介

ack 封裝 16px bsp strong 一個 硬盤 其他 file 閑來沒事,重溫馬士兵老師的java基礎。。。 流 水流的流 流氓的流,,流 英文叫做stream,溪流 流的分類: 流是用來讀寫數據的。 流就像水流一樣,File類封裝

JAVAJDBC的簡單使用(Mysql)

nag cep 發現 jdb box 分享 .get 不知道 今天 JDBC增刪查改 昨天七七八八的關於Mysql的配置 和 基本使用也算是初步解決了,今天 抽空看了JAVA的JDBC(JAVA DATA BASE CONNECTION)我也不知道我全稱拼寫對對不對??

javaURL(URL,URLConnection)實例

div port stream file http exce getproto local rep import org.junit.Test; public class TestURL { @Test public void readUrl() throws

JavaIO(五)文件系統

系統 選擇 shutdown img lap roo files -1 parent   轉載請註明源出處:http://www.cnblogs.com/lighten/p/6992043.html 1.前言   在講解Java的文件流之前,先來認識一下Java的文件系統的

java真假分頁

分頁 真假 .com 至少 ref lec from kdt baidu 真分頁(要的是什麽範圍的記錄在數據庫查的時候就只查這幾條記錄):select s.* from (select *,row_number() over(order by SLoginId) as ro

javaIO整理(中)

getparent create olt highlight print enc buffered byte package 一:打印流/*System.out.println()重定向輸出*/ /*public static void main(String[] ar

Java基本類庫學習

decimal ren 常量池 blog 新建 random類 使用 ring org  JAVA基本類庫:   (一),輸入相關     main(String[] args):設置輸入參數     輸入類;Scanner:Scanner sc=new Scanner(S

JavaIO(八)PipedIutputStream和PipedOutputStream

gin lose 讀取數據 interrupt src link fin 字節 zed   轉載請註明源出處:http://www.cnblogs.com/lighten/p/7056278.html 1.前言   本章介紹Java的IO體系中最後一對字節流--管道流。之前

JavaIO(九)其它字節流

character play har array 文件中 output 技術分享 com 允許   轉載請註明源出處:http://www.cnblogs.com/lighten/p/7063161.html 1.前言   之前的章節已經介紹了java的io包中所有成對(輸

JavaIO(十)Reader和Writer

puts app 使用 [] 前言 left t對象 log pen   轉載請註明源出處:http://www.cnblogs.com/lighten/p/7071733.html 1.前言   之前的章節已經將Java8的io包中的字節流介紹完畢了。本章開始介紹Jav