常见的java序列化/反序列化几种类型

Java序列化是指把Java对象转换为字节序列的过程,Java反序列化是指把字节序列恢复为Java对象的过程

主要有两种用途: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 在网络上传送对象的字节序列。

不管什么用途我们都希望占用空间小,传输效率高,读写快。方式有多中,效率不同,常见的方式有jdk的ObjectOutputStream、json类库、javax的xml、googe的protobuf及基于protobuf的protostuff。

 

一、JDK序列化/反序列化

用到的实体People.java

public class People  implements Serializable {
     private static final long serialVersionUID = 1L;
    
	private String id;
	private String name;
	private String age;
	private String birthday;
	
	public String getId() {
		return id;
	}
	
	public People(String id, String name, String age, String birthday) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}

	public People() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public void setId(String id) {
		this.id = id;
	}
}

测试类

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import com.ultradata.task.software.People;

import redis.clients.jedis.Jedis;

public class JDKSerializeUtil {
	/**
	 *  序列化(对象 -> 字节数组)
	 * @param object
	 * @return
	 */
    private static byte[] serialize(Object object) {
        ObjectOutputStream objectOutputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        byte[] getByte = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(object);
            getByte = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return getByte;
    }
    /**
     * 反序列化(字节数组 -> 对象)
     * @param binaryByte
     * @return
     */
    private static Object deserizlize(byte[] binaryByte) {
        ObjectInputStream objectInputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        Object readObject = null;
        try {
        	byteArrayInputStream = new ByteArrayInputStream(binaryByte);
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            readObject = objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return readObject;
    }
    
    public static void main(String[] args) {
        Jedis jedis = null;
        try {
            jedis = new Jedis("192.168.172.74");
            People people = new People("0", "张三", "30", "2019-01-17");
            jedis.set("zs".getBytes(), serialize(people));
            byte[] getByte = jedis.get("zs".getBytes());
            
            People p = (People)deserizlize(getByte);
            System.out.println(p.getId()+"--"+p.getName()+"-"+p.getAge()+"-"+p.getBirthday());
            System.out.println("------------------");
            
    		People p1 = new People("1", "张三", "34", "2019-01-18");
    		People p2 = new People("2", "李四", "28", "2019-01-19");
    		List list = new ArrayList<>();
    		list.add(p1);
    		list.add(p2);
    		jedis.set("list".getBytes(), serialize(list));
    		
            byte[] bytesList = jedis.get("list".getBytes());
            @SuppressWarnings("unchecked")
            List lists = (List)deserizlize(bytesList);
            for (People pp : lists) {
            	 System.out.println(pp.getId()+"--"+pp.getName()+"-"+pp.getAge()+"-"+pp.getBirthday());
			}
    		
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

redis-cli中 显示

192.168.172.74:6379> get obj
"\xac\xed\x00\x05sr\x00\"com.ultradata.task.software.People\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x04L\x00\x03aget\x00\x12Ljava/lang/String;L\x00\bbirthdayq\x00~\x00\x01L\x00\x02idq\x00~\x00\x01L\x00\x04nameq\x00~\x00\x01xpt\x00\x0230t\x00\n2019-01-17t\x00\x010t\x00\x06\xe5\xbc\xa0\xe4\xb8\x89"
192.168.172.74:6379> get list
"\xac\xed\x00\x05sr\x00\x13java.util.ArrayListx\x81\xd2\x1d\x99\xc7a\x9d\x03\x00\x01I\x00\x04sizexp\x00\x00\x00\x02w\x04\x00\x00\x00\x02sr\x00\"com.ultradata.task.software.People\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x04L\x00\x03aget\x00\x12Ljava/lang/String;L\x00\bbirthdayq\x00~\x00\x03L\x00\x02idq\x00~\x00\x03L\x00\x04nameq\x00~\x00\x03xpt\x00\x0234t\x00\n2019-01-18t\x00\x011t\x00\x06\xe5\xbc\xa0\xe4\xb8\x89sq\x00~\x00\x02t\x00\x0228t\x00\n2019-01-19t\x00\x012t\x00\x06\xe6\x9d\x8e\xe5\x9b\x9bx"
192.168.172.74:6379> 

控制台输出

0--张三-30-2019-01-17
------------------
1--张三-34-2019-01-18
2--李四-28-2019-01-19

 

二、protobuf序列化/反序列化

1、Protobuf介绍

  Protobuf是 Google 公司内部的混合语言数据标准,为Google Protocol Buffer缩写。 目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。与平台、语言无关,可扩展,解析速度快效率高,占用空间小。目前提供了 C++、Java、Python ,Ruby、Go等语言的 API。

2、Protobuf使用流程

  需要自己写一个.proto文件用来描述序列化的格式,然后用Protobuf提供的protoc工具将.proto文件编译成一个Java文件,最后将该Java文件引入到项目中就可以了。

(1)依赖安装

yum -y install autoconf automake libtool curl make g++ unzip

(2)下载源码

已经安装git的情况下

$ git clone https://github.com/protocolbuffers/protobuf.git
$ cd protobuf
#初始化本地子仓库,并从远程父仓库检出对应的两个子库,一个基准测试库,一个谷歌C++测试库
$ git submodule update --init --recursive #对我们使用没有protobuf影响,可以不执行
$ ./autogen.sh

没有git的直接下载protobuf的git仓库https://github.com/protocolbuffers/protobuf

$ unzip protobuf-master.zip
$ cd protobuf-master
$ ./autogen.sh

或者直接去https://github.com/protocolbuffers/protobuf/releases/latest最新源码包,可以全部下载,也可以选择单个语言下载,这里我选java,下载protobuf-java-3.6.1.tar.gz(推荐此方式,简单

$ tar -zxvf protobuf-java-3.6.1.tar.gz
$ cd protobuf-3.6.1

 

(3)编译安装

$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig # refresh shared library cache.

(4)编写proto文件

syntax = "proto3";
option java_package = "com.serialize.protobuf";
option java_outer_classname="PersonProtobuf";

message Person {
  string id= 1;
  string name = 2;
  int32 age = 3;
  string birthday = 4;

  Address domicile = 5;  
  message Address{
    string province = 1;
    string city = 2;
    string district = 3;
    DomicileType type = 4;
  }

   enum DomicileType {
    COUNTRY = 0;
    CITY = 1;
    NO_CITY = 2;
  }
}

java_package包名,java_outer_classname类名。这里使用了proto3语法编译,移除了 “required”。关于protobuf的更多使用信息后续会进行介绍,也可以看别同学的文章。

(5)生成java代码

进入到安装路径下/usr/local/protobuf,有bin  include  lib三个文件夹,bin下有protoc命令

用来生成java代码

bin/protoc --proto_path=./src/proto/ --java_out=src/java/ PersonProtobuf.proto

--proto_path是我们自己编写的proto文件路劲,--java_out是我们产生java文件的路径;PersonProtobuf.proto是源文件

执行命令后会在src/java/com/serialize/protobuf下生成PersonProtobuf.java文件,com/serialize/protobuf是包名

(6)引入maven依赖


    com.google.protobuf
    protobuf-java
    3.6.1



  com.google.protobuf
  protobuf-java-util
  3.6.1

(7)序列化使用

把生成PersonProtobuf.java文件拷贝到项目中

测试类如下:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.data.redis.PersonProtobuf.Person;
import org.springframework.data.redis.PersonProtobuf.Person.Address;
import org.springframework.data.redis.PersonProtobuf.Person.DomicileType;

import com.google.protobuf.InvalidProtocolBufferException;

import redis.clients.jedis.Jedis;

public class ProtobufSerializetionUtil {
	public static void main(String[] args) {
		Jedis jedis = null;
		try {
			jedis = new Jedis("192.168.172.74");
			PersonProtobuf.Person.Builder personBuilder = PersonProtobuf.Person.newBuilder();  
			personBuilder.setId("123456");
			personBuilder.setName("张三");
			personBuilder.setAge(20);
			personBuilder.setBirthday("2019-02-20");
			
			PersonProtobuf.Person.Address.Builder place = PersonProtobuf.Person.Address.newBuilder();  
			place.setProvince("北京");
			place.setCity("北京");
			place.setDistrict("朝阳");
			place.setType(DomicileType.CITY);
			
			personBuilder.setDomicile(place);
			  
			PersonProtobuf.Person person = personBuilder.build();  
			
			//第一种方式  
			//序列化  
			byte[] bytes = person.toByteArray();//获取字节数组,适用于SOCKET或者保存在磁盘。  
			jedis.set("protobuf-obj".getBytes(), bytes);
			//反序列化  
			PersonProtobuf.Person per = PersonProtobuf.Person.parseFrom(jedis.get("protobuf-obj".getBytes()));  
			System.out.println(per.getId()+"-"+per.getAge()+"-"+per.getName()+"-"+per.getBirthday());
			Address add = per.getDomicile();
			System.out.println(add.getProvince()+"-"+add.getCity()+"-"+add.getDistrict()+"-"+add.getType());
			
			
			//第二种序列化:粘包,将一个或者多个protobuf对象字节写入stream。  
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  
			//生成一个由:[字节长度][字节数据]组成的package。特别适合RPC场景  
			person.writeDelimitedTo(byteArrayOutputStream);  
			
			//反序列化,从steam中读取一个或者多个protobuf字节对象  
			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());  
			Person personinfo = PersonProtobuf.Person.parseDelimitedFrom(byteArrayInputStream);  
			System.out.println(personinfo);  
			System.out.println("-----------------------");
			//第三种序列化,写入文件或者Socket,不太常用  
			FileOutputStream fileOutputStream = new FileOutputStream(new File("/test.dt"));  
			person.writeTo(fileOutputStream);  
			fileOutputStream.close();  
			  
			FileInputStream fileInputStream = new FileInputStream(new File("/test.dt"));  
			personinfo = PersonProtobuf.Person.parseFrom(fileInputStream);  
			System.out.println(personinfo);  
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (jedis!=null) {
				jedis.close();
			}
		}
		
	}
}

 redis-cli中显示

192.168.172.74:6379> get protobuf-obj
"\n\x06123456\x12\x06\xe5\xbc\xa0\xe4\xb8\x89\x18\x14\"\n2019-02-20*\x1a\n\x06\xe5\x8c\x97\xe4\xba\xac\x12\x06\xe5\x8c\x97\xe4\xba\xac\x1a\x06\xe6\x9c\x9d\xe9\x98\xb3 \x01"
192.168.172.74:6379>

控制台输出

123456-20-张三-2019-02-20
北京-北京-朝阳-CITY
------------------------
id: "123456"
name: "\345\274\240\344\270\211"
age: 20
birthday: "2019-02-20"
domicile {
  province: "\345\214\227\344\272\254"
  city: "\345\214\227\344\272\254"
  district: "\346\234\235\351\230\263"
  type: CITY
}

-----------------------
id: "123456"
name: "\345\274\240\344\270\211"
age: 20
birthday: "2019-02-20"
domicile {
  province: "\345\214\227\344\272\254"
  city: "\345\214\227\344\272\254"
  district: "\346\234\235\351\230\263"
  type: CITY
}

三、protostuff序列化/反序列化

protostuff基于Google Protobuf的封装的,不用用户自己写.proto文件,使用起来比较方便,在几乎不损耗性能的情况下即可实现对象的序列化与反序列化。

在pom.xml引入maven依赖

io.protostuff
    protostuff-runtime
    1.6.0


    io.protostuff
    protostuff-core
    1.6.0
    test

集合包装类DataListWrapper.java

public class DataListWrapper {
	private List dataList = new ArrayList<>();
	 
    public DataListWrapper() {
    }
 
    public DataListWrapper(List dataList) {
        this.dataList = dataList;
    }
 
    public List getDataList() {
        return dataList;
    }
 
    public void setDataList(List dataList) {
        this.dataList = dataList;
    }
}

序列化工具类ProtostuffSerializer.java

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

/**
 * 序列化和反序列化工具
 * Protostuff
 */
public class ProtostuffSerializer {
	
	private static Map, Schema> cachedSchema = new ConcurrentHashMap<>();
	
    /**
     * 序列化(对象 -> 字节数组)
     * @param obj
     * @return
     */
	@SuppressWarnings("unchecked")
    public static  byte[] serialize(final T obj) {
		Class clazz = (Class) obj.getClass();
//    	Schema schema = (Schema) RuntimeSchema.createFrom(clazz);
    	Schema schema = (Schema) getSchema(clazz);
    	
        final LinkedBuffer linkedBuffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            return ProtostuffIOUtil.toByteArray(obj, schema, linkedBuffer);
        } catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            linkedBuffer.clear();
        }
    }
    /**
     * 反序列化(字节数组 -> 对象)
     * @param bytes
     * @param clazz
     */
    public static  T deserialize(final byte[] bytes,Class clazz) {
        try {
//        	Schema schema = (Schema) RuntimeSchema.getSchema(clazz);
        	Schema schema = getSchema(clazz);
        	T newMessage = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(bytes, newMessage, schema);;
            if (newMessage != null) {
                return newMessage;
            }
        } catch (final Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
        return null;
    }
    /**
     * 用ConcurrentHashMap缓存首次创建的Schema对象
     * 避免每次重复创建
     * @param cls
     */
    @SuppressWarnings("unchecked")
    private static  Schema getSchema(Class claszz) {
        Schema schema = (Schema) cachedSchema.get(claszz);
        if (schema == null) {
            schema = RuntimeSchema.createFrom(claszz);
            cachedSchema.put(claszz, schema);
        }
        return schema;
    }

}

测试类(redis相关类较易,就不出示了)

import java.util.ArrayList;
import java.util.List;

import org.icm.net.tcp.serializer.ProtostuffSerializer;

import redis.clients.jedis.Jedis;

public class TestSerializer{
	
	/**
	 * get String
	 * @param key
	 * @return
	 */
	public synchronized static String getString(String key) {
		Jedis jedis = null;
		try {
			jedis = RedisClient.getJedis();
			if (jedis == null) {
	            return null;
	        }
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisClient.closeJedis(jedis);
		}
        return jedis.get(key);
    }
	
	public synchronized static String setString(byte[] key,byte[] value) {
		Jedis jedis = null;
		try {
			jedis = RedisClient.getJedis();
			if (jedis == null) {
	            return null;
	        }
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisClient.closeJedis(jedis);
		}
        return jedis.set(key,value);
    }
	
	public static void main(String[] args) {
		//对象序列化,对象people序列化后存redis
		People people = new People("0", "张三", "30", "2019-01-17");
		setString("111".getBytes(),ProtostuffSerializer.serialize(people));
		//从redis取出并反序列化
        People pp = ProtostuffSerializer.deserialize(getString("111").getBytes(),People.class);
        System.out.println(pp.getId()+"--"+pp.getName()+"-"+pp.getAge()+"-"+pp.getBirthday());
        System.out.println("--------------------");
        //集合序列化,把对象people 封装对象中的集合
		People p1 = new People("1", "张三", "34", "2019-01-18");
		People p2 = new People("2", "李四", "28", "2019-01-19");
		List list = new ArrayList<>();
		list.add(p1);
		list.add(p2);
		DataListWrapper dataListWrapper = new DataListWrapper(list);
		
		//序列化后存redis
		byte[] bytesValue = ProtostuffSerializer.serialize(dataListWrapper);
		setString("222".getBytes(),bytesValue);
		//从redis取出并反序列化
        byte[] getBytes = getString("222").getBytes();
        DataListWrapper wrapper = ProtostuffSerializer.deserialize(getBytes,DataListWrapper.class);
        
		for (People p : (List)wrapper.getDataList()) {
			System.out.println(p.getId()+"--"+p.getName()+"-"+p.getAge()+"-"+p.getBirthday());
		}
		
	}
   
}

redis-cli中显示

192.168.172.74:6379> get 111
"\n\x010\x12\x06\xe5\xbc\xa0\xe4\xb8\x89\x1a\x0230\"\n2019-01-17"
192.168.172.74:6379> get 222
"\x0b\n\x011\x12\x06\xe5\xbc\xa0\xe4\xb8\x89\x1a\x0234\"\n2019-01-18\x0c\x0b\n\x012\x12\x06\xe6\x9d\x8e\xe5\x9b\x9b\x1a\x0228\"\n2019-01-19\x0c"
192.168.172.74:6379> 

控制台输出

0--张三-30-2019-01-17
---------------------
1--张三-34-2019-01-18
2--李四-28-2019-01-19

四、Json序列化/反序列化

常见的json库有JSON-lib、FastJson、Jackson、Gson

在pom.xml中引入maven依赖


	com.fasterxml.jackson.core
	jackson-annotations
	2.9.6


	com.fasterxml.jackson.core
	jackson-core
	2.9.6


	com.fasterxml.jackson.core
	jackson-databind
	2.9.6

jackson的序列化如下:

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.ultradata.task.software.People;

import redis.clients.jedis.Jedis;

public class JsonSerializeUtil {
    
    public static void main(String[] args) {
        Jedis jedis = null;
        try {
            jedis = new Jedis("192.168.172.74");
            //对象序列化
            People people = new People("0", "张三", "30", "2019-01-17");
            
            ObjectMapper objectMapper = new ObjectMapper();
            byte[] writeValueAsBytes = objectMapper.writeValueAsBytes(people);
            
            jedis.set("jsonobj".getBytes(), writeValueAsBytes);
            byte[] getByte = jedis.get("jsonobj".getBytes());
            
            People p = objectMapper.readValue(getByte, People.class);
            
            System.out.println(p.getId()+"--"+p.getName()+"-"+p.getAge()+"-"+p.getBirthday());
            System.out.println("------------------");
            
            //集合list序列化
    		People p1 = new People("1", "张三", "34", "2019-01-18");
    		People p2 = new People("2", "李四", "28", "2019-01-19");
    		List list = new ArrayList<>();
    		list.add(p1);
    		list.add(p2);
    		byte[] jsonbyte = objectMapper.writeValueAsBytes(list);
    		jedis.set("jsonlist".getBytes(), jsonbyte);
            byte[] getBytess = jedis.get("jsonlist".getBytes());
            //因为list没有List.class操作,TypeReference可以传递完整的泛型类型信息,并避免类型擦除的问题
            TypeReference> typeReference = new TypeReference>(){};
			List lists = objectMapper.readValue(getBytess,typeReference);
            for (People pp : lists) {
            	 System.out.println(pp.getId()+"--"+pp.getName()+"-"+pp.getAge()+"-"+pp.getBirthday());
			}
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

redis-cli中输出

192.168.172.74:6379> get jsonobj
"{\"name\":\"\xe5\xbc\xa0\xe4\xb8\x89\",\"id\":\"0\",\"age\":\"30\",\"birthday\":\"2019-01-17\"}"
192.168.172.74:6379> get jsonlist
"[{\"name\":\"\xe5\xbc\xa0\xe4\xb8\x89\",\"id\":\"1\",\"age\":\"34\",\"birthday\":\"2019-01-18\"},{\"name\":\"\xe6\x9d\x8e\xe5\x9b\x9b\",\"id\":\"2\",\"age\":\"28\",\"birthday\":\"2019-01-19\"}]"
192.168.172.74:6379> 

 控制台输出

0--张三-30-2019-01-17
------------------
1--张三-34-2019-01-18
2--李四-28-2019-01-19

 

五、XML序列化/反序列化

和之前不同的是需要在实体类上加注解

People类上@XmlRootElement(name = "People") 

DataListWrapper类上@XmlRootElement(name = "DataListWrapper") 

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import com.ultradata.task.software.DataListWrapper;
import com.ultradata.task.software.People;

import redis.clients.jedis.Jedis;

public class XMLSerializeUtil {

    private static String serialize(Object object) {
        StringWriter stringWriter = null;
        try {
            stringWriter = new StringWriter();
            JAXBContext jContext = JAXBContext.newInstance(object.getClass());
            Marshaller marshaller = jContext.createMarshaller();
            marshaller.marshal(object, stringWriter);
            if (stringWriter!=null) {
            	return stringWriter.toString();
			}
        } catch (JAXBException e) {
            e.printStackTrace();
        }
		return null;
    }

    private static Object deserizlize(Class clazz, String xmlString) {
        Object xmlObject = null;
        try {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            StringReader stringReader = new StringReader(xmlString);
            xmlObject = unmarshaller.unmarshal(stringReader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return xmlObject;
    }
    public static void main(String[] args) {
        Jedis jedis = null;
        try {
            jedis = new Jedis("192.168.172.74");
            //对象序列化,对象people序列化后存redis
            People people = new People("0", "张三", "30", "2019-01-17");
            jedis.set("xmlobj", serialize(people));
            String getByte = jedis.get("xmlobj");
            
            People p = (People)deserizlize(People.class,getByte.toString());
            System.out.println(p.getId()+"--"+p.getName()+"-"+p.getAge()+"-"+p.getBirthday());
            System.out.println("------------------");
            
            //集合序列化,把对象people 封装对象中的集合
    		People p1 = new People("1", "张三", "34", "2019-01-18");
    		People p2 = new People("2", "李四", "28", "2019-01-19");
    		List list = new ArrayList<>();
    		list.add(p1);
    		list.add(p2);
    		DataListWrapper dataListWrapper = new DataListWrapper(list);
    		jedis.set("xmllist", serialize(dataListWrapper));
    		
    		String strList = jedis.get("xmllist");
            DataListWrapper wrapper = (DataListWrapper)deserizlize(DataListWrapper.class,strList);
            for (People pp : (List)wrapper.getDataList()) {
    			System.out.println(pp.getId()+"--"+pp.getName()+"-"+pp.getAge()+"-"+pp.getBirthday());
    		}
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

redis-cli中显示

192.168.172.74:6379> get xmlobj
"302019-01-170\xe5\xbc\xa0\xe4\xb8\x89"
192.168.172.74:6379> get xmllist
"342019-01-181\xe5\xbc\xa0\xe4\xb8\x89282019-01-192\xe6\x9d\x8e\xe5\x9b\x9b"
192.168.172.74:6379> 

控制台输出

0--张三-30-2019-01-17
------------------
1--张三-34-2019-01-18
2--李四-28-2019-01-19

 

参考:https://github.com/protocolbuffers/protobuf

参考:https://github.com/protocolbuffers/protobuf/blob/master/src/README.md

参考:https://www.cnblogs.com/BigJunOba/p/9127414.html

参考:https://blog.csdn.net/huanggang982/article/details/77944174

你可能感兴趣的:(Java)