在使用redis的过程中,存入数据乱码,还有反序列化异常问题,
Exception in thread "main" org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:81)
at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:315)
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:55)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:202)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:164)
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:88)
at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43)
at com.lichen.test.RolesTest.main(RolesTest.java:30)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:79)
... 7 more
Caused by: java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2679)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3424)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:3224)
at java.io.ObjectInputStream.readString(ObjectInputStream.java:1903)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1562)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:72)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73)
... 9 more
这是我在ssm整合redis的时候配置文件的编写,但是注意一点,由于采用了String的序列化策略,所以只接受value值类型为String的参数,如果像我一样传递了包装数据类型或者pojo队形的参数,直接使用toString()方法存入缓存。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--整合redis 开始-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数 -->
<property name="maxIdle" value="50" />
<!--最大连接数 -->
<property name="maxTotal" value="100" />
<!--最大等待时间 -->
<property name="maxWaitMillis" value="20000" />
</bean>
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost" />
<property name="port" value="6379" />
<!--<property name="password" value="paasword"/> -->
<property name="poolConfig" ref="poolConfig" />
</bean>
<!--StringRedisSerializer:字符串编码,数据以string存储
但是注意一点,由于采用了String的序列化策略,
所以只接受value值类型为String的参数,
如果像我一样传递了包装数据类型或者pojo队形的参数,
直接使用toString()方法存入缓存。
-->
<bean id="StringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer" ref="StringRedisSerializer" />
<property name="valueSerializer" ref="stringRedisSerializer" />
</bean>
<!--整合redis 开始-->
</beans>
这边介绍一下serializer策略
spring-data-redis提供了多种serializer策略,这对使用jedis的开发者而言,实在是非常便捷。提供了4种内置的serializer:
- JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储
- StringRedisSerializer:字符串编码,数据以string存储
- JacksonJsonRedisSerializer:json格式存储
- OxmSerializer:xml格式存储
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,其 中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。
RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:
1) keySerializer :对于普通K-V操作时,key采取的序列化策略
2) valueSerializer:value采取的序列化策略
3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
4) hashValueSerializer:hash-value的序列化策略
无论如何,建议key/hashKey采用StringRedisSerializer。