@RequestBody與@RequestParam

一涝焙、基礎(chǔ)知識(shí)介紹

1??@RequestBody主要用來(lái)接收前端傳遞給后端的json字符串中的數(shù)據(jù)(請(qǐng)求體中的數(shù)據(jù))
2??因?yàn)?code>GET方式無(wú)請(qǐng)求體卑笨,所以使用@RequestBody接收數(shù)據(jù)時(shí),前端不能使用GET方式提交數(shù)據(jù)仑撞,而是用POST方式進(jìn)行提交赤兴。
3??在后端的同一個(gè)接收方法里,@RequestBody@RequestParam可以同時(shí)使用隧哮。
4??一個(gè)請(qǐng)求桶良,只能有一個(gè)@RequestBody,卻可以有多個(gè)@RequestParam沮翔。
5??當(dāng)同時(shí)使用@RequestParam@RequestBody時(shí)艺普,@RequestParam指定的參數(shù)可以是普通元素、數(shù)組鉴竭、集合、對(duì)象等等(即:當(dāng)@RequestBody@RequestParam可以同時(shí)使用時(shí)岸浑,原SpringMVC接收參數(shù)的機(jī)制不變搏存,只不過@RequestBody接收的是請(qǐng)求體里面的數(shù)據(jù);而@RequestParam接收的是key-value里面的參數(shù)矢洲,所以它會(huì)被切面進(jìn)行處理從而可以用普通元素璧眠、數(shù)組、集合读虏、對(duì)象等接收责静。)
6??如果參數(shù)是放在請(qǐng)求體中,傳入后臺(tái)的話盖桥,那么后臺(tái)要用@RequestBody才能接收到灾螃;如果不是放在請(qǐng)求體中的話,那么后臺(tái)接收前臺(tái)傳過來(lái)的參數(shù)時(shí)揩徊,要用@RequestParam來(lái)接收腰鬼,或形參前什么也不寫也能接收嵌赠。如果參數(shù)前寫了@RequestParam(xxx),那么前端必須有對(duì)應(yīng)的xxx名字才行(不管其是否有值熄赡,當(dāng)然可以通過設(shè)置該注解的required屬性來(lái)控制是否必須傳)姜挺,如果沒有xxx名的話,那么請(qǐng)求會(huì)出錯(cuò)彼硫,報(bào)400炊豪。

注:如果參數(shù)前不寫@RequestParam(xxx)的話,那么就前端可有可無(wú)對(duì)應(yīng)的xxx名字拧篮,如果有xxx名的話词渤,那么就會(huì)自動(dòng)匹配;沒有的話他托,請(qǐng)求也能正確發(fā)送掖肋。

注意:這里與feign消費(fèi)服務(wù)時(shí)不同:

  • feign消費(fèi)服務(wù)時(shí),如果參數(shù)前什么也不寫赏参,那么會(huì)被默認(rèn)是@RequestBody的志笼。
  • 如果后端參數(shù)是一個(gè)對(duì)象,且該參數(shù)前是以@RequestBody修飾的把篓,那么前端傳遞json參數(shù)時(shí)纫溃,必須滿足以下要求:后端@RequestBody注解對(duì)應(yīng)的類在將HTTP的輸入流(含請(qǐng)求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時(shí),會(huì)根據(jù)json字符串中的key來(lái)匹配對(duì)應(yīng)實(shí)體類的屬性韧掩,如果匹配一致且json中的該key對(duì)應(yīng)的值符合(或可轉(zhuǎn)換為)實(shí)體類的對(duì)應(yīng)屬性的類型要求時(shí)紊浩,會(huì)調(diào)用實(shí)體類的setter方法將值賦給該屬性。

json字符串中疗锐,如果value為""的話坊谁,后端對(duì)應(yīng)屬性如果是String類型的,那么接受到的就是""滑臊,如果是后端屬性的類型是Integer口芍、Double等類型,那么接收到的就是null雇卷。json字符串中鬓椭,如果value為null的話,后端對(duì)應(yīng)收到的就是null关划。如果某個(gè)參數(shù)沒有value的話小染,在傳json字符串給后端時(shí),要么干脆就不把該字段寫到json字符串中贮折;要么寫value時(shí)裤翩, 必須有值,null 或""都行调榄。

二岛都、@RequestBody與前端傳過來(lái)的json數(shù)據(jù)的匹配規(guī)則

聲明:根據(jù)不同的Content-Type等情況律姨,Spring-MVC會(huì)采取不同的HttpMessageConverter實(shí)現(xiàn)來(lái)進(jìn)行信息轉(zhuǎn)換解析。下面介紹的是最常用的:前端以Content-Typeapplication/json傳遞json字符串?dāng)?shù)據(jù)臼疫,后端以@RequestBody模型接收數(shù)據(jù)的情況择份。

解析json數(shù)據(jù)大體流程概述:Http傳遞請(qǐng)求體信息,最終會(huì)被封裝進(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)行解析。

