婷婷综合国产,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
    亚洲五码中文字幕| 一区二区三区在线免费| 欧美日韩国产一级片| 91在线无精精品入口| 国产成+人+日韩+欧美+亚洲| 精品一区二区在线免费观看| 久久99久久精品| 国产激情视频一区二区三区欧美| 日韩国产欧美一区二区三区| 欧美96一区二区免费视频| 日本v片在线高清不卡在线观看| 亚洲va欧美va人人爽午夜| 亚洲综合小说图片| 免费观看在线色综合| 国产精品99久久久久久久vr| 成人av在线播放网址| 99re视频精品| 91精品国产综合久久香蕉的特点 | 中文一区在线播放| 国产精品久久久久久户外露出| 亚洲国产另类精品专区| 免费成人美女在线观看| 成人v精品蜜桃久久一区| 欧美综合久久久| 亚洲一区二区黄色| 日本不卡1234视频| 91久久线看在观草草青青| 久久免费国产精品| 免费在线看一区| 欧美日韩一卡二卡三卡 | 欧美日韩高清影院| 亚洲免费在线看| 欧洲精品在线观看| 国产亚洲一区二区三区在线观看| 日韩成人av影视| 日韩欧美一区中文| 日韩av成人高清| 欧美一级精品在线| 首页综合国产亚洲丝袜| 91精品免费观看| 日本视频中文字幕一区二区三区| 欧美日韩在线综合| 日本少妇一区二区| 欧美一区二区三级| 激情六月婷婷久久| 国产亚洲女人久久久久毛片| 97se亚洲国产综合自在线观| 亚洲日本中文字幕区| 欧美日韩亚洲另类| 国内不卡的二区三区中文字幕| 国产日韩欧美高清在线| 91视频在线观看| 天堂久久久久va久久久久| 久久免费看少妇高潮| 成人在线视频首页| 午夜精品福利一区二区蜜股av | 亚洲精品五月天| 欧美精品亚洲二区| 国产精品一线二线三线| 玉米视频成人免费看| 精品久久人人做人人爽| 91小视频在线观看| 国产成人在线视频网址| 亚洲美女免费视频| 欧美国产日韩亚洲一区| 7878成人国产在线观看| 欧美在线视频日韩| 成人激情黄色小说| 久久激情五月婷婷| 丝袜亚洲另类丝袜在线| 一区二区三区中文在线观看| 日本一区二区免费在线| 日韩一区国产二区欧美三区| 国产亚洲一区二区三区在线观看| 在线观看视频一区二区欧美日韩| 成人免费视频一区| 国产高清不卡二三区| 国产精品一卡二卡在线观看| 蜜桃视频在线观看一区二区| 亚洲电影一级黄| 亚洲另类在线视频| 一区二区三区蜜桃| 亚洲影院久久精品| 亚洲午夜免费福利视频| 亚洲成人一区二区| 麻豆国产精品777777在线| 久久99久久久久| 国产成人综合自拍| 91日韩在线专区| 538prom精品视频线放| 日韩美女在线视频| 久久亚洲一级片| 亚洲色图19p| 午夜欧美大尺度福利影院在线看| 美女性感视频久久| 国产麻豆精品一区二区| 成人美女视频在线观看| 一本久久精品一区二区| 日韩午夜在线观看| 亚洲精品亚洲人成人网在线播放| 天天亚洲美女在线视频| 国产成人在线电影| 欧美精品 国产精品| 国产精品美女久久久久aⅴ国产馆| 一区二区成人在线观看| 极品少妇一区二区| 欧美午夜不卡在线观看免费| 欧美激情一区二区三区蜜桃视频| 亚洲国产成人va在线观看天堂| 丁香婷婷综合激情五月色| 欧美剧在线免费观看网站| 国产精品视频九色porn| 日韩成人av影视| 在线观看视频一区| 亚洲色图在线视频| 成人福利视频在线看| 国产免费久久精品| 激情综合色丁香一区二区| 欧美精品在欧美一区二区少妇| 国产精品区一区二区三区| 国内外成人在线| 欧美精品一区二区三区在线 | 国产无人区一区二区三区| 99麻豆久久久国产精品免费| 欧美一个色资源| 午夜精品免费在线| 宅男噜噜噜66一区二区66| 亚洲观看高清完整版在线观看| 在线观看免费视频综合| 樱桃国产成人精品视频| 色综合天天视频在线观看| 中文字幕一区二区视频| 99精品偷自拍| 性欧美大战久久久久久久久| 91精品国产综合久久蜜臀 | 欧美mv日韩mv亚洲| 国内精品国产成人| 亚洲欧洲www| 欧美中文字幕一区二区三区| 日韩在线一区二区| 久久久国产综合精品女国产盗摄| 爽好多水快深点欧美视频| 精品国产电影一区二区| 成人爱爱电影网址| 奇米888四色在线精品| 国产清纯在线一区二区www| 91丨porny丨首页| 久久精品99国产精品| 中文字幕一区二区三区不卡| 欧美浪妇xxxx高跟鞋交| 成人av资源在线| 另类调教123区| 亚洲午夜在线电影| 国产精品理论在线观看| 欧美一区二区黄| 欧美性生活大片视频| 成人综合婷婷国产精品久久蜜臀 | 欧美一区二区三区在线视频 | 中文字幕在线一区免费| 日韩精品一区二区三区swag| 久久免费美女视频| 7777精品伊人久久久大香线蕉经典版下载| 国产精品一二三四区| 美日韩一区二区三区| 免费在线观看一区二区三区| 亚洲精品国产一区二区三区四区在线 | 日韩一级免费观看| 欧美日韩一区二区三区在线看 | 蓝色福利精品导航| 美女高潮久久久| 久久se这里有精品| 麻豆91在线观看| 国产一区二区三区免费观看| 久久精品999| 国产成人精品亚洲日本在线桃色 | 日韩一区国产二区欧美三区| 欧美三级日韩三级| 亚洲一区二区三区四区的| 中文字幕乱码一区二区免费| 国产日韩欧美一区二区三区乱码 | 在线观看免费亚洲| 欧美日韩亚洲综合一区| 宅男噜噜噜66一区二区66| 精品国产乱码久久久久久夜甘婷婷 | 国产精品福利影院| 亚洲欧美激情视频在线观看一区二区三区| 国产精品国模大尺度视频| 一区二区三区中文字幕电影| 日韩**一区毛片| 成人免费av在线| 91麻豆精品91久久久久久清纯| 久久久久九九视频| 亚洲成人一区在线| 国产91露脸合集magnet| 91精品婷婷国产综合久久| 中文字幕精品一区二区精品绿巨人| 亚洲国产精品自拍| 国产传媒日韩欧美成人| 欧美日韩免费高清一区色橹橹| 中文字幕在线一区二区三区|