• Redis 自定义对象 cannot be cast to java.lang.String


    Redis序列化对象的时候报错如下

    java.lang.ClassCastException: com.ppdai.cbd.ddp.thirdparty.contract.bhxtzx.BHXTZXTask cannot be cast to java.lang.String
            at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:33)
            at org.springframework.data.redis.core.AbstractOperations.rawValue(AbstractOperations.java:117)
            at org.springframework.data.redis.core.DefaultListOperations.leftPush(DefaultListOperations.java:71)
            at org.springframework.data.redis.core.DefaultBoundListOperations.leftPush(DefaultBoundListOperations.java:60)
            at com.ppdai.realtime.datachannel.pullservice.entity.RedisQueue.pushFromHead(RedisQueue.java:63)
            at com.ppdai.realtime.datachannel.pullservice.redisconfig.RedisTaskSender.sendTask(RedisTaskSender.java:35)
            at com.ppdai.realtime.datachannel.pullservice.redisconfig.RedisTaskSender$sendTask.call(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    BHXTZXTask是自己定义的Bean,因此问题就变成了自定义的对象不能转成String对象,为什么会需要转成String对象呢

    因为redis默认使用jdkSerializer,看RedisTemplate的代码如下,

    afterPropertiesSet函数
    public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
    
        public void afterPropertiesSet() {
    
            super.afterPropertiesSet();
    
            boolean defaultUsed = false;
    
            if (defaultSerializer == null) {
    
                defaultSerializer = new JdkSerializationRedisSerializer(
                        classLoader != null ? classLoader : this.getClass().getClassLoader());
            }
    
            if (enableDefaultSerializer) {
    
                if (keySerializer == null) {
                    keySerializer = defaultSerializer;
                    defaultUsed = true;
                }
                if (valueSerializer == null) {
                    valueSerializer = defaultSerializer;
                    defaultUsed = true;
                }
                if (hashKeySerializer == null) {
                    hashKeySerializer = defaultSerializer;
                    defaultUsed = true;
                }
                if (hashValueSerializer == null) {
                    hashValueSerializer = defaultSerializer;
                    defaultUsed = true;
                }
            }
    
            if (enableDefaultSerializer && defaultUsed) {
                Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
            }
    
            if (scriptExecutor == null) {
                this.scriptExecutor = new DefaultScriptExecutor<K>(this);
            }
    
            initialized = true;
        }
    }

    查看源码,如下,通过rawValue()函数获取序列化之后的字节码

    public Long leftPush(K key, V value) {
            final byte[] rawKey = rawKey(key);
            final byte[] rawValue = rawValue(value);
            return execute(new RedisCallback<Long>() {
    
                public Long doInRedis(RedisConnection connection) {
                    return connection.lPush(rawKey, rawValue);
                }
            }, true);
        }
    private byte[] rawValue(Object value) {
    if (valueSerializer == null && value instanceof byte[]) {
    return (byte[]) value;
    }
    return valueSerializer.serialize(value);
    }
     

    通过 valueSerializer序列化来序列化对象, redis如果不配置,默认 valueSerializer的序列化是会使用

    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
            JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
    
            System.out.println(redisTemplate.hasKey("bohai_credit"));
            redisTemplate.delete("bohai_credit");
    
            System.out.println(stringRedisSerializer.serialize("bohai_credit"));
            System.out.println(jdkSerializationRedisSerializer.serialize("bohai_credit"));
    [B@21831984
    [B@4488db1f

    运行结果如上所示。

    欢迎关注Java流水账公众号
  • 相关阅读:
    SpringBoot整合ActiveMQ同时支持P2P和发布订阅模式(三)
    SpringBoot整合ActiveMQ的publish/subscribe发布订阅模式(二)
    Windows启动ActiveMQ报Wrapper Stopped错误
    IDEA从远程仓库克隆项目
    Git的安装
    IDEA上传项目到使用github上
    Mybaits的逆向工程
    posman测试接口需要登录验证的使用
    SSM整合SpringSecurity
    SpringBoot整合MongoDB的连接用户名和密码问题
  • 原文地址:https://www.cnblogs.com/guofu-angela/p/9965406.html
Copyright © 2020-2023  润新知