Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

问题描述

springboot 2.3.7 想存取java对象到redis中去,但是能存不能取,并且存进去的值看起来不太对。

redis 5.0.4

问题出现的环境背景及自己尝试过哪些方法

开始用 springboot 2.2.2 版本,不行,升级到2.3.7后还是不行。
用Jedis 替换默认的 Lettuce 也不行
按照网上的教程配置 RedisConfig 配置类,来序列化对象,不行
自己手动写了个序列化工具类不行

已单独尝试 Jedis 和 Lettuce 进行对象的存取,没毛病

### 相关代码

@Configuration
//@EnableCaching
//@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {
    @Bean("redisTemplates")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 配置 json 序列化器 - Jackson2JsonRedisSerializer
        Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //ObjectMapper类是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构
        ObjectMapper objectMapper = new ObjectMapper();
        //配置全局序列化参数
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSerializer.setObjectMapper(objectMapper);

        // 创建并配置自定义 RedisTemplateRedisOperator
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 将 key 序列化成字符串
        template.setKeySerializer(new StringRedisSerializer());
        // 将 hash 的 key 序列化成字符串
        template.setHashKeySerializer(new StringRedisSerializer());
        // 将 value 序列化成 json
//        template.setValueSerializer(jacksonSerializer);
        template.setValueSerializer(new RedisObjectSerializer());
        // 将 hash 的 value 序列化成 json
        template.setHashValueSerializer(new RedisObjectSerializer());
        template.afterPropertiesSet();
        return template;
    }

    class RedisObjectSerializer implements RedisSerializer<Object> {

        @Override
        public Object deserialize(byte[] bytes) {
            Object obj = SerializeUtil.unserialize(bytes);
            return obj;
        }

        @Override
        public byte[] serialize(Object object) {
            byte[] bytes = SerializeUtil.serialize(object);
            return bytes;
        }
    }
}

其中

template.setValueSerializer( jacksonSerializer);

不管是用自己的还是 jacksonSerializer都一样。

你期待的结果是什么?实际看到的错误信息又是什么?

跟了一下代码,发现存入redis之前序列化的byte[]大概长这样
image

存入之后,从redis中读取出来就变成这样了
image
明显就不是一个东西,所以在反序列化的时候,就会报一个不太相关的错误:

java.io.StreamCorruptedException: invalid stream header: 00000000
    at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:946)
    at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:385)
    at cn.zj.service.util.SerializeUtil.unserialize(SerializeUtil.java:36)
    at cn.zj.service.config.RedisConfig$RedisObjectSerializer.deserialize(RedisConfig.java:117)
    at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:335)
    at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:61)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:228)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:188)
    at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:96)
    at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:53)

如果我用 jacksonSerializer 的话,报错如下

17:09:18.860 logback [http-nio-8090-exec-5] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/zj] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Illegal character ((CTRL-CHAR, code 0)): only regular white space (
, 
, ) is allowed between tokens
 at [Source: (byte[])""[truncated 604356 bytes]; line: 1, column: 2]; nested exception is com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 0)): only regular white space (
, 
, ) is allowed between tokens
 at [Source: (byte[])""[truncated 604356 bytes]; line: 1, column: 2]] with root cause
com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 0)): only regular white space (
, 
, ) is allowed between tokens
 at [Source: (byte[])""[truncated 604356 bytes]; line: 1, column: 2]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1851)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:707)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._throwInvalidSpace(ParserMinimalBase.java:685)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._skipWSOrEnd(ReaderBasedJsonParser.java:2403)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:672)
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4664)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4513)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3572)
    at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:73)

请教到底是该怎么存进去?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
3.7k views
Welcome To Ask or Share your Answers For Others

1 Answer

序列化和反序列化方式不一样
序列化用的jackson,反序列化用的对象流,肯定读不回来
配成一样的就行了


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...