序列化/反序列化 - 实现内存对象 - 二进制数据的转换,二进制数据用于存储、持久化、网络传输。
技术选型要素:①序列化空间开销(压缩比) ②序列化时间损耗(性能需求) ③是否跨平台 ④使用的难易程度 ⑤是否需要可读性
Java序列化
// 序列化对象需实现Serializable接口,可通过transient标签标注属性无需序列化,建议设置序列化UUID
public class JavaSerializer implements ISerializer {
public <T> byte[] serialize(T obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);){
oos.writeObject(obj);
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
public <T> T deserialize(byte[] data) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais);){
return (T)ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
XML序列化
// 当前demo采用Xstream组件
public class XMLSerializer implements ISerializer{
XStream stream=new XStream(new DomDriver());
@Override
public <T> byte[] serialize(T obj) {
return stream.toXML(obj).getBytes();
}
@Override
public <T> T deserialize(byte[] data) {
return (T)stream.fromXML(new String(data));
}
}
Json序列化
// Fastjson组件,性能最高,但稳定性不如Gson和Jackson
public class FastjsonSerializer implements ISerializer{
public <T> byte[] serialize(T obj) {
return JSON.toJSONBytes(obj);
}
public <T> T deserialize(byte[] data) {
return JSON.parseObject(data, User.class);
}
}
Hessian序列化
public class HessianSerializer implements ISerializer{
@Override
public <T> byte[] serialize(T obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();){
HessianOutput oos = new HessianOutput(baos);
oos.writeObject(obj);
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
@Override
public <T> T deserialize(byte[] data) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);){
HessianInput ois = new HessianInput(bais);
return (T)ois.readObject();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
protobuf序列化
特殊的序列化组件,需要额外的脚本支持(压缩率快而高)
int压缩算法:zigzag和varint算法
private static void testProtobufSerializer() throws InvalidProtocolBufferException {
UserProto.User user = UserProto.User.newBuilder().setName("kiqi").setAge(18).setStatus(-200).build();
byte[] bytes = user.toByteArray();
System.out.println(Arrays.toString(bytes));
UserProto.User userRever = UserProto.User.parseFrom(bytes);
System.out.println(userRever.toString());
}