Cachecloud的spring接入 以及RedisTemplate SerializationFailedException: Failed to deserialize payload 异常解决

    公司项目接入Redis CacheCloud(Redis监控运维云平台CacheCloud),统一管理redis时,因为是Spring项目,采用的是xml方式接入,适用于非springboot的工程(当然,也有适用于springboot工程的,配置文件接入方式)。 大体上的流程如下:

如下配置增加到你的pom.xml中

<dependency>
     <groupId>com.ppdai.cachecloud</groupId>
     <artifactId>cachecloud-spring-client</artifactId>
     <version>0.0.2</version>

 </dependency>

然后在xml配置中增加cachecloud配置部分,参考demo工程的cache-spring.xml文件,需要注意的是:采用构造方法注入方式,如果是cluster模式,有3个构造参数,如果是standalone模式,有2个构造参数。  

demo工程:cachecloud-spring-client-demo.zip(本地所有)

具体涉及到的配置内容如下:

以下是spring-cache.xml配置文件

<?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:cache="http://www.springframework.org/schema/cache"
	xmlns:c="http://www.springframework.org/schema/c"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
                       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
    ">

	<context:property-placeholder location="classpath:/application.properties" />
	<context:component-scan base-package="com.ppdai.cachecloud.spring" />
	<aop:aspectj-autoproxy proxy-target-class="true" />
	<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" order="2" key-generator="commonsKeyGenerator"/>

	<bean id="jedisConnectionFactory" class="com.ppdai.cachecloud.spring.CachecloudJedisFactory">
		<constructor-arg index="0">
			<value>${redis.cachecloud.appId}</value>
		</constructor-arg>
		<constructor-arg index="1">
			<value>${redis.cachecloud.domain_url}</value>
		</constructor-arg>

		<!--standalone 模式不需要此配置-->
		<constructor-arg index="2">
			<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
				<property name="maxTotal" value="${redis.pool.maxActive}"></property>
				<property name="maxIdle" value="${redis.pool.maxIdle}" />
				<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
				<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
			</bean>
		</constructor-arg>
	</bean>

	<!-- redis template definition -->
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
		<property name="connectionFactory" ref="jedisConnectionFactory"/>
		<property name="keySerializer" >
			<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
		</property>
	</bean>

	<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:redisOperations-ref="redisTemplate">
		<property name="expires">
			<map>
				<entry key="testCache1" value="${redis.testCache1.time}"/>
				<entry key="testCache2" value="${redis.testCache2.time}"/>
			</map>
		</property>
		<property name="usePrefix" value="false"/>
	</bean>

</beans>  

这个包依赖fasterxml包,如果未引入过, 需增加如下配置:

<dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>${fasterxml.version}</version>
  </dependency>


项目采用上述接入方式,修改对应代码后,项目可正常运行,cachecloud上亦能监控到redis内存使用情况。

        然而,在同时存在两个项目,A项目数据存入redis,B项目调用redis中对应的key值进行相关逻辑判断,却发现报如下错误

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.StreamCorruptedException: invalid stream 

    可以看出是sping对redis查询的返回结果进行deserialize的时候出错了 , 错误提示:序列号对象生成这个字节数组的方法是否与默认的反序列化方法相对应。 

   于是,参照网上的解决办法,配置RedisTemplate的属性,给value加入序列化,添加配置代码如下:

        <property name="valueSerializer" >
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>

同样采用StringRedisSerializer 序列化方法,与keySerializer 相同。 问题解决。

更进一步的原理分析见参考文章:

1.点击打开链接  http://www.cnblogs.com/shihaiming/p/6019795.html 

RedisTemplate SerializationFailedException: Failed to deserialize payload 异常解决

2. 点击打开链接 https://blog.csdn.net/doctor_who2004/article/details/48790523

spring data redis serializer Serialization Exception 序列化问题




版权声明:本文为haoshuai2015原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。