最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

@RequestBody注解的原理及使用技巧分享

 更新時間:2022年10月31日 14:26:06   作者:KAITUOZHEMJ  
這篇文章主要介紹了@RequestBody注解的原理及使用技巧分享,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

本文是基于SpringBoot,進(jìn)行的演示說明。

基礎(chǔ)知識介紹

@RequestBody主要用來接收前端傳遞給后端的json字符串中的數(shù)據(jù)的(請求體中的數(shù)據(jù)的);GET方式無請求體,所以使用@RequestBody接收數(shù)據(jù)時,前端不能使用GET方式提交數(shù)據(jù),而是用POST方式進(jìn)行提交。

在后端的同一個接收方法里,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多只能有一個,而@RequestParam()可以有多個。

  • 注:一個請求,只有一個RequestBody;一個請求,可以有多個RequestParam。
  • 注:當(dāng)同時使用@RequestParam()和@RequestBody時,@RequestParam()指定的參數(shù)可以是普通元素、數(shù)組、集合、對象等等(即:當(dāng),@RequestBody 與@RequestParam()可以同時使用時,原SpringMVC接收參數(shù)的機制不變,只不過RequestBody 接收的是請求體里面的數(shù)據(jù);而RequestParam接收的是key-value里面的參數(shù),所以它會被切面進(jìn)行處理從而可以用普通元素、數(shù)組、集合、對象等接收)。即:如果參數(shù)時放在請求體中,傳入后臺的話,那么后臺要用@RequestBody才能接收到;如果不是放在請求體中的話,那么后臺接收前臺傳過來的參數(shù)時,要用@RequestParam來接收,或則形參前什么也不寫也能接收。
  • 注:如果參數(shù)前寫了@RequestParam(xxx),那么前端必須有對應(yīng)的xxx名字才行(不管其是否有值,當(dāng)然可以通過設(shè)置該注解的required屬性來調(diào)節(jié)是否必須傳),如果沒有xxx名的話,那么請求會出錯,報400。
  • 注:如果參數(shù)前不寫@RequestParam(xxx)的話,那么就前端可以有可以沒有對應(yīng)的xxx名字才行,如果有xxx名的話,那么就會自動匹配;沒有的話,請求也能正確發(fā)送。追注:這里與feign消費服務(wù)時不同;feign消費服務(wù)時,如果參數(shù)前什么也不寫,那么會被默認(rèn)是@RequestBody的。

如果后端參數(shù)是一個對象,且該參數(shù)前是以@RequestBody修飾的,那么前端傳遞json參數(shù)時

必須滿足以下要求:

  • 后端@RequestBody注解對應(yīng)的類在將HTTP的輸入流(含請求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時,會根據(jù)json字符串中的key來匹配對應(yīng)實體類的屬性,如果匹配一致且json中的該key對應(yīng)的值符合(或可轉(zhuǎn)換為),這一條我會在下面詳細(xì)分析,其他的都可簡單略過,但是本文末的核心邏輯代碼以及幾個結(jié)論一定要看! 實體類的對應(yīng)屬性的類型要求時,會調(diào)用實體類的setter方法將值賦給該屬性。
  • json字符串中,如果value為""的話,后端對應(yīng)屬性如果是String類型的,那么接受到的就是"",如果是后端屬性的類型是Integer、Double等類型,那么接收到的就是null。
  • json字符串中,如果value為null的話,后端對應(yīng)收到的就是null。
  • 如果某個參數(shù)沒有value的話,在傳json字符串給后端時,要么干脆就不把該字段寫到j(luò)son字符串中;要么寫value時, 必須有值,null  或""都行。千萬不能有類似"stature":,這樣的寫法,如:

                                                                     

示例詳細(xì)說明

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

User實體類:

public class User{
    private String name;    //姓名
    private Integer age;    //年齡
    private String gender;  //性別
    private String motto;   //座右銘
    //geter 和  seter  方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getMotto() {
        return motto;
    }
    public void setMotto(String motto) {
        this.motto = motto;
    }
    //重寫toString 方法
    @Override
    public String toString(){
        return age + "歲" +gender+ "人["+name+"]的座右銘是:"+motto;
    }
}

Team實體類:

