栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot-redis整合并使用fastjason作序裂化器,存取类对象

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot-redis整合并使用fastjason作序裂化器,存取类对象

目的
@SpringBootTest
class Springboot01ApplicationTests {

    @Autowired
    private  RedisTemplate redisTemplate;
    @Test
    public void redis() {
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        Motor motor = new Motor(1234, 22, 1, 1, 1, 1, 1, 1);
        redisTemplate.opsForValue().set("cwd",motor);
        //Motor cwd = (Motor) redisTemplate.opsForValue().get("cwd");
        //System.out.println(cwd.getTargetPosition());
    }
  }

使用默认的序列化器,直接使用 redisTemplate.opsForValue().set("cwd",motor);这样的语句是会报错的,直接解析更是无从谈起。想要完成注释掉的这几个语句正常执行,需要使用新的解析器。

org.springframework.data.redis.serializer.
SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.
SerializationFailedException:
Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: 
DefaultSerializer requires a Serializable payload but received an object of type [com.example.springboot01.pojo.Motor]

Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.example.springboot01.pojo.Motor]
	
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.example.springboot01.pojo.Motor]

方法一:Jackson2JsonRedisSerializer序列化器

使用自带的Jackson2JsonRedisSerializer序列化器,增加一个javaconfig类

@Configuration
public class rediscConfig {
    @Bean
    public RedisTemplate MyRedisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws Exception {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 设置其他的k-v的默认的序列化
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer(Object.class));
        //单独设置k的序列化
        template.setKeySerializer(new StringRedisSerializer());
        return template;
    }
}

测试类

@SpringBootTest
class Springboot01ApplicationTests {
    @Autowired
    @Qualifier("MyRedisTemplate")
    private  RedisTemplate redisTemplate;
    @Test
    public void redis() {
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        Motor motor = new Motor(1234, 22, 1, 1, 1, 1, 1, 1);
        redisTemplate.opsForValue().set("cwd",motor);
        //Motor cwd = (Motor) redisTemplate.opsForValue().get("cwd");
    }
 }

这样测试类中可以set一个对象,但是获取(注释语句)仍会报错。

class java.util.linkedHashMap cannot be cast to class com.example.springboot01.pojo.Motor 
(java.util.linkedHashMap is in module java.base of loader 'bootstrap'; 
com.example.springboot01.pojo.Motor is in unnamed module of loader 'app')

插入是成功的,可以看到redis中插入了cwdkey的json字符串
{
“motorindex”:1234,
“opmode”:22,
“targetPosition”:1,
“targetTorque”:1,
“targetVelocity”:1,
“currentPosition”:1,
“currentTorque”:1,
“currentVelocity”:1
}

方法二:FastJsonRedisSerializer序列化器

FastJson是阿里巴巴的Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。需要maven导入java包


    com.alibaba
    fastjson
    1.2.78

自己编写FastJsonRedisSerializer,需要实现RedisSerializer接口即可。

package com.example.springboot01.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.Charset;

public class FastJsonRedisSerializer implements RedisSerializer {
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private Class clazz;

    public FastJsonRedisSerializer(Class clazz) {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (null == t) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (null == bytes || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) JSON.parseObject(str, clazz);
    }
}

修改配置类

@Configuration
public class rediscConfig {
    @Bean
    public RedisTemplate MyRedisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws Exception {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
//使用fastjson序列化
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);
        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

测试类中,因为FastJson中AutoType反序列化漏洞,需要加入一行代码配置,将其加入到静态代码块。

class Springboot01ApplicationTests {

    static {
        ParserConfig.getGlobalInstance().addAccept("com.example.springboot01.pojo");
    }

    @Autowired
    @Qualifier("MyRedisTemplate")
    private  RedisTemplate redisTemplate;

    @Test
    public void redis() {

        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        Motor motor = new Motor(1234, 22, 1, 1, 1, 1, 1, 1);
        redisTemplate.opsForValue().set("cwd",motor);

        Motor cwd = (Motor) redisTemplate.opsForValue().get("cwd");
        //System.out.println(cwd.getTargetPosition());
    }
}

测试通过。
观察redis注入的json
{
“@type”:“com.example.springboot01.pojo.Motor”,
“currentPosition”:1,
“currentTorque”:1,
“currentVelocity”:1,
“motorindex”:1234,
“opmode”:22,
“targetPosition”:1,
“targetTorque”:1,
“targetVelocity”:1
}
多了一个内容标记实体类所在目录,故而就可以成功解析回去

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/362216.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号