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;
    }
}
View Code

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/

posted @ 2017-12-08 16:49  壹尘  阅读(4339)  评论(0编辑  收藏  举报