class Team{
    private Integer id;//id
    private String teamName;//小組名
    private List<String> honors;//所獲稱號
    private List<User> teamMembers;//小組成員
    //geter 和 seter 方法
 
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getTeamName() {
        return teamName;
    }
    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }
    public List<String> getHonors() {
        return honors;
    }
    public void setHonors(List<String> honors) {
        this.honors = honors;
    }
    public List<User> getTeamMembers() {
        return teamMembers;
    }
    public void setTeamMembers(List<User> teamMembers) {
        this.teamMembers = teamMembers;
    }
    //重寫toString方法
    @Override
    public String toString(){
        //遍歷出小組所獲榮耀
        StringBuffer sbHonors = new StringBuffer("榮耀start----\n");
        for (String honor : honors){
            sbHonors.append(honor);
            sbHonors.append("\n");
        }
        sbHonors.append("榮耀end----\n");
        // 遍歷出小組成員
        StringBuffer sbMenbers = new StringBuffer("成員start---\n");
        for (User user:teamMembers){
            sbMenbers.append(user.toString());
            sbMenbers.append("\n");
        }
        sbMenbers.append("成員end---\n");
        return "小組id:"+ id+"\n"+"小組名字:"+teamName+"\n"+"小組所獲榮耀:"
                +sbHonors+"\n"+"小組成員:"+sbMenbers;
    }
}

@RequestBody直接以String接收前端傳過來的json數(shù)據(jù):

后端對應(yīng)的Controller:

使用PostMan測試:

@RequestBody以簡單對象接收前端傳過來的json數(shù)據(jù):

后端對應(yīng)的Controller:

使用PostMan測試:

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

后端對應(yīng)的Controller:

使用PostMan測試:

@RequestBody與復(fù)雜的@RequestParam()同時使用:

后端對應(yīng)的Controller

使用PostMan測試:

@RequestBody接收請求體中的json數(shù)據(jù);不加注解接收URL中的數(shù)據(jù)并組裝為對象:

后端對應(yīng)的Controller:

使用PostMan測試:

注:如果在后端方法參數(shù)前,指定了@RequestParam()的話,那么前端必須要有對應(yīng)字段才行(當(dāng)然可以通過設(shè)置該注解的required屬性來調(diào)節(jié)是否必須傳),否者會報錯;如果參數(shù)前沒有任何該注解,那么前端可以傳,也可以不傳,如:

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

@RequestBody與前端傳過來的json數(shù)據(jù)的匹配規(guī)則

聲明:根據(jù)不同的Content-Type等情況,Spring-MVC會采取不同的HttpMessageConverter實現(xiàn)來進(jìn)行信息轉(zhuǎn)換解析。

下面介紹的是最常用的:前端以Content-Type 為application/json,傳遞json字符串?dāng)?shù)據(jù);后端以@RequestBody模型接收數(shù)據(jù)的情況。

解析json數(shù)據(jù)大體流程概述

Http傳遞請求體信息,最終會被封裝進(jìn)com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring采用CharacterEncodingFilter設(shè)置了默認(rèn)編碼為UTF-8),然后在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通過 public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException方法進(jìn)行解析。

核心邏輯分析示例

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

小技巧之指定模型中的屬性對應(yīng)什么key

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

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

給出Controller中的測試類:

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

使用postman測試一下,示例:

上圖簡單測試了一下,但是測得并不全面,這里就不帶大家一起測試了,直接給出。

全面的結(jié)論

結(jié)論①

@JsonAlias注解,實現(xiàn):json轉(zhuǎn)模型時,使json中的特定key能轉(zhuǎn)化為特定的模型屬性;但是模型轉(zhuǎn)json時,對應(yīng)的轉(zhuǎn)換后的key仍然與屬性名一致,見:上圖示例中的name字段的請求與響應(yīng)。

以下圖進(jìn)一步說明:

此時,json字符串轉(zhuǎn)換為模型時,json中key為Name或為name123或為name的都能識別。

結(jié)論②

@JsonProperty注解,實現(xiàn):json轉(zhuǎn)模型時,使json中的特定key能轉(zhuǎn)化為指定的模型屬性;同樣的,模型轉(zhuǎn)json時,對應(yīng)的轉(zhuǎn)換后的key為指定的key,見:示例中的motto字段的請求與響應(yīng)。

以下圖進(jìn)一步說明:

此時,json字符串轉(zhuǎn)換為模型時,key為MOTTO的能識別,但key為motto的不能識別。

結(jié)論③

@JsonAlias注解需要依賴于setter、getter,而@JsonProperty注解不需要。

