筆者曾經對redis鍵值使用了不一樣類型的序列化方法html
用過默認值、JdkSerializationRedisSerializer、StringRedisSerializer還用改如下自定類型的序列化工具類(聽說這個比Spring RedisTemplate的序列化、反序列化快)java
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; } }
遇到過如下異常:redis
hash操做:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String,而後此次又換另一個Hash的序列化類spring
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 floatspringboot
,由於通過ProtostuffSerializer序列化的hash值會變形,編程、\X0A=\X5A\X43\XC格式的數據,進行數值運算報錯。app
注意事項:redis端increment操做,只支持double和long,因此數據要進行相關轉換。ide
好比筆者代碼以下,就會報錯:工具
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存儲數據,出現\xAC\xED\x00\x05t\x00
參考: