昨天在程序中向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/
来源:https://www.cnblogs.com/javJoker/p/8006128.html