三鸽斟、結(jié)論

  1. @JsonAlias注解拔创。實(shí)現(xiàn)json轉(zhuǎn)模型時(shí),使json中的特定key能轉(zhuǎn)化為特定的模型屬性富蓄;但是模型轉(zhuǎn)json時(shí)剩燥,對(duì)應(yīng)的轉(zhuǎn)換后的key仍然與屬性名一致,
  2. @JsonProperty注解立倍。實(shí)現(xiàn)json轉(zhuǎn)模型時(shí)灭红,使json中的特定key能轉(zhuǎn)化為指定的模型屬性;同樣的口注,模型轉(zhuǎn)json時(shí)变擒,對(duì)應(yīng)的轉(zhuǎn)換后的key為指定的key。
  3. @JsonAlias注解需要依賴于setter寝志、getter娇斑,而@JsonProperty注解不需要。
  4. 在不考慮上述兩個(gè)注解的一般情況下材部,key與屬性匹配時(shí)毫缆,默認(rèn)大小寫敏感。
  5. 有多個(gè)相同的key的json字符串中乐导,轉(zhuǎn)換為模型時(shí)悔醋,會(huì)以相同的幾個(gè)key中,排在最后的那個(gè)key的值給模型屬性復(fù)制兽叮,因?yàn)閟etter會(huì)覆蓋原來(lái)的值。
  6. 后端@RequestBody注解對(duì)應(yīng)的類在將HTTP的輸入流(含請(qǐng)求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時(shí)猾愿,會(huì)根據(jù)json字符串中的key來(lái)匹配對(duì)應(yīng)實(shí)體類的屬性鹦聪,如果匹配一致且json中的該key對(duì)應(yīng)的值符合(或可轉(zhuǎn)換為)實(shí)體類的對(duì)應(yīng)屬性的類型要求時(shí),會(huì)調(diào)用實(shí)體類的setter方法將值賦給該屬性蒂秘。

四泽本、在使用Json傳值并且使用@RequestBody注解的時(shí)候需要注意的問題

1??一個(gè)方法中只能有一個(gè)@RequestBody注解。
因?yàn)镽equestBody就是request的inputStream姻僧,這個(gè)流在第一次使用該注解后會(huì)關(guān)閉规丽,后面的都會(huì)報(bào)錯(cuò)(stream closed)蒲牧。

2??默認(rèn)情況下@RequestBody標(biāo)注的對(duì)象必須包含前臺(tái)傳來(lái)的所有字段。如果沒有包含前臺(tái)傳來(lái)的字段赌莺,就會(huì)報(bào)錯(cuò):Unrecognized field xxx , not marked as ignorable冰抢,出現(xiàn)這種問題是因?yàn)槭褂胘ackson進(jìn)行json轉(zhuǎn)換時(shí),MappingJacksonHttpMessageConverter默認(rèn)要求必須存在相應(yīng)的字段艘狭。如果沒有前臺(tái)傳來(lái)的某個(gè)字段或者字段沒有提供set方法挎扰,就會(huì)報(bào)錯(cuò)。解決方法:

  1. 可以增加一個(gè)字段來(lái)接收前臺(tái)傳來(lái)的這個(gè)值巢音,如果存在多個(gè)字段遵倦,這種方式很不好(就算一個(gè)字段,如果沒用官撼,新增字段也不好)梧躺。
  2. 在前臺(tái)往后臺(tái)傳值的時(shí)候,去掉無(wú)用的字段傲绣。這樣還能減少網(wǎng)絡(luò)傳輸?shù)拇笮 ?/li>
  3. 使用Jackson提供的json注解:
  • @JsonIgnore注解用來(lái)忽略某些字段掠哥,可以用在Field或者Getter方法上,用在Setter方法時(shí)斜筐,和Filed效果一樣龙致。這個(gè)注解只能用在POJO存在的字段要忽略的情況,不能滿足現(xiàn)在需要的情況顷链。
  • @JsonIgnoreProperties(ignoreUnknown = true)目代,將這個(gè)注解寫在類上之后,就會(huì)忽略類中不存在的字段嗤练,可以滿足當(dāng)前的需要榛了。這個(gè)注解還可以指定要忽略的字段。如: @JsonIgnoreProperties({ "internalId", "secretKey"})指定的字段不會(huì)被序列化和反序列化煞抬。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末霜大,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子革答,更是在濱河造成了極大的恐慌战坤,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件残拐,死亡現(xiàn)場(chǎng)離奇詭異途茫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)塞赂,“玉大人季俩,你說我怎么就攤上這事栅组∪钙埃” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵玉掸,是天一觀的道長(zhǎng)刃麸。 經(jīng)常有香客問我,道長(zhǎng)排截,這世上最難降的妖魔是什么嫌蚤? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮断傲,結(jié)果婚禮上脱吱,老公的妹妹穿的比我還像新娘。我一直安慰自己认罩,他們只是感情好箱蝠,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垦垂,像睡著了一般宦搬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上劫拗,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天间校,我揣著相機(jī)與錄音,去河邊找鬼页慷。 笑死憔足,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酒繁。 我是一名探鬼主播滓彰,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼州袒!你這毒婦竟也來(lái)了揭绑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤郎哭,失蹤者是張志新(化名)和其女友劉穎他匪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夸研,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邦蜜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陈惰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抬闯,靈堂內(nèi)的尸體忽然破棺而出井辆,到底是詐尸還是另有隱情,我是刑警寧澤溶握,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布杯缺,位于F島的核電站,受9級(jí)特大地震影響睡榆,放射性物質(zhì)發(fā)生泄漏萍肆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一胀屿、第九天 我趴在偏房一處隱蔽的房頂上張望塘揣。 院中可真熱鬧,春花似錦宿崭、人聲如沸亲铡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奖蔓。三九已至,卻和暖如春讹堤,著一層夾襖步出監(jiān)牢的瞬間吆鹤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工洲守, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疑务,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓岖沛,卻偏偏與公主長(zhǎng)得像暑始,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婴削,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容