結(jié)論④

在不考慮上述兩個注解的一般情況下,key與屬性匹配時,默認(rèn)大小寫敏感。

結(jié)論⑤

有多個相同的key的json字符串中,轉(zhuǎn)換為模型時,會以相同的幾個key中,排在最后的那個key的值給模型屬性復(fù)制,因為setter會覆蓋原來的值。見示例中的gender屬性。

結(jié)論⑥

后端@RequestBody注解對應(yīng)的類在將HTTP的輸入流(含請求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時,會根據(jù)json字符串中的key來匹配對應(yīng)實體類的屬性,如果匹配一致且json中的該key對應(yīng)的值符合(或可轉(zhuǎn)換為)實體類的對應(yīng)屬性的類型要求時,會調(diào)用實體類的setter方法將值賦給該屬性。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springmvc參數(shù)為對象,數(shù)組的操作

    springmvc參數(shù)為對象,數(shù)組的操作

    這篇文章主要介紹了springmvc參數(shù)為對象,數(shù)組的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java實戰(zhàn)項目之記賬軟件

    java實戰(zhàn)項目之記賬軟件

    這篇文章主要介紹了java實戰(zhàn)項目之記賬軟件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • 基于Java回顧之集合的總結(jié)概述

    基于Java回顧之集合的總結(jié)概述

    在這篇文章里,我們關(guān)注Java中的集合(Collection)。集合是編程語言中基礎(chǔ)的一部分,Java自JDK早期,就引入了Java Collection Framework。設(shè)計JCF的那個人,后來還寫了一本書,叫《Effective Java》
    2013-05-05
  • Redis內(nèi)存數(shù)據(jù)庫示例分析

    Redis內(nèi)存數(shù)據(jù)庫示例分析

    Redis本身的內(nèi)容比較復(fù)雜。如果你上來,你應(yīng)該研究一個細(xì)節(jié)點,比如連接池和數(shù)據(jù)結(jié)構(gòu)。雖然可以直接了解某一點的詳細(xì)來源內(nèi)容,甚至盡快解決一些意外,但是容易淹沒在失眠的細(xì)節(jié)中,整體控制不了Redis
    2022-12-12
  • java生成圖片驗證碼的示例代碼

    java生成圖片驗證碼的示例代碼

    這篇文章主要介紹了java生成圖片驗證碼的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • Java實現(xiàn)UDP通信過程實例分析【服務(wù)器端與客戶端】

    Java實現(xiàn)UDP通信過程實例分析【服務(wù)器端與客戶端】

    這篇文章主要介紹了Java實現(xiàn)UDP通信過程,結(jié)合實例形式分析了java實現(xiàn)UDP服務(wù)器端與客戶端相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2020-05-05
  • 圖片驗證碼概述及實現(xiàn)步驟

    圖片驗證碼概述及實現(xiàn)步驟

    本文主要介紹了圖片驗證碼概述及實現(xiàn)步驟。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解

    IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解

    這篇文章主要介紹了IDEA項目代碼上傳gitlab遠(yuǎn)程倉庫過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Java實現(xiàn)批量修改txt文件名稱的方法示例

    Java實現(xiàn)批量修改txt文件名稱的方法示例

    這篇文章主要介紹了Java實現(xiàn)批量修改txt文件名稱的方法,結(jié)合實例形式分析了Java針對目錄文件遍歷及文件讀寫、屬性操作等相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-03-03
  • SSH框架網(wǎng)上商城項目第10戰(zhàn)之搭建商品類基本模塊

    SSH框架網(wǎng)上商城項目第10戰(zhàn)之搭建商品類基本模塊

    這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項目第10戰(zhàn)之搭建商品類基本模塊的相關(guān)資料,有一定的實用性,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論

海门市| 毕节市| 霍林郭勒市| 都兰县| 桑日县| 乳山市| 呼玛县| 南安市| 女性| 柏乡县| 武城县| 云安县| 湟中县| 通榆县| 兖州市| 金华市| 潜江市| 西安市| 闵行区| 顺平县| 积石山| 临泽县| 岳池县| 鲁甸县| 长垣县| 衡阳县| 祁门县| 镇安县| 汝城县| 类乌齐县| 靖远县| 东方市| 双城市| 千阳县| 葫芦岛市| 从化市| 阿拉善左旗| 合作市| 无锡市| 沁阳市| 河池市|