使用Redis獲取數(shù)據(jù)轉(zhuǎn)json,解決動(dòng)態(tài)泛型傳參的問題_第1頁
使用Redis獲取數(shù)據(jù)轉(zhuǎn)json,解決動(dòng)態(tài)泛型傳參的問題_第2頁
使用Redis獲取數(shù)據(jù)轉(zhuǎn)json,解決動(dòng)態(tài)泛型傳參的問題_第3頁
使用Redis獲取數(shù)據(jù)轉(zhuǎn)json,解決動(dòng)態(tài)泛型傳參的問題_第4頁
使用Redis獲取數(shù)據(jù)轉(zhuǎn)json,解決動(dòng)態(tài)泛型傳參的問題_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、使用Redi獲取數(shù)據(jù)轉(zhuǎn)json解決動(dòng)態(tài)泛型傳參的問題場景:項(xiàng)目有兩種角色需要不同的登錄權(quán)限,將ed做為用戶登錄信息緩存數(shù)據(jù)庫。碼一個(gè)方法,希望能夠根據(jù)傳入不用用戶實(shí)體類型來獲取相應(yīng)的數(shù)據(jù)。用戶實(shí)體為:essionni、sessionni。json(使用SjSon先闡述遇到的幾個(gè)問題:ied獲取到的數(shù)據(jù)序列化后,轉(zhuǎn)json經(jīng)常提示轉(zhuǎn)換異常(并不是每次,只是時(shí)常)。2不想每種用戶都書寫一個(gè)ed操作方法(顯得i)。解決:ied獲取到的數(shù)據(jù)序列化后,轉(zhuǎn)json經(jīng)常提示轉(zhuǎn)換異常:先說edi&兩種獲取方式。1)redisTeme.opsFoue(et(key);)essionEntity)resulred

2、isTemplate.execute(new)RedisCallback)serializergetRedisserializer();e)key)=)serializer.serialize(seue)=)connection.get(key)if)(lue)=)nu)ren)nulingjson)=)serializer.deserialize(value);)returnObjecrseObject(json,sessionEntity.class);顯然第一種的方式比較簡單。查看源碼,發(fā)現(xiàn)第一種方式底層調(diào)用的也是edisee方法,e所以應(yīng)該算是一種封裝吧。我們一直釆用的是第二種方式。(

3、第一種方式試過,也一樣會(huì)出現(xiàn)son強(qiáng)轉(zhuǎn)異常)。這里出現(xiàn)過json異常,懷疑是跟泛型有關(guān)。這里手動(dòng)指定泛型反序列化類型。修改后:essionEntity)resulredisTemplate.execute(new)RedisCallback)serializer)=)getRedisserializer()e)key)=)serializer.serialize(s);eue)=)connection.get(key);)if)(lue)=)nu)ren)nulingjson)=)serializer.deserialize(value);)returnObjecrseObject(json,

4、)new)TypeReferencesessionEntityUse完美,確實(shí)解決了json強(qiáng)轉(zhuǎn)異常。那么問題來了,這里的eRee需要手動(dòng)指定明確的的實(shí)體類型,嘗試添加泛型:essionEntity)result)=)redisTemplate.execute(new)RedisCallback)serializegetRedisserializer();)byte)key)=)serializer.serialize(s);)byte)value)=)connection.get(key)if)(value)=)nuen)nStringjson=serializer.deserialize(

5、value);returnJSONObject.parseObject(json,newTypeReferenceSessionEntity(););看樣子是沒什么問題,而且泛型也被識(shí)別到了。但是依舊無法通過。2、不想每種用戶都書寫一個(gè)redis操作方法:上面說到就算加了泛型也依舊無法通過,嘗試了多種方式依舊如此。百度了一圈,都是說使用TypeReference這個(gè)來解決,但是并沒有提及動(dòng)態(tài)泛型的問題。偶然間看到文章說Fastjson不支持,所以嘗試替換Jackson。替換后的代碼:SessionEntityresult=redisTemplate.execute(newRedisCallba

6、ckSessionEntity()publicSessionEntitydoInRedis(RedisConnectionconnection)throwsDataAccessExceptionRedisSerializerserializer=getRedisSerializer();bytekey=serializer.serialize(s);bytevalue=connection.get(key);if(value=null)returnnull;Stringjson=serializer.deserialize(value);ObjectMapperom=newObjectMapp

7、er();JavaTypejavatype=om.getTypeFactory().constructParametricType(SessionEntity.class,clazz);tryreturnom.readValue(json,javatype);catch(IOExceptione)e.printStackTrace();returnnull;/returnJSONObject.parseObject(json,newTypeReferenceSessionEntity(););這里使用到Tjackson的ObjectMapper。ObjectMapper類是Jackson庫的主

8、要類。它提供一些功能將轉(zhuǎn)換成Java對(duì)象匹配JSON結(jié)構(gòu),反之亦然。它使用JsonParser和JsonGenerator的實(shí)例實(shí)現(xiàn)JSON實(shí)際的讀/寫。(復(fù)制來的)發(fā)現(xiàn)問題解決。提供的抽象方法為:publicSessionEntityget(finalStrings,Classclazz);調(diào)用方式為:sessionEntityDao.get(key,User1.class);跟sessionEntityDao.get(key,User2.class);由于這里使用到的是jackson-databind-2.6.0的庫,這個(gè)版本種constructParametricType這個(gè)方法已經(jīng)快要

9、過時(shí),更高版本使用constructParametrizedType替換。這里我還沒嘗試過,等有空再玩。這里問題已經(jīng)解決,純粹做個(gè)筆記以供自己以后方便查閱。這里只提供自己項(xiàng)目中遇到的解決方式之一,相信應(yīng)該還有其他方式可以解決。如果有說明錯(cuò)誤的地方,請(qǐng)指出并見諒。補(bǔ)充知識(shí):Redis爬坑Redis實(shí)現(xiàn)通用序列化器&解決Redis反序列化失敗Redis默認(rèn)序列化是JdkSerializationRedisSerializer,由此可見publicvoidafterPropertiesSet()super.afterPropertiesSet();booleandefaultUsed=false;i

10、f(this.defaultSerializer=null)this.defaultSerializer=newJdkSerializationRedisSerializer(this.classLoader!=null?this.classLoader:this.getClass().getClassLoader();if(this.enableDefaultSerializer)if(this.keySerializer=null)this.keySerializer=this.defaultSerializer;defaultUsed=true;if(this.valueSerializ

11、er=null)this.valueSerializer=this.defaultSerializer;defaultUsed=true;if(this.hashKeySerializer=null)this.hashKeySerializer=this.defaultSerializer;defaultUsed=true;if(this.hashValueSerializer=null)this.hashValueSerializer=this.defaultSerializer;defaultUsed=true;if(this.enableDefaultSerializer&default

12、Used)Assert.notNull(this.defaultSerializer,defaultserializernullandnotallserializersinitialized);if(this.scriptExecutor=null)this.scriptExecutor=newDefaultScriptExecutor(this);this.initialized=true;這里因?yàn)槲覀兊捻?xiàng)目需要更改默認(rèn)序列策略為Jackson2JsonRedisSerialize讓它序列化為可視化的*json*語句我們首先定義自己的RedisTemplate,這里我們不要為了每一個(gè)類定義一

