Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解_第1頁
Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解_第2頁
Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解_第3頁
Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解_第4頁
Java SpringBoot在RequestBody中高效的使用枚舉參數(shù)原理案例詳解_第5頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論