婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 使用Redis獲取數據轉json,解決動態泛型傳參的問題

使用Redis獲取數據轉json,解決動態泛型傳參的問題

熱門標簽:高碑店市地圖標注app 四川穩定外呼系統軟件 廊坊外呼系統在哪買 400電話辦理的口碑 一個地圖標注多少錢 地圖標注工廠入駐 南京手機外呼系統廠家 臺灣電銷 b2b外呼系統

場景:

項目有兩種角色需要不同的登錄權限,將redis做為用戶登錄信息緩存數據庫。碼一個方法,希望能夠根據傳入不用用戶實體類型來獲取相應的數據。用戶實體為:SessionEntityUser1>、SessionEntityUser2>。json使用FastJson。

先闡述遇到的幾個問題:

1、redis獲取到的數據序列化后,轉json,經常提示轉換異常(并不是每次,只是時常)。

2、不想每種用戶都書寫一個redis操作方法(顯得tai low)。

解決:

1、redis獲取到的數據序列化后,轉json,經常提示轉換異常:

先說redis有兩種獲取方式。

1)

redisTemplate.opsForValue().get(key);

2)

SessionEntity result = redisTemplate.execute(new RedisCallbackSessionEntity>() {
   public SessionEntity doInRedis(RedisConnection connection)
     throws DataAccessException {
    RedisSerializerString> serializer = getRedisSerializer();
    byte[] key = serializer.serialize(s);
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    String json = serializer.deserialize(value);
    return JSONObject.parseObject(json,SessionEntity.class);
   }
  });

顯然第一種的方式比較簡單。查看源碼,發現第一種方式底層調用的也是redisTemplate.execute方法,所以應該算是一種封裝吧。我們一直采用的是第二種方式。(第一種方式試過,也一樣會出現json強轉異常)。這里出現過json異常,懷疑是跟泛型有關。這里手動指定泛型反序列化類型。

修改后:

SessionEntity result = redisTemplate.execute(new RedisCallbackSessionEntity>() {
   public SessionEntity doInRedis(RedisConnection connection)
     throws DataAccessException {
    RedisSerializerString> serializer = getRedisSerializer();
    byte[] key = serializer.serialize(s);
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    String json = serializer.deserialize(value);
    return JSONObject.parseObject(json, new TypeReferenceSessionEntityUser>>(){});
   }
  });

完美~,確實解決了json強轉異常。

那么問題來了,這里的TypeReference需要手動指定明確的的實體類型,嘗試添加泛型:

SessionEntityT> result = redisTemplate.execute(new RedisCallbackSessionEntityT>>() {
   public SessionEntityT> doInRedis(RedisConnection connection)
     throws DataAccessException {
    RedisSerializerString> serializer = getRedisSerializer();
    byte[] key = serializer.serialize(s);
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    String json = serializer.deserialize(value);
    return JSONObject.parseObject(json, new TypeReferenceSessionEntityT>>(){});
   }
  });

看樣子是沒什么問題,而且泛型也被識別到了。 但是依舊無法通過。

2、不想每種用戶都書寫一個redis操作方法:

上面說到就算加了泛型也依舊無法通過,嘗試了多種方式依舊如此。百度了一圈,都是說使用TypeReference這個來解決,但是并沒有提及動態泛型的問題。偶然間看到文章說Fastjson不支持,所以嘗試替換成jackson。

替換后的代碼:

SessionEntityT> result = redisTemplate.execute(new RedisCallbackSessionEntityT>>() {
   public SessionEntityT> doInRedis(RedisConnection connection)
     throws DataAccessException {
    RedisSerializerString> serializer = getRedisSerializer();
    byte[] key = serializer.serialize(s);
    byte[] value = connection.get(key);
    if (value == null) {
     return null;
    }
    String json = serializer.deserialize(value);
    ObjectMapper om = new ObjectMapper();
    JavaType javatype = om.getTypeFactory().constructParametricType(SessionEntity.class, clazz);
    try {
     return om.readValue(json, javatype);
    } catch (IOException e) {
     e.printStackTrace();
    }
    return null;
//    return JSONObject.parseObject(json, new TypeReferenceSessionEntityT>>(){});
   }
  });

