Redis反序列化--操作java对象

这篇具有很好参考价值的文章主要介绍了Redis反序列化--操作java对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Redis反序列化–操作java对象

1.前言:
  • 前段时间完成一个需求,上线之后发现每次发起请求服务器查询数据太慢了,组长便说加个两分钟的缓存。便打算使用reids做缓存,因为这个接口返回的是一个java对象,就遇到了序列化的问题。
  • 针对数据的“序列化和反序列化”,提供了多种策略(RedisSerializer)
    默认为使用JdkSerializationRedisSerializer,同时还有StringRedisSerializer,JacksonJsonRedisSerializer,OxmSerializer,GenericFastJsonRedisSerializer。
2.RedisTemplate的两种序列化实践方案
  • 方案一:(内存开销较大,会存储多余的字节码)
    1.自定义RedisTemplate
    2.修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer(bean注入)
  • 方案二:(节省内存空间、步骤麻烦需要手动处理数据)
    1.使用StringRedisTemplate
    2.写入Redis时,手动把对象序列化为JSON
    3.读取Redis时,手动把读取到的JSON反序列化为对象
3.方案一具体实现

1.依赖(版本继承了SpringBoot版本)

  • maven依赖
// maven依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

  • gradle依赖
implementation "org.springframework.boot:spring-boot-starter-redis:1.3.5.RELEASE"

2.RedisConfig类

  • 添加bean,指定key/value以及HashKey和HashValue的序列化和反序列化为FastJson的。
package com.cmft.ff.config.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;

/**
 * @Author: zeng_shuqi
 * @DateTime: 2023/3/28 10:00
 **/

@Configuration
public class RedisConfig {


    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用 GenericFastJsonRedisSerializer 替换默认序列化
        GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        // 设置key和value的序列化规则
        redisTemplate.setKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);
        // 设置hashKey和hashValue的序列化规则
        redisTemplate.setHashKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer);
        // 设置支持事物
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

3.操作redis

  • service实现类
@Service
@Slf4j
public class HuaFeiBoardClickhouseServiceImpl implements HuaFeiBoardClickhouseService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    public static final String KEY = "businessLineBO";
    @Override
    public BrokenBusinessLineBO getCountAndResponseTime() {
    	// 当key不存在时
		 if (!redisTemplate.hasKey(KEY)) {
		  // 逻辑代码 .....

		 // 将对象存储到reids当中、key120秒过期  bo = value 代表你要存储的java对象
		  redisTemplate.opsForValue().set(KEY, bo, 120, TimeUnit.SECONDS);
		 }
		 // 当key存在时、根据key从redis获取数据  
		 return (BrokenBusinessLineBO) redisTemplate.opsForValue().get(KEY);
	}
    
}
4.方案二具体实现

1.如上一样需要配置依赖

Redis反序列化--操作java对象

  • 为了节省内存空间,我们并不会使用]SON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储lava对象时,手动完成对象的序列化和反序列化。

  • service实现类 Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定
    义RedisTemplate的过程:

  • Jackson ObjectMapper类(com.fasterxml.jackson.databind.ObjectMapper)是使用Jackson解析JSON最简单的方法。Jackson ObjectMapper可以从字符串、流或文件解析JSON,并创建Java对象或对象图来表示已解析的JSON文章来源地址https://www.toymoban.com/news/detail-401762.html

@Service
@Slf4j
public class HuaFeiBoardClickhouseServiceImpl implements HuaFeiBoardClickhouseService {
   
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    public static final String KEY = "businessLineBO";
    // spring使用的是这个,大家也可以使用自己熟悉的解析工具
    private final static ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public BrokenBusinessLineBO getCountAndResponseTime() throws JsonProcessingException { // 这里会抛出一个异常
    	// 当key不存在时
		 if (!stringRedisTemplate.hasKey(KEY)) {
		   // 逻辑代码 .....
		   // 手动将java对象序列化
            String json = objectMapper.writeValueAsString(bo);
            stringRedisTemplate.opsForValue().set(KEY, json, 120, TimeUnit.SECONDS);
            return bo;
		 }
		  // 获取key
        String json = stringRedisTemplate.opsForValue().get(KEY);
        // 反序列化
        BrokenBusinessLineBO businessLineBO = objectMapper.readValue(json, BrokenBusinessLineBO.class);
        return businessLineBO;
	}
    
}
5.总结
  • 第一种方案

  • 优点:方便快捷存储java对象,只需要配置bean让spring扫描;
  • 内存开销较大,会存储多余的字节码;
  • 第二种方案

  • 优点:节省内存空间
  • 缺点:步骤麻烦需要手动处理数据(可以自定义封装一个工具类)
  • 至此,两种常用的解决方案就结束了,不明白的小伙伴可以留言我及时解答

