redis存取对象
昨天在程序中向redis中存取对象,获取对象的时候遇到了一个问题,经过一番询问和查询相关资料终于弄明白了,认为有必要记录下来,对以后的自己或者其他人都有一定的帮助。我先把问题阐述一遍:对象A_model存取到redis中,但是从redis中获取后存取到B_model,即使A_model和B_model中变量都是一样的,但是依然会报java.lang.ClassCastException错误。导致会报java.lang.ClassCastException错误的根本原因是序列化的问题。经过定义的序列化存取到redis中,也把数据类型存取进去了,所以获取该key对应的数据的时候也必须是改数据类型。
下面是测试类:
package com.chr.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.ycy.domain.User; import com.ycy.domain.User_A; import com.ycy.service.impl.UserOperationsServiceImpl; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:config/spring-context.xml", "classpath:config/redis-context.xml" }) public class RedisTest { @Autowired private UserOperationsServiceImpl userops; @Test public void Test1() { // System.out.println(userops.getUser("test")); Object user = userops.getUser("1"); System.out.println(user); } @Test public void Test2() { //System.out.println(userops.getUser("a")); // System.out.println(userops.getUser("test")); // userops.add("test", "aaa"); User user = new User(); user.setId("1"); user.setName("bb"); user.setPassword("1234"); userops.add(user); } @Test public void Test3() { //System.out.println(userops.getUser("a")); //System.out.println(userops.getUser("test")); userops.del("test"); } @Test public void Test4() { User user = new User(); user.setId("1"); user.setName("bb"); user.setPassword("1234"); byte[] byt= serialize(user); Object obj=unserizlize(byt); User_A str; try { str = (User_A)obj; System.out.println(str); } catch (Exception e) { e.printStackTrace(); } if(obj instanceof User){ System.out.println(obj); } } //序列化 public static byte [] serialize(Object obj){ ObjectOutputStream obi=null; ByteArrayOutputStream bai=null; try { bai=new ByteArrayOutputStream(); obi=new ObjectOutputStream(bai); obi.writeObject(obj); byte[] byt=bai.toByteArray(); return byt; } catch (IOException e) { e.printStackTrace(); } return null; } //反序列化 public static Object unserizlize(byte[] byt){ ObjectInputStream oii=null; ByteArrayInputStream bis=null; bis=new ByteArrayInputStream(byt); try { oii=new ObjectInputStream(bis); Object obj=oii.readObject(); return obj; } catch (Exception e) { e.printStackTrace(); } return null; } }
test2()将User_model插入到redis中,用test1()方法获取数据存到Object中,输出的值为com.ycy.domain.User@9da3f3,说明从redis中存取对象的时候也把数据结构也存取进去了,后来查询了相关资料有这种结果的是Serializable序列化的问题,于是我就写了test4测试方法来进行验证,User_model和User_A_model类名不同,两个model中变量一模一样,第二条输出语句正确,但是第一条数据语句依然还会报如下错误:
java.lang.ClassCastException: com.ycy.domain.User cannot be cast to com.ycy.domain.User_A at com.chr.test.RedisTest.Test4(RedisTest.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) ====================== com.ycy.domain.User@9b0789
我也找了一些相关资料:
redis采用序列化方案存对象------------------------------------------------https://www.cnblogs.com/yaobolove/p/5632891.html
序列化和反序列化 -----------------------------------------------------------https://kb.cnblogs.com/page/515982/