13、個(gè)序列化器,我們定義一個(gè)統(tǒng)一的序列化器所以這里泛型是,key我們使用StringRedisSerializer,value使用Jackson2JsonRedisSerializer注釋代碼為修復(fù)反序列化bug的代碼BeanpublicRedisTemplateobjectRedisTemplate(RedisConnectionFactoryredisConnectionFactory)throwsUnknownHostExceptionRedisTemplatetemplate=newRedisTemplate();Jackson2JsonRedisSerializerjsonSerial=

14、newJackson2JsonRedisSerializer(Object.class);/修復(fù)反序列化bug/ObjectMapperom=newObjectMapper();/om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);/om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);/jsonSerial.setObjectMapper(om);template.setDefaultSerializer(jsonSerial);templ

15、ate.setKeySerializer(RedisSerializer.string();template.setConnectionFactory(redisConnectionFactory);template.afterPropertiesSet();returntemplate;測試代碼為TestpublicvoidredisSaveObject()UserDOob=newUserDO();ob.setName(name);ob.setCity(city);objectRedisTemplate.opsForValue().set(ob1,ob);Objectob2=objectRe

16、disTemplate.opsForValue().get(ob1);UserDOob1=(UserDO)ob2;System.out.println(ob1);運(yùn)行結(jié)果為java.lang.ClassCastException:java.util.LinkedHashMapcannotbecasttocom.hcy.core.model.UserDOatcom.hcy.core.redistest.RedisTest.redisSaveObject(RedisTest.java:42)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeM

17、ethod)atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)atjava.lang.reflect.Method.invoke(Method.java:498)atorg.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.

18、java:50)ernal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)atorg.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)ernal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at很明顯是對(duì)象強(qiáng)制轉(zhuǎn)換錯(cuò)誤這是因?yàn)榉盒偷脑?,redis在序列化時(shí)候把他當(dāng)成O

19、bject序列化的,所以這里反序列化為Object是可以的,但是因?yàn)檫@個(gè)Object沒有類型定義所以無法強(qiáng)轉(zhuǎn)。解決辦法在RedisTemplate中對(duì)序列化器Jackson2JsonRedisSerializer進(jìn)行修改添加如下代碼,上文注釋了/修復(fù)反序列化bugObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jsonS

20、erial.setObjectMapper(om);通過objectMapper.enableDefaultTyping()方法設(shè)置即使使用Object.class作為jcom.fasterxml.jackson.databind.JavaType也可以實(shí)現(xiàn)相應(yīng)類型的序列化和反序列化好處:只定義一個(gè)序列化器就可以了(通用)這里我們也做個(gè)測試,分別用不修改ObjectMapper的和修改了ObjectMapper的看看生成的value有啥子不一樣jnRedisTenplate-StringAObject*cbjectRedisTempla:el(fie吐LwfDneeicziiacFmttcjr

21、yredisConnec:ticnfactnr1Tit曠耐5._4cdlFempliecStrinyjODjeci.epiatt=mwRizdisTiefflplariJ;2ac4ED-n2JoriRtd;isScrlaLiztrjEfluSerial-n電常2ackscrtXJscnRdi&Scrializ0rtDti-2t1*5$釘A*jtcvircidReifisTen需1譏亡巧匸JjiCLte:egobjectKtdisTmulatel;AjtMircdFKc1istct;pUTe5iring,abjectRetiisiwnp1atez:restpublicvoidreditSaveObjectfH運(yùn)行結(jié)果:obi:com.hcy.core.model.UserDO,userid:null,openid:null,name:name,city:cityob2:userid:null,openid:null,name:name,city:city這里結(jié)果很明顯啦希望對(duì)大家有幫助以上這篇使用Redis獲取數(shù)據(jù)轉(zhuǎn)js

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論