下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、使用Redi獲取數(shù)據(jù)轉(zhuǎn)json解決動(dòng)態(tài)泛型傳參的問題場(chǎng)景:項(xiàng)目有兩種角色需要不同的登錄權(quán)限,將ed做為用戶登錄信息緩存數(shù)據(jù)庫(kù)。碼一個(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);顯然第一種的方式比較簡(jiǎn)單。查看源碼,發(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庫(kù)的主
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的庫(kù),這個(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;測(cè)試代碼為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è)測(cè)試,分別用不修改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. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 藝術(shù)與意識(shí)形態(tài)研究-洞察分析
- 移動(dòng)健康干預(yù)研究-洞察分析
- 原型設(shè)計(jì)與迭代方法-洞察分析
- 網(wǎng)絡(luò)安全與數(shù)據(jù)保護(hù)-洞察分析
- 心理咨詢?cè)谔厥鈨和深A(yù)中的應(yīng)用-洞察分析
- 網(wǎng)絡(luò)安全在電信行業(yè)的重要性-洞察分析
- 細(xì)胞液分子識(shí)別-洞察分析
- 云內(nèi)存安全審計(jì)-洞察分析
- 創(chuàng)建文明校園校長(zhǎng)精彩講話稿(5篇)
- 抑制效應(yīng)生物合成-洞察分析
- 歷史人教部編版八年級(jí)(上冊(cè))22.抗日戰(zhàn)爭(zhēng)的勝利課件(25張)2024版新教材
- 2024年新北師大版七年級(jí)上冊(cè)數(shù)學(xué)課件 第六章 6.2 第2課時(shí) 樣本的選取
- 15《搭船的鳥》(教學(xué)設(shè)計(jì))2024-2025學(xué)年統(tǒng)編版語文三年級(jí)上冊(cè)
- 2024至2030年中國(guó)傳染病醫(yī)院產(chǎn)業(yè)發(fā)展動(dòng)態(tài)及未來前景展望報(bào)告
- 知識(shí)點(diǎn)填空練習(xí)-2024-2025學(xué)年統(tǒng)編版道德與法治七年級(jí)上冊(cè)
- 學(xué)習(xí)使用顯微鏡 2024-2025學(xué)年七年級(jí)上冊(cè)生物同步課件(人教版2024)
- 護(hù)理疑難病例討論課件模板
- 中國(guó)近現(xiàn)代史綱要智慧樹知到答案2024年北京師范大學(xué)等跨校共建
- 別墅群施工組織設(shè)計(jì)
- JGJ7-2010 空間網(wǎng)格結(jié)構(gòu)技術(shù)規(guī)程
- 建筑工程代付款協(xié)議書
評(píng)論
0/150
提交評(píng)論