下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第JavaSpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解本例中,HttpMessageConverter使用的是MappingJackson2HttpMessageConverter,該類繼承自AbstractJackson2HttpMessageConverter??疵Q就知道,這個類是使用Jackson處理請求參數(shù)。其中read方法之后,會調用內部私有方法readJavaType,下面給出該方法的核心邏輯:
privateObjectreadJavaType(JavaTypejavaType,HttpInputMessageinputMessage)throwsIOException{
MediaTypecontentType=inputMessage.getHeaders().getContentType();//1
Charsetcharset=getCharset(contentType);
ObjectMapperobjectMapper=selectObjectMapper(javaType.getRawClass(),contentType);//2
Assert.state(objectMapper!=null,"NoObjectMapperfor"+javaType);
booleanisUnicode=ENCODINGS.containsKey(())||
"UTF-16".equals(())||
"UTF-32".equals(());//3
try{
if(isUnicode){
returnobjectMapper.readValue(inputMessage.getBody(),javaType);//4
}else{
Readerreader=newInputStreamReader(inputMessage.getBody(),charset);
returnobjectMapper.readValue(reader,javaType);
catch(InvalidDefinitionExceptionex){
thrownewHttpMessageConversionException("Typedefinitionerror:"+ex.getType(),ex);
catch(JsonProcessingExceptionex){
thrownewHttpMessageNotReadableException("JSONparseerror:"+ex.getOriginalMessage(),ex,inputMessage);
跟著代碼說明一下各部分用途:
獲取請求的content-type,這個是Spring實現(xiàn)的擴展邏輯,根據(jù)不同的content-type可以選擇不同的ObjectMapper實例。也就是第2步的邏輯
根據(jù)content-type和目標類型,選擇ObjectMapper實例。本例中直接返回的是默認的,也就是通過Jackson2ObjectMapperBuilder.cbor().build()方法創(chuàng)建的。
檢查請求是否是unicode字符,目前來說,大家用的都是UTF-8的
通過ObjectMapper將請求json轉換為對象。其實這部分還有一段判斷inputMessage是否是MappingJacksonInputMessage實例的,考慮到大家使用的版本,這部分就不說了。
至此,Spring的邏輯全部結束,似乎還是沒有找到我們使用的JsonCreator注解或者JsonDeserialize的邏輯。不過也能想到,這兩個都是Jackson的類,那必然應該是Jackson的邏輯。接下來,就扒一扒Jackson的轉換邏輯了。
深入Jackson的ObjectMapper邏輯
牽扯Jackson的邏輯主要分布在AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters和ObjectMapper#readValue這兩個方法中。先說一下ObjectMapper#readValue方法的邏輯,這里面會調用GenderIdCodeEnum#create方法,完成類型轉換。
ObjectMapper#readValue方法直接調用了當前類中的_readMapAndClose方法,這個方法里面比較關鍵的是ctxt.readRootValue(p,valueType,_findRootDeserializer(ctxt,valueType),null),這個方法就是將輸入json轉換為對象。咱們再繼續(xù)深入,可以找到Jackson內部是通過BeanDeserializer這個類轉換對象的,比較重要的是deserializeFromObject方法,源碼如下(刪除一下不太重要的代碼):
publicObjectdeserializeFromObject(JsonParserp,DeserializationContextctxt)throwsIOException
//這里根據(jù)上下文中目標類型,創(chuàng)建實例對象,其中_valueInstantiator是StdValueInstantiator實例。
finalObjectbean=_valueInstantiator.createUsingDefault(ctxt);
//[databind#631]:Assigncurrentvalue,tobeaccessiblebycustomdeserializers
p.setCurrentValue(bean);
if(p.hasTokenId(JsonTokenId.ID_FIELD_NAME)){
StringpropName=p.currentName();
do{
p.nextToken();
//根據(jù)字段名找到屬性對象,對于gender字段,類型是MethodProperty。
SettableBeanPropertyprop=_beanProperties.find(propName);
if(prop!=null){//normalcase
try{
//開始進行解碼操作,并將解碼結果寫入到對象中
prop.deserializeAndSet(p,ctxt,bean);
}catch(Exceptione){
wrapAndThrow(e,bean,propName,ctxt);
continue;
handleUnknownVanilla(p,ctxt,bean,propName);
}while((propName=p.nextFieldName())!=null);
returnbean;
咱們看一下MethodProperty#deserializeAndSet的邏輯(只保留關鍵代碼):
publicvoiddeserializeAndSet(JsonParserp,DeserializationContextctxt,
Objectinstance)throwsIOException
Objectvalue;
//調用FactoryBasedEnumDeserializer實例的解碼方法
value=_valueDeserializer.deserialize(p,ctxt);
//通過反射將值寫入對象中
_setter.invoke(instance,value);
其中_valueDeserializer是FactoryBasedEnumDeserializer實例,快要接近目標了,看下這段邏輯:
publicObjectdeserialize(JsonParserp,DeserializationContextctxt)throwsIOException
//獲取json中的值
Objectvalue=_deser.deserialize(p,ctxt);
//調用GenderIdCodeEnum#create方法
return_factory.callOnWith(_valueClass,value);
_factory是AnnotatedMethod實例,主要是對JsonCreator注解定義的方法的包裝,然后callOnWith中調用java.lang.reflect.Method#invoke反射方法,執(zhí)行GenderIdCodeEnum#create。
至此,我們終于串起來所有邏輯。
本文通過一個示例串起來@JsonCreator注解起作用的邏輯,JsonDeserializer接口的邏輯與之類型,可以耐心debug一番。下面給出主要類的類圖:
SpringBoot實戰(zhàn):一招實現(xiàn)結果的優(yōu)雅響應
SpringBoot實戰(zhàn):如何優(yōu)雅的處理異常
SpringBoot實戰(zhàn):通過Bea
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山泉小學教學常規(guī)管理制度(3篇)
- 項目管理制度及格式范文(3篇)
- 茶室品茗活動策劃方案(3篇)
- 教育管理制度學習體會(3篇)
- 2026年河北唐山中心醫(yī)院腎內科急聘英才1名考試參考試題及答案解析
- 2026年福建莆田礪志高級中學多學科教師招聘若干人備考考試題庫及答案解析
- 海南儋州市2026屆教育部直屬師范大學公費師范畢業(yè)生供需見面招聘24人(一)備考考試題庫及答案解析
- 2026北京航空航天大學集成電路科學與工程學院聘用編科研助理F崗招聘1人備考考試題庫及答案解析
- 2025湖南郴州市永興縣基層醫(yī)療衛(wèi)生單位招聘專業(yè)技術人員選崗15人備考考試題庫及答案解析
- 2026北京北化化學科技有限公司招聘15人考試備考題庫及答案解析
- 2024-2025學年廣東省實驗中學高一(上)期中語文試卷
- DB34T 1948-2013 建設工程造價咨詢檔案立卷標準
- 鋼鐵制造的工藝流程(內部資料)課件
- DB31-T 1448-2023 監(jiān)獄場所消防安全管理規(guī)范
- 公司干部調研方案
- 無糾紛自愿離婚協(xié)議書
- 四川省高等教育自學考試畢業(yè)生登記表【模板】
- 專題五 以新發(fā)展理念引領高質量發(fā)展
- GB/T 22417-2008叉車貨叉叉套和伸縮式貨叉技術性能和強度要求
- GB/T 1.1-2009標準化工作導則 第1部分:標準的結構和編寫
- 長興中學提前招生試卷
評論
0/150
提交評論