先定义序列化和反序列化接口
public interface ISerializer {
<T> byte[] serialize(T obj);
<T> T deserialize(byte[] data);
}
**注意下面的System.out.println("bytes数组长度:" + bytes.length); 其实就是说,很多序列化技术的好坏,是根据序列化后产生的字节数组的大小来看的,如果产生的字节数组大,就表示很占内存,其次也要看序列化的效率和传输的效率 **
序列化技术的选型
1. 序列化空间开销,也就是序列化产生的结果大小,这个影响到传输的性能
2. 序列化过程中消耗的时长,序列化消耗时间过长影响到业务的响应时间
3. 序列化协议是否支持跨平台,跨语言。因为现在的架构更加灵活,如果存在异构系统通信
需求,那么这个是必须要考虑的
4. 可扩展性/兼容性,在实际业务开发中,系统往往需要随着需求的快速迭代来实现快速更新,
这就要求我们采用的序列化协议基于良好的可扩展性/兼容性,
比如在现有的序列化数据结构中新增一个业务字段,不会影响到现有的服务
序列化输出的byte数组里存的是啥
- protobuf 序列化的byte数组是Ascii码
- 其他待补
Java实现序列化和反序列化
public class JavaSerializer implements ISerializer{
//序列化
@Override
public <T> byte[] serialize(T obj) {
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream=new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
//反序列化
@Override
public <T> T deserialize(byte[] data) {
ByteArrayInputStream byteArrayOutputStream=new ByteArrayInputStream(data);
try {
ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayOutputStream);
return (T)objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
测试:
public class SerializerMain {
public static void main(String[] args) {
ISerializer serializer=new JavaSerializer();
User user=new User();
user.setName("小风");
user.setAge(27);
byte[] bytes=serializer.serialize(user);
//实际上这个byte数组 就是对象通过序列化之后转换成的一个二进制流
System.out.println("bytes数组长度:" + bytes.length);
for (int i = 0; i < bytes.length; i++) {
//byte是一个字节8位的二进制存储(不超过256),在输出时是十进制,所以感觉是int
System.out.print(bytes[i]+ " ");
}
System.out.println();
User userRever=serializer.deserialize(bytes);
System.out.println(userRever);
}
}
控制台输出:
注意User对象:
/**
* User对象必须实现Serializable,然后可以不手动生成serialVersionUID=1L或serialVersionUID=一串数字
* 其实implements Serializable之后,内部默认会生成serialVersionUID的
*/
@Data
public class User implements Serializable
{
// private static final long serialVersionUID = -2112105888550168550L;
// private static final long serialVersionUID = 1L;
private String name;
private int age;
}
如果不实现 Serializable,会报错:
XML实现序列化和反序列化
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));
}
}
Main方法测试:
public class SerializerMain {
public static void main(String[] args) {
User user=new User();
user.setName("小风");
user.setAge(27);
ISerializer serializer=new XMLSerializer();
byte[] bytes=serializer.serialize(user);
System.out.println("bytes数组长度:" + bytes.length);
System.out.println(new String(bytes));
User userRever=serializer.deserialize(bytes);
System.out.println(userRever);
}
}
控制台输出如下:
Hessian实现序列化
public class HessianSerializer implements ISerializer{
@Override
public <T> byte[] serialize(T obj) {
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
HessianOutput hessianOutput=new HessianOutput(byteArrayOutputStream);
try {
hessianOutput.writeObject(obj);
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
@Override
public <T> T deserialize(byte[] data) {
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(data);
HessianInput hessianInput=new HessianInput(byteArrayInputStream);
try {
return (T)hessianInput.readObject();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Main方法测试:
public class SerializerMain {
public static void main(String[] args) {
User user=new User();
user.setName("小风");
user.setAge(27);
ISerializer serializer=new HessianSerializer();
byte[] bytes=serializer.serialize(user);
System.out.println("bytes数组长度:" + bytes.length);
System.out.println(new String(bytes));
User userRever=serializer.deserialize(bytes);
System.out.println(userRever);
}
}
控制台输出:
FastJSON 序列化,反序列化
直接看源代码,其实序列化方式和上面几种有很大的相通性,意会意会吧
JSONObject.toJSONString(accountInfo)
//序列号后输出跨平台容易理解的字符串
public static String toJSONString(Object object, //
SerializeConfig config, //
SerializeFilter[] filters, //
String dateFormat, //
int defaultFeatures, //
SerializerFeature... features) {
//部分代码省略
SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);
try {
JSONSerializer serializer = new JSONSerializer(out, config);
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}
public final class SerializeWriter extends Writer {
private final static ThreadLocal<char[]> bufLocal = new ThreadLocal<char[]>();
private final static ThreadLocal<byte[]> bytesBufLocal = new ThreadLocal<byte[]>();
其余代码省略 ...
}