這里使用到了jackson的ObjectMapper。ObjectMapper類是Jackson庫的主要類。它提供一些功能將轉換成Java對象匹配JSON結構,反之亦然。它使用JsonParser和JsonGenerator的實例實現JSON實際的讀/寫。(復制來的)發現問題解決。

提供的抽象方法為:

public T> SessionEntityT> get(final String s, ClassT> clazz);

調用方式為:

sessionEntityDao.get(key, User1.class); 跟 sessionEntityDao.get(key, User2.class);

由于這里使用到的是jackson-databind-2.6.0的庫,這個版本種constructParametricType這個方法已經快要過時,更高版本使用

constructParametrizedType

替換。這里我還沒嘗試過,等有空再玩。

這里問題已經解決,純粹做個筆記以供自己以后方便查閱。這里只提供自己項目中遇到的解決方式之一,相信應該還有其他方式可以解決。如果有說明錯誤的地方,請指出并見諒。

補充知識:Redis爬坑——Redis實現通用序列化器 解決Redis反序列化失敗

Redis默認序列化是 JdkSerializationRedisSerializer,由此可見

public void afterPropertiesSet() {
 super.afterPropertiesSet();
 boolean defaultUsed = false;
 if (this.defaultSerializer == null) {
  this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
 }

 if (this.enableDefaultSerializer) {
  if (this.keySerializer == null) {
   this.keySerializer = this.defaultSerializer;
   defaultUsed = true;
  }

  if (this.valueSerializer == 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  defaultUsed) {
  Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
 }

 if (this.scriptExecutor == null) {
  this.scriptExecutor = new DefaultScriptExecutor(this);
 }

 this.initialized = true;
}

這里因為我們的項目需要更改默認序列策略為Jackson2JsonRedisSerializer讓它序列化為可視化的***json***語句

我們首先定義自己的RedisTemplate,這里我們不要為了每一個類定義一個序列化器,我們定義一個統一的序列化器所以這里泛型是 String,Object>,key我們使用StringRedisSerializer,value使用Jackson2JsonRedisSerializer

注釋代碼為修復反序列化bug的代碼

 @Bean
 public RedisTemplateString, Object> objectRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
  RedisTemplateString, Object> template = new RedisTemplate();
  Jackson2JsonRedisSerializerObject> jsonSerial = new 		 Jackson2JsonRedisSerializer(Object.class);
//  //修復反序列化bug
//  ObjectMapper om = new ObjectMapper();
//  om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//  om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//  jsonSerial.setObjectMapper(om);
  template.setDefaultSerializer(jsonSerial);
  template.setKeySerializer(RedisSerializer.string());
  template.setConnectionFactory(redisConnectionFactory);
  template.afterPropertiesSet();
  return template;
 }

測試代碼為

@Test
public void redisSaveObject(){

 UserDO ob = new UserDO();
 ob.setName("name");
 ob.setCity("city");
 objectRedisTemplate.opsForValue().set("ob1",ob);
 Object ob2 = objectRedisTemplate.opsForValue().get("ob1");
 UserDO ob1 = (UserDO)ob2;
 System.out.println(ob1);

}

