• spring redistemplate中使用setHashValueSerializer的设置hash值序列化方法


    笔者曾经对redis键值使用了不同类型的序列化方法

    用过默认值、JdkSerializationRedisSerializer、StringRedisSerializer还用改以下自定类型的序列化工具类(据说这个比Spring RedisTemplate的序列化、反序列化快)

    import com.dyuproject.protostuff.LinkedBuffer;
    import com.dyuproject.protostuff.ProtostuffIOUtil;
    import com.dyuproject.protostuff.Schema;
    import com.dyuproject.protostuff.runtime.RuntimeSchema;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.SerializationException;
    
    public class ProtostuffSerializer implements RedisSerializer<Object> {
    
        private boolean isEmpty(byte[] data) {
            return (data == null || data.length == 0);
        }
    
        private final Schema<ProtoWrapper> schema;
    
        private final ProtoWrapper wrapper;
    
        private final LinkedBuffer buffer;
    
        public ProtostuffSerializer() {
            this.wrapper = new ProtoWrapper();
            this.schema = RuntimeSchema.getSchema(ProtoWrapper.class);
            this.buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        }
    
        @Override
        public byte[] serialize(Object t) throws SerializationException {
            if (t == null) {
                return new byte[0];
            }
            wrapper.data = t;
            try {
                return ProtostuffIOUtil.toByteArray(wrapper, schema, buffer);
            } finally {
                buffer.clear();
            }
        }
    
        @Override
        public Object deserialize(byte[] bytes) throws SerializationException {
            if (isEmpty(bytes)) {
                return null;
            }
    
            ProtoWrapper newMessage = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(bytes, newMessage, schema);
            return newMessage.data;
        }
    
        private static class ProtoWrapper {
    
            public Object data;
    
        }
    }

    遇到过以下异常:

    hash操作:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String,然后这次又换另外一个Hash的序列化类

    template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

    序列化后的缓存如下:

    因为上次使用ProtostuffSerializer对Hash值进行序列化,进行以下操作报错了

    HashOperations<String,String,T> hashOperations = redisTemplate.opsForHash();
    
            if(value instanceof Long || value instanceof Integer|| value instanceof Short||value instanceof Byte)
            {
                long longValue = ((Number) value).longValue();
                hashOperations.increment(key,field,longValue);
            }
    
            if(value instanceof Float ||value instanceof  Double)
            {
                double doubleValue = ((Number) value).doubleValue();
                Double returned = hashOperations.increment(key, field, -0.005);
            }
            return hashOperations;

    报错如下:io.lettuce.core.RedisCommandExecutionException: ERR hash value is not a valid float

    ,因为经过ProtostuffSerializer序列化的hash值会变形,编程、X0A=X5AX43XC格式的数据,进行数值运算报错。

    注意事项:redis端increment操作,只支持double和long,所以数据要进行相关转换。

    比如笔者代码如下,就会报错:

     public <T> T getCacheHashValue(String key, String field, Class<T> targetClass) {
            HashOperations<String,String,T> hashOperations = redisTemplate.opsForHash();
            return hashOperations.get(key, field);
        }

    传入

    Float balance = cacheService.getCacheHashValue(cacheKey, "balance", Float.class);

    报错:

    Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float

    redisTemplate相关文章:

    springboot项目中使用spring-data-Redis对map序列化时报错

    使用redisTemplate存储数据,出现xACxEDx00x05tx00

     参考:

    Spring-data-redis @Cacheable java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String

  • 相关阅读:
    Python 单向循环链表
    python 单向链表实现
    Python实现栈
    单进程-非阻塞服务器
    Nginx开发从入门到精通
    Spring入门第十五课
    Spring入门第十六课
    Spring入门第十四课
    Spring入门第十三课
    Spring入门第十二课
  • 原文地址:https://www.cnblogs.com/passedbylove/p/12084731.html
Copyright © 2020-2023  润新知