Hessian2 是一个通用的序列化框架,官方文档:http://hessian.caucho.com/doc/hessian-serialization.html 。
基础示例
若使用 gradle 构建 Java 项目,请在 build.gradle 中增加以下依赖:
compile group: 'com.caucho', name: 'hessian', version: '4.0.60'
本文的示例用了lombok 和 junit(怎么写 Java 示例代码?),所以 build.gradle 中依赖配置如下:
compile group: 'com.caucho', name: 'hessian', version: '4.0.60'
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.0' // lombok 依赖
compile group: 'junit', name: 'junit', version: '4.12'
编写 Hessian2 的工具类:
package demo;
import com.caucho.hessian.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class HessianUtil {
// 序列化
public static byte[] serialize(Object obj) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
AbstractHessianOutput out = new Hessian2Output(os);
out.setSerializerFactory(new SerializerFactory());
try {
out.writeObject(obj);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
out.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return os.toByteArray();
}
// 反序列化
public static <T> T deserialize(byte[] bytes) {
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
AbstractHessianInput in = new Hessian2Input(is);
in.setSerializerFactory(new SerializerFactory());
T value;
try {
value = (T) in.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
in.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return value;
}
}
示例1:序列化
编写 Java Bean:
package demo;
import lombok.Data;
import lombok.ToString;
import java.io.Serializable;
@Data
@ToString
public class Person implements Serializable {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
序列化示例:
Person person = new Person("letian", 18);
// 序列化
byte[] bytes = HessianUtil.serialize(person);
// 输出数字,看长什么样子
for (byte i : bytes) {
System.out.printf("%s ", i);
}
System.out.println();
// 输出字符,看长什么样子(注意,数字转字符,有些会比较奇怪,有些字符是不可见的)
for (byte i : bytes) {
System.out.printf("%s", (char)i);
}
System.out.println();
运行结果:
67 11 100 101 109 111 46 80 101 114 115 111 110 -110 4 110 97 109 101 3 97 103 101 96 6 108 101 116 105 97 110 -94
Cdemo.Personメnameage`letianᄁ
示例2:反序列化
Person person = new Person("letian", 18);
// 序列化
byte[] bytes = HessianUtil.serialize(person);
// 反序列化
Person person2 = HessianUtil.deserialize(bytes);
System.out.println(person2);
运行结果:
Person(name=letian, age=18)
示例3:复杂 Java Bean 的序列化和反序列化
我把一个含有其他 Java Bean 的 Java Bean 叫做 复杂Java bean 。
package demo;
import lombok.Data;
import java.io.Serializable;
@Data
public class Address implements Serializable {
private String city;
public Address() {
}
public Address(String city) {
this.city = city;
}
}
package demo;
import lombok.Data;
import java.io.Serializable;
@Data
public class Student implements Serializable {
private String name;
private int age;
private Address address;
public Student() {
}
public Student(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
这里,Student 是一个复杂类型,序列化和反序列化示例如下:
Student student = new Student("letian", 18, new Address("test"));
// 序列化
byte[] bytes = HessianUtil.serialize(student);
// 输出数字,看长什么样子
for (byte i : bytes) {
System.out.printf("%s ", i);
}
System.out.println();
// 输出字符,看长什么样子(注意,数字转字符,有些会比较奇怪,有些字符是不可见的)
for (byte i : bytes) {
System.out.printf("%s", (char)i);
}
System.out.println();
// 反序列化
Student student1 = HessianUtil.deserialize(bytes);
System.out.println("反序列化结果:" + student1);
运行结果:
67 12 100 101 109 111 46 83 116 117 100 101 110 116 -109 4 110 97 109 101 3 97 103 101 7 97 100 100 114 101 115 115 96 6 108 101 116 105 97 110 -94 67 12 100 101 109 111 46 65 100 100 114 101 115 115 -111 4 99 105 116 121 97 4 116 101 115 116
Cdemo.Studentモnameageaddress`letianᄁCdemo.Addressムcityatest
反序列化结果:Student(name=letian, age=18, address=Address(city=test))
示例4:泛型 Java Bean 的序列化和反序列化
下面是一个使用了泛型的 Java Bean:
package demo;
import lombok.Data;
import java.io.Serializable;
@Data
public class Response<T> implements Serializable {
private Boolean success;
private T data;
public Response() {
}
public Response(Boolean success, T data) {
this.success = success;
this.data = data;
}
}
序列化和反序列化示例:
Student student = new Student("letian", 18, new Address("test"));
Response<Student> response = new Response<>(true, student);
// 序列化
byte[] bytes = HessianUtil.serialize(response);
// 输出数字,看长什么样子
for (byte i : bytes) {
System.out.printf("%s ", i);
}
System.out.println();
// 输出字符,看长什么样子(注意,数字转字符,有些会比较奇怪,有些字符是不可见的)
for (byte i : bytes) {
System.out.printf("%s", (char)i);
}
System.out.println();
// 反序列化
Response<Student> response1 = HessianUtil.deserialize(bytes);
System.out.println("反序列化结果:" + response1);
Java 的泛型是伪泛型,如果使用不当,会在运行时报错,比如:
Student student = new Student("letian", 18, new Address("test"));
Response<Student> response = new Response<>(true, student);
// 序列化
byte[] bytes = HessianUtil.serialize(response);
// 反序列化,注意,这里泛型用的 Address
Response<Address> response1 = HessianUtil.deserialize(bytes);
// 这里不会报错
System.out.println(response1);
// 这里会报错
System.out.println(response1.getData().getCity());
执行结果如下:
Response(success=true, data=Student(name=letian, age=18, address=Address(city=test)))
java.lang.ClassCastException: demo.Student cannot be cast to demo.Address
......