運行結果為

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.hcy.core.model.UserDO
at com.hcy.core.redistest.RedisTest.redisSaveObject(RedisTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at 

很明顯是對象強制轉換錯誤

這是因為泛型的原因,redis在序列化時候把他當成Object序列化的,所以這里反序列化為Object是可以的,但是因為這個Object沒有類型定義所以無法強轉。

解決辦法

在RedisTemplate中對序列化器Jackson2JsonRedisSerializer進行修改添加如下代碼,上文注釋了

  //修復反序列化bug
  ObjectMapper om = new ObjectMapper();
  om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  jsonSerial.setObjectMapper(om);

通過 objectMapper.enableDefaultTyping() 方法設置

即使使用 Object.class 作為 jcom.fasterxml.jackson.databind.JavaType 也可以實現相應類型的序列化和反序列化

好處:只定義一個序列化器就可以了(通用)

這里我們也做個測試,分別用不修改ObjectMapper的和修改了ObjectMapper的看看生成的value有啥子不一樣

運行結果:

ob1: [“com.hcy.core.model.UserDO”,{“userid”:null,“openid”:null,“name”:“name”,“city”:“city”}]

ob2: {“userid”:null,“openid”:null,“name”:“name”,“city”:“city”}

這里結果很明顯啦!!!

希望對大家有幫助!!!

以上這篇使用Redis獲取數據轉json,解決動態泛型傳參的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Redis緩存,泛型集合與json字符串的相互轉換實例
  • Java后臺返回和處理JSon數據的方法步驟
  • Java 實現Redis存儲復雜json格式數據并返回給前端

標簽:畢節 甘南 定州 泰州 伊春 河源 南寧 拉薩

巨人網絡通訊聲明:本文標題《使用Redis獲取數據轉json,解決動態泛型傳參的問題》,本文關鍵詞  使用,Redis,獲取,數據,轉,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《使用Redis獲取數據轉json,解決動態泛型傳參的問題》相關的同類信息!
  • 本頁收集關于使用Redis獲取數據轉json,解決動態泛型傳參的問題的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    中文一区二区完整视频在线观看| 国产精品一品二品| 国内精品久久久久影院色| 激情欧美一区二区三区在线观看| 老司机午夜精品| 99re这里只有精品视频首页| 日本一区二区久久| 成人国产电影网| 国产成人久久精品77777最新版本| 国产精品天干天干在线综合| 裸体在线国模精品偷拍| 欧美精品日韩综合在线| 亚洲欧美日本韩国| 亚洲精品亚洲人成人网在线播放| 亚洲欧美视频在线观看| 成人综合在线观看| 精品国产乱码久久久久久闺蜜| 欧美另类videos死尸| 日韩午夜激情av| 国产亚洲欧美色| 黄色成人免费在线| 久久久久久久久久久久电影| 国产成人在线看| 亚洲视频图片小说| 欧美一区二区三区四区视频 | 91成人免费电影| 亚洲午夜免费福利视频| 欧美电影免费观看高清完整版| 制服.丝袜.亚洲.另类.中文| 美女视频免费一区| 成人一区二区三区视频 | 国产调教视频一区| 精品国内片67194| 久久精品国产77777蜜臀| 欧美三级电影一区| 欧美天天综合网| 国产肉丝袜一区二区| 色综合久久中文综合久久牛| 欧美午夜精品一区| 中文字幕精品三区| 91麻豆免费视频| 麻豆成人91精品二区三区| 中文一区在线播放| 国产精品情趣视频| 午夜精品爽啪视频| 国产欧美一区二区精品婷婷| 欧美三级蜜桃2在线观看| 国产成人综合亚洲网站| 亚洲精品视频在线观看网站| 欧美一级专区免费大片| 91啪亚洲精品| 国产·精品毛片| 首页欧美精品中文字幕| 国产剧情一区二区| 在线观看亚洲精品视频| 精品日韩99亚洲| 欧美精品一区二区三区在线| 欧美日韩在线一区二区| 成人精品国产福利| 另类成人小视频在线| 艳妇臀荡乳欲伦亚洲一区| 国产亚洲一本大道中文在线| 6080国产精品一区二区| 国产欧美日韩视频在线观看| 日韩欧美国产精品一区| 91福利国产精品| 综合久久久久久| 91免费国产在线观看| 精品亚洲免费视频| 日韩一级在线观看| 欧美视频一区二区三区四区| a级高清视频欧美日韩| 国产东北露脸精品视频| 另类中文字幕网| 日欧美一区二区| 亚洲国产成人精品视频| 色一区在线观看| 亚洲视频在线一区二区| 欧美电影免费观看完整版| 欧美色中文字幕| 中文字幕av一区二区三区高| 欧美麻豆精品久久久久久| 日本国产一区二区| 波多野结衣在线一区| 成人在线综合网站| 成人性生交大片免费看中文| 国产精品影音先锋| 久久久av毛片精品| 欧美xxxxx牲另类人与| 欧美精品aⅴ在线视频| 91精品国产综合久久久久久| 国产一区亚洲一区| 久久精品国产精品亚洲精品| 国产片一区二区| 免费黄网站欧美| 久久se精品一区二区| 国产亚洲精品aa午夜观看| 久久日韩精品一区二区五区| 亚洲国产精品99久久久久久久久| 成人av电影在线观看| 成人a免费在线看| 在线免费观看视频一区| 欧美一区二区三区成人| 国产午夜精品一区二区三区嫩草 | 欧美色网站导航| 欧美日韩在线播| 欧美大片免费久久精品三p | 91精品国产综合久久小美女| 欧美一区二区三区精品| 中文字幕欧美三区| 亚洲一区二区三区在线看| 精品一区二区在线视频| 在线亚洲免费视频| 国产成人精品影视| 亚洲一区二区三区四区中文字幕| 日本精品一区二区三区高清| 欧美在线观看视频在线| 欧美一区二区免费视频| 91小视频免费观看| 亚洲综合激情小说| 国产综合久久久久久鬼色| 色综合久久中文字幕| 精品久久国产老人久久综合| 精品国产免费人成在线观看| 欧美日韩一区二区在线观看| 欧美激情在线一区二区三区| 亚洲午夜在线观看视频在线| 国产成人激情av| 3atv一区二区三区| 1024成人网色www| 国产在线国偷精品产拍免费yy | 久久婷婷成人综合色| 亚洲免费在线观看| 国产精品一级二级三级| 欧美一区二区三区四区视频| 色婷婷国产精品| 精品剧情v国产在线观看在线| 91成人免费电影| 亚洲欧洲美洲综合色网| 国产美女在线观看一区| 日韩一级视频免费观看在线| 亚洲免费在线播放| 粉嫩嫩av羞羞动漫久久久| 蜜臀国产一区二区三区在线播放 | 久久久蜜桃精品| 日本成人中文字幕在线视频| 欧美中文字幕亚洲一区二区va在线| av激情综合网| 久久久久国产精品麻豆ai换脸 | 国产综合色精品一区二区三区| 亚洲精品高清在线| 99re这里只有精品首页| 99视频热这里只有精品免费| 中文字幕一区二区不卡| 成人高清av在线| 中文字幕在线播放不卡一区| av在线免费不卡| 亚洲日本va午夜在线影院| av一区二区三区在线| 国产精品白丝在线| 成人国产精品免费观看动漫| 国产原创一区二区| 欧美大白屁股肥臀xxxxxx| 亚洲国产一区二区视频| 色综合天天性综合| 日韩二区在线观看| 91国产成人在线| 欧美日韩国产综合一区二区三区| 色婷婷精品久久二区二区蜜臂av| 国产三级精品三级在线专区| 国产成人免费视频| 久久久久国产免费免费 | 国产成人精品亚洲日本在线桃色| 加勒比av一区二区| 69精品人人人人| 美女网站在线免费欧美精品| 精品不卡在线视频| 国产成a人亚洲精| 亚洲欧美一区二区不卡| 欧美亚洲综合另类| 日本成人在线网站| 中文字幕av在线一区二区三区| 亚洲一区二区三区四区五区黄 | 国产欧美日韩另类视频免费观看| 久久综合狠狠综合久久激情| 成人性生交大片免费看在线播放| 欧美亚洲另类激情小说| 午夜视频在线观看一区二区三区| 国产乱一区二区| 色婷婷亚洲婷婷| 婷婷久久综合九色综合伊人色| 亚洲一区二区黄色| 日韩欧美在线123| 国产精品一区专区| 亚洲国产一区视频| 亚洲人成网站色在线观看| 九九**精品视频免费播放| 亚洲精品老司机| 日本一区二区三区视频视频| 欧美日韩国产综合草草|