Java序列化与反序列化

一.概述

  1.序列化:是指将对象转化为二进制数据,保存到磁盘中

  2.反序列化:将保存在磁盘中的二进制数据转化回对象。

  3.作用:

       1.将对象持久化,从内存中保存到磁盘,这次的分布式session需要缓存到redis服务器时进行序列化与反序列化。

       2.当你想用套接字在网络上传送对象的时候。

二.怎么使用

  1.首先,需要序列化的对象要实现Serializable接口,如图下。

                       

public class Car implements Serializable{
    
    private String name;
    private int id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    

}

 

  2.建立序列化工具类,里面写序列化和反序列化的方法,如下:

//序列化的方法
     public static Object DeserializeUser(byte b[]) {
            ByteArrayInputStream bis = null;
            ObjectInputStream ois = null;
            Object object=null;
            try {
                bis = new ByteArrayInputStream(b);
                ois = new ObjectInputStream(bis);
                object = ois.readObject();

            } catch (Exception e) {
                e.printStackTrace();
            }

            return  object;
        }
     //反序列化的方法
        public static byte [] SerializeUser(Object object) {
            ByteArrayOutputStream bos = null;
            ObjectOutputStream oos = null;
            byte b [] =null;
            try {
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(object);
                b = bos.toByteArray();
            }catch (Exception e) {

            }
            return b;
        }

   3.写个测试类,新建一个Car,然后调用序列化工具类进行操作,成功,看下面:

                  

四.异常处理

  

  本来呢,出现这个问题去上网搜,发现是说在序列化时得到的字节数组并不是反序列化时的字节数组,他们出现问题的代码是这样的:图中在序列化完成后不应该用tostring,但是其实我在上面写的序列化工具类里面的方法是对的呀,就是在输出的时候使用toByteArray生成字节数组,反序列化的时候直接用这个数组

       //序列化的方法
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(baos); 
        oos.writeObject(bi);  
        String str = baos.toString();   错误的方法
     byte[] str = baos.toByteArray();  正确的方法
//反序列化
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(str.getBytes())));//正确的这里应该直接用上面的字节数组。 Object obj = ois.readObject();

   后来,仔细查找,还是发现原来在业务逻辑中出现了问题,业务中是这样的,序列化的时候返回的的确是正确的字节数组,但是由于要存到redis里面,又转为String,这个时候就错误了。下面是改正后用了jdk8的Base64工具类,就ok了。


       //序列化
       byte [] b = SerializUtil.SerializeUser(user);
       //字节数组转String String serialize_user
= Base64.getEncoder().encodeToString(b);
       //反序列化
       //String转字节数组 
       byte strData[] = Base64.getDecoder().decode(jedis.get(key));
       User user = (User)SerializUtil.DeserializeUser(strData);

 

posted @ 2018-11-18 23:03  AJimmyFang  阅读(674)  评论(0编辑  收藏  举报