到了这里,关于Redis反序列化--操作java对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

    1.类什么时候被加载到JVM中,new,Class.forName: Class.forName(“包名.类名”); 2.创建对象的方式,反射,本质是获得类的类对象Class; 3.克隆clone,深拷贝,浅拷贝的对比; 4.序列化和反序列化的方式; Hello h; // 此时没有用Hello,jvm并没有进行类加载 看到new : new Book() Class.forName:

    2024年02月12日
    浏览(33)
  • 【优化技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路

    序列化和反序列化 序列化就是指把对象转换为字节码; 对象传递和保存时,保证对象的完整性和可传递性。把对象转换为有字节码,以便在网络上传输或保存在本地文件中; 反序列化就是指把字节码恢复为对象; 根据字节流中保存的对象状态及描述信息,通过反序列化重建

    2024年01月22日
    浏览(39)
  • Qt 对象序列化/反序列化

    阅读本文大概需要 3 分钟 日常开发过程中,避免不了对象序列化和反序列化,如果你使用 Qt 进行开发,那么有一种方法实现起来非常简单和容易。 我们知道 Qt 的元对象系统非常强大,基于此属性我们可以实现对象的序列化和反序列化操作。 比如有一个学生类,包含以下几

    2024年02月13日
    浏览(28)
  • springboot对象序列化自定义序列化注解

    在开发中有时候会遇到一些内容返回时需要翻译,或者一些内容在序列化之前需要特殊处理(脱敏啥的)。 一般对单个属性可以直接用 jackson 的序列化注解对某个属性单独处理 com.fasterxml.jackson.databind.annotation.JsonSerialize(using= xxx.class) 但是直接使用不太灵活,可以进一步引入注

    2024年02月07日
    浏览(37)
  • 4.4. 对象序列化与反序列化

    在本节中,我们将详细讨论Java中的对象序列化与反序列化概念、使用方法以及实例。对象序列化是将对象的状态信息转换为字节流的过程,而反序列化则相反,是将字节流恢复为对象的过程。 4.4.1 为什么需要对象序列化? 对象序列化的主要目的是为了在不同的系统间传输对

    2024年02月07日
    浏览(39)
  • SharedPreferences工具类保存List对象,自动完成序列化和反序列化

    以下是一个示例的SharedPreferences工具类,其中包含了setList()和getList()方法,用于将List序列化为JSON字符串并存储到SharedPreferences中,以及从SharedPreferences中获取JSON字符串并反序列化为List对象: 在上述代码中,我们定义了一个SharedPreferencesUtils工具类,其中包含了setList()和getLis

    2024年02月16日
    浏览(27)
  • 序列化实现对象的拷贝

    提到拷贝,大家第一时间想到的可能都是克隆模式的深克隆,因为这个模式在面试中出现的机率非常高,同时实现的方式也比较容易:对象的类实现Cloneable接口并且重写clone()方法即可。但是在实际情况中克隆模式有时候其实并不适合用来拷贝对象,因为如果有很多的实体类都

    2023年04月19日
    浏览(25)
  • RabbitMQ 消息对象通过 Jackson 库消息转化器 序列化/反序列化 天坑!

    目录 1. 报错的背景 2. 问题分析 3. 最佳解决办法 a)使用 RabbitMQ 发送消息时,发送消息的类型为 MapString, Object,map 里面我 put 了一个 String, Long 类型,如下图: b)这里有一个前提:我清楚使用 org.springframework.amqp.rabbit.core.RabbitTemplate 来发送消息到 RabbitMQ 队列时,消息的序列

    2024年04月15日
    浏览(51)
  • redis 中文存储的序列化配置

    redis 中文存储的序列化配置 为了解决 Redis 中文存储时出现的乱码问题,通常需要设置合适的序列化器。在 Spring Boot 应用中,使用 Jackson2JsonRedisSerializer 或 GenericJackson2JsonRedisSerializer 作为序列化器是一种常见的做法。这两种序列化器都会使用 UTF-8 编码,从而避免了中文乱码问

    2024年02月02日
    浏览(30)
  • Python中关于对象序列化实现和原理

    pickle模块可以实现任意的Python对象转换为一系列字节(即序列化对象)的算法。这些字节流可以被传输或存储,接着也可以重构为—个和原先对象具有相同特征的新对象。 注意: pickle的文档清晰的表明它不提供安全保证。实际上,反序列化后可以执行任意代码,所以慎用 pick

    2024年02月03日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包