解决RedisTemplate存储至缓存数据出现乱码的情况

前言

RedisTemplate是Spring对于Redis的封装。

如上图所示,RedisTemplate中定义了对5种数据结构操作。

redisTemplate.opsForList();//操作list
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForCluster();//集群时使用
redisTemplate.opsForGeo();//地理位置时使用
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set

与StringRedisTemplate的区别

StringRedisTemplate继承RedisTemplate。

它们采用的序列化策略不同:

* StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

* RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

RedisTemplate和StringRedisTemplate它们存取的数据是相互独立的。

解决办法

上文已经提及,在动手的过程中,我采用的是RedisTemplate,在传递String类型的数据结构后,查看缓存会发现数据乱码现象。

这时候我们需要修改RedisTemplate的序列化策略。

RedisSerializer<String> stringSerializer = new StringRedisSerializer();
      redisTemplate.setKeySerializer(stringSerializer);
      redisTemplate.setValueSerializer(stringSerializer);
      redisTemplate.setHashKeySerializer(stringSerializer);
      redisTemplate.setHashValueSerializer(stringSerializer);

但是注意一点,由于采用了String的序列化策略,所以只接受value值类型为String的参数。

如果像我一样传递了Integer类型的参数,直接使用toString()方法存入缓存。

ops.set("stock", redPacket.getStock().toString(),TIME_OUT, TimeUnit.SECONDS);

这样就解决了乱码问题。

附:SpringBoot启动实例化配置

@Configuration
public class RedisConfigurtion {
  @Autowired
  private RedisTemplate redisTemplate;
  @Bean
  public RedisTemplate<String, Object> stringSerializerRedisTemplate() {
    RedisSerializer<String> stringSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringSerializer);
    redisTemplate.setValueSerializer(stringSerializer);
    redisTemplate.setHashKeySerializer(stringSerializer);
    redisTemplate.setHashValueSerializer(stringSerializer);
    return redisTemplate;
  }
}

补充:redis key和value的乱码问题解决,含日期转化格式问题

在项目中,遇到的问题是redis的key和value出现的乱码问题:

而原本的内容为下:

{
  "status":"success",
  "data":{
    "id":3,
    "title":"花林",
    "price":99,
    "stock":81,
    "description":"美女一只",
    "sales":17,
    "imgUrl":"https://xiaolei1996.oss-cn-shanghai.aliyuncs.com/blog/title/we1.jpg",
    "promoStatus":2,
    "promoPrice":50,
    "promoId":1,
    "startDate":"2020-03-23 21:50:59"
  }
}

原因:

是因为和redis内部的编码协议出现了问题,所以需要改进。spring提供了一个优化方案。

springboot的redisTemplate改进。

@Component
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisConfig {
  @Bean
  public RedisTemplate redisTemplate(RedisConnectionFactory factory){
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(factory);
    //首先解决key的序列化问题
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringRedisSerializer);
    //解决value的序列化问题
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    return redisTemplate;
  }
}

比之前好了,但是还有点小问题,json的数据比以前多了,这是因为日期的转化出现问题,这块的知识触及盲区,就先把解决方案写下面,以后有时间在研究。

public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> {
  @Override
  public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss"));
  }
}
public class JodaDateTimeJsonDeserializer extends JsonDeserializer<DateTime> {
  @Override
  public DateTime deserialize(JsonParser p, DeserializationContext ctxt
  ) throws IOException, JsonProcessingException {
    String dateString= p.readValueAs(String.class);
    DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    return DateTime.parse(dateString,dateTimeFormatter);//转成
  }
}
@Component
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisConfig {
  @Bean
  public RedisTemplate redisTemplate(RedisConnectionFactory factory){
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(factory);
    //首先解决key的序列化问题
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringRedisSerializer);
    //解决value的序列化问题
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    //改进日期转化问题
    ObjectMapper objectMapper = new ObjectMapper();
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(DateTime.class,new JodaDateTimeJsonSerializer());
    simpleModule.addDeserializer(DateTime.class,new JodaDateTimeJsonDeserializer());
//解决反序列化问题 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    objectMapper.registerModule(simpleModule);
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    return redisTemplate;
  }
}

最后终于出现了预期的效果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • Java Http请求传json数据乱码问题的解决

    业务场景:调easyui的dialog打开一个弹窗,传参是用json封装的,而且有中文,然后在极速模式是正常的,在ie11测试发现中文出现乱码了 var params = JSON.stringify(writParamList); top.dialog({ id: 'noticeList', title:'列表', width:900, height:500, url:'${root}/notice/multiNoticeList.do?params='+params, onclose:fun

  • JavaWeb中获取表单数据及乱码问题的解决方法

    首先使用一个用户提交界面作为举例(文本框,密码框,选择,下拉表单等),效果如下 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="t

  • JAVA中 redisTemplate 和 jedis的配合使用操作

    首先项目A,也就是SpringBOOT项目中使用redisTemplate 来做REDIS的缓存时,你会发现存到REDIS里边的KEY和VALUE,redisTemplat使用jdkSerializeable存储二进制字节编码 项目B中使用jedis时,存储起来的是字符串,导致项目A要调用项目缓存的键值对时,获取不到 解决方案: 修改项目A的redisTemplate的序列方式 @Configuration @EnableCaching public class RedisConfig exte

  • 解决RedisTemplate存储至缓存数据出现乱码的情况

    前言 RedisTemplate是Spring对于Redis的封装. 如上图所示,RedisTemplate中定义了对5种数据结构操作. redisTemplate.opsForList();//操作list redisTemplate.opsForValue();//操作字符串 redisTemplate.opsForCluster();//集群时使用 redisTemplate.opsForGeo();//地理位置时使用 redisTemplate.opsForHash();//操作hash

  • 解决Ajax加载JSon数据中文乱码问题

    一.问题描述 使用zTree的异步刷新父级菜单时,服务器返回中文乱码,但项目中使用了SpringMvc,已经对中文乱码处理,为什么还会出现呢? 此处为的异步请求的配置: Java代码 async: { enable: true, url: basePath + '/sysMenu/listSysMenu', autoParam: ["id=parentId"] } SpringMvc中文字符处理: Java代码 <mvc:annotation-driven> <mvc

  • 解决OkHttp接收gzip压缩数据返回乱码问题

    目录 问题 请求头信息 BridgeInterceptor拦截器 问题 Retrofit 是现在最流行的网络开发框架之一,功能十分强大,但是最近确遇到一个十分坑的问题,现在记录下来,希望看到的人能注意下. 众所周知,在 HTTP 传输时是支持 gzip 压缩的,客户端发起请求时在请求头里增加 Accept-Encoding: gzip,服务端响应时在返回的头信息里增加 Content-Encoding: gzip,这表示传输的数据是采用 gzip 压缩的.默认情况下,传输内容是不压缩的,采用 g

  • 解决SpringMvc后台接收json数据中文乱码问题的几种方法

    1.使用ajax从前台页面传输数据到后台controller控制器的时候,出现中文乱码(问号???). 之前在网上找了各种解决方案,都行不通,最后发现是tomcat服务器接收数据的问题 解决方案: 方式一:在controller接收参数时,对参数进行转码 @ResponseBody @RequestMapping(value="/getJsonDataByCityName",produces="application/json") public String get

  • PHP读取mssql json数据中文乱码的解决办法

    PHP及网页使用UTF-8编码,数据库是sql server2008,使用默认编码(936,即GBK编码) 当读取数据库数据时,使用php自带的json_encode()返回到前端,结果中文不显示. 解决办法如下: 这样,sql server 2008中的中文就可以在网页正常显示了. 如果要将中文正常插入到sql server 2008中,还要加入一条代码:$query = iconv("utf-8", "gbk//ignore", $query);//为了解决中文

  • 完美解决php 导出excle的.csv格式的数据时乱码问题

    1.header('Content-Encoding: XXXX'); 有可能是编码问题:可以尝试UTF-8,GBK,GB2312,等编码格式 2.有可能是文件编码问题,虽然UTF-8不建议带BOM,但是导出的excle是微软的产品,所以需要把文件格式改成,UTF-8有BOM格式的. 以上这篇完美解决php 导出excle的.csv格式的数据时乱码问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • mysql导入导出数据中文乱码解决方法小结

    linux系统中 linux默认的是utf8编码,而windows是gbk编码,所以会出现上面的乱码问题. 解决mysql导入导出数据乱码问题 首先要做的是要确定你导出数据的编码格式,使用mysqldump的时候需要加上--default-character-set=utf8, 例如下面的代码: 复制代码 代码如下: mysqldump -uroot -p --default-character-set=utf8 dbname tablename > bak.sql 那么导入数据的时候也要使用-

  • node使用mysql获取数据库数据中文乱码问题的解决

    参考链接:StackOverflow 问题 问题描述 在学习使用 nodejs 写 web 服务的时候,在用 mysql 获取数据库信息的时候,返回的中文一直是乱码,无论配置 charset 与否,都是乱码. 问题根源 其实这个问题不在 mysql 那边,在配置了 charet 之后,数据库获取到的数据已经不是乱码了,这个乱码是 http 服务器那边的问题 解决方法 在 http 响应数据的头部添加 charset=utf-8 即可 res.setHeader('Content-Type', '

  • 解决使用httpclient传递json数据乱码的问题

    今天用httpclient传输json数据,服务端接受数据 中文乱码,下面分别贴上修改前与修改后的代码以及原因分析 (1)修改前: client端 public String sendHttpPost(String httpUrl, String data) { // 创建post请求 HttpPost httpPost = new HttpPost(httpUrl); StringEntity entity; try { entity = new StringEntity(data); ent

  • 基于Redis缓存数据常见的三种问题及解决

    目录 1.缓存穿透 1.1 问题描述 1.2 解决方法 2.缓存击穿 2.1 问题描述 2.2 解决方法 3.缓存雪崩 3.1 问题描述 3.2 解决方法 1.缓存穿透 1.1 问题描述 缓存穿透是在客户端/浏览器端请求一个不存在的key,这个key在redis中不存在,在数据库中也不存在数据源,每次对此key的请求从缓存获取不到,就会请求数据源. 如使用一个不存在的用户id去访问用户信息,redis和数据库中都没有,多次进行请求可能会压垮数据源 1.2 解决方法 一个一定不存在缓存及查询不到的

随机推荐