下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、使用Redi获取数据转json解决动态泛型传参的问题场景:项目有两种角色需要不同的登录权限,将ed做为用户登录信息缓存数据库。码一个方法,希望能够根据传入不用用户实体类型来获取相应的数据。用户实体为:essionni、sessionni。json(使用SjSon先阐述遇到的几个问题:ied获取到的数据序列化后,转json经常提示转换异常(并不是每次,只是时常)。2不想每种用户都书写一个ed操作方法(显得i)。解决:ied获取到的数据序列化后,转json经常提示转换异常:先说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);显然第一种的方式比较简单。查看源码,发现第一种方式底层调用的也是edisee方法,e所以应该算是一种封装吧。我们一直釆用的是第二种方式。(
3、第一种方式试过,也一样会出现son强转异常)。这里出现过json异常,怀疑是跟泛型有关。这里手动指定泛型反序列化类型。修改后: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完美,确实解决了json强转异常。那么问题来了,这里的eRee需要手动指定明确的的实体类型,尝试添加泛型: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(););看样子是没什么问题,而且泛型也被识别到了。但是依旧无法通过。2、不想每种用户都书写一个redis操作方法:上面说到就算加了泛型也依旧无法通过,尝试了多种方式依旧如此。百度了一圈,都是说使用TypeReference这个来解决,但是并没有提及动态泛型的问题。偶然间看到文章说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、要类。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然。它使用JsonParser和JsonGenerator的实例实现JSON实际的读/写。(复制来的)发现问题解决。提供的抽象方法为:publicSessionEntityget(finalStrings,Classclazz);调用方式为:sessionEntityDao.get(key,User1.class);跟sessionEntityDao.get(key,User2.class);由于这里使用到的是jackson-databind-2.6.0的库,这个版本种constructParametricType这个方法已经快要
9、过时,更高版本使用constructParametrizedType替换。这里我还没尝试过,等有空再玩。这里问题已经解决,纯粹做个笔记以供自己以后方便查阅。这里只提供自己项目中遇到的解决方式之一,相信应该还有其他方式可以解决。如果有说明错误的地方,请指出并见谅。补充知识:Redis爬坑Redis实现通用序列化器&解决Redis反序列化失败Redis默认序列化是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;这里因为我们的项目需要更改默认序列策略为Jackson2JsonRedisSerialize让它序列化为可视化的*json*语句我们首先定义自己的RedisTemplate,这里我们不要为了每一个类定义一
13、个序列化器,我们定义一个统一的序列化器所以这里泛型是,key我们使用StringRedisSerializer,value使用Jackson2JsonRedisSerializer注释代码为修复反序列化bug的代码BeanpublicRedisTemplateobjectRedisTemplate(RedisConnectionFactoryredisConnectionFactory)throwsUnknownHostExceptionRedisTemplatetemplate=newRedisTemplate();Jackson2JsonRedisSerializerjsonSerial=
14、newJackson2JsonRedisSerializer(Object.class);/修复反序列化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);运行结果为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很明显是对象强制转换错误这是因为泛型的原因,redis在序列化时候把他当成O
19、bject序列化的,所以这里反序列化为Object是可以的,但是因为这个Object没有类型定义所以无法强转。解决办法在RedisTemplate中对序列化器Jackson2JsonRedisSerializer进行修改添加如下代码,上文注释了/修复反序列化bugObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jsonS
20、erial.setObjectMapper(om);通过objectMapper.enableDefaultTyping()方法设置即使使用Object.class作为jcom.fasterxml.jackson.databind.JavaType也可以实现相应类型的序列化和反序列化好处:只定义一个序列化器就可以了(通用)这里我们也做个测试,分别用不修改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运行结果:obi:com.hcy.core.model.UserDO,userid:null,openid:null,name:name,city:cityob2:userid:null,openid:null,name:name,city:city这里结果很明显啦希望对大家有帮助以上这篇使用Redis获取数据转js
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五美容院跨区域品牌拓展合作协议4篇
- 2025版养老院入住后休闲娱乐设施使用合同3篇
- 2025年度个人二手车买卖合同模板4篇
- 2025版双方垫资合作知识产权简单协议3篇
- 二零二五年度生物制药产品研发与销售合同4篇
- 二零二五版美甲店会员积分体系合作合同4篇
- 2025版高端定制门窗设计加工合作协议4篇
- 2025年度绿色生态面料生产加工合作合同4篇
- 个人委托培训合同书2024年版范例版B版
- 2025年度冷库设施设备租赁及维护合同4篇
- GB/T 45107-2024表土剥离及其再利用技术要求
- 2024-2025学年八年级上学期1月期末物理试题(含答案)
- 商场电气设备维护劳务合同
- 2023年国家公务员录用考试《行测》真题(行政执法)及答案解析
- 2024智慧医疗数据字典标准值域代码
- 年产12万吨装配式智能钢结构项目可行性研究报告模板-立项备案
- 【独家揭秘】2024年企业微信年费全解析:9大行业收费标准一览
- 医疗器械经销商会议
- 《±1100kV特高压直流换流变压器使用技术条件》
- 《风电场项目经济评价规范》(NB-T 31085-2016)
- 五年级上册脱式计算100题及答案
评论
0/150
提交评论