NO IMAGE

spring data redis serializer SerializationException 序列化問題

專案中需要使用redis做一些快取失效,以達到驗證碼失效的目的。由於K,V使用了<string,stirng>,<string,long>,驗證驗證碼是否存在,是否達到規定次數。參看了官方文件(內容很少),碰到了序列化的問題,異常如下:

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:41) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:296) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:53) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:86) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
at com.xhqb.user.register.manager.impl.CaptchaMessageManagerImpl.getCaptcha(CaptchaMessageManagerImpl.java:77) ~[classes/:na]
at com.xhqb.user.register.controller.UserRegisterController.getCaptcha(UserRegisterController.java:40) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:197) [cors-filter-2.4.jar:2.4]
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:274) [cors-filter-2.4.jar:2.4]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) [jetty-security-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [jetty-io-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.13.v20150730.jar:9.2.13.v20150730]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
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) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:39) ~[spring-data-redis-1.6.0.RELEASE.jar:1.6.0.RELEASE]
... 52 common frames omitted
Caused by: java.io.EOFException: null
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2325) ~[na:1.7.0_79]
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2794) ~[na:1.7.0_79]
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801) ~[na:1.7.0_79]
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) ~[na:1.7.0_79]
at org.springframework.core.ConfigurableObjectInputStream.<init>(ConfigurableObjectInputStream.java:64) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.core.ConfigurableObjectInputStream.<init>(ConfigurableObjectInputStream.java:50) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:66) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73) ~[spring-core-4.2.1.RELEASE.jar:4.2.1.RELEASE]
... 54 common frames omitted

試了各種網上的方法,還是不能解決。所以,我們解決框架的問題,最好還是理解透框架的思想。

現把正確配置檔案貼一下:

<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true" 
p:hostName="${redis.hostName}"
p:port="${redis.port}"  />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" 
p:connection-factory-ref="jedisConnFactory" 
p:keySerializer-ref="stringRedisSerializer" 
p:valueSerializer-ref="stringRedisSerializer"/>
<bean id="longRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" 
p:connection-factory-ref="jedisConnFactory" 
p:keySerializer-ref="stringRedisSerializer" 
p:valueSerializer-ref="GenericToStringSerializer"/>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean  id ="JdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean  id="GenericToStringSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer"
c:type="java.lang.Long"/>
</beans>

配置redisTemplate,是為了使用<k,v>都是string型別的redis操作,配置longRedisTemplate為了使用<k,v>是string,long型別。

使用方式:

@Resource(name = "redisTemplate")
private ValueOperations<String, String> valueOperations;
@Resource(name = "longRedisTemplate")
private RedisTemplate<String, Long> longRedisTemplate;
@Resource(name = "longRedisTemplate")
private ValueOperations<String, Long> intervalOperations;