入门Hessian反序列化
People
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package org.example.client;
import java.io.Serializable;
public class People implements Serializable { int id; String name;
public int getId() { System.out.println("Student getId call"); return id; }
public void setId(int id) { System.out.println("Student setId call"); this.id = id; }
public String getName() { System.out.println("Student getName call"); return name; }
public void setName(String name) { System.out.println("Student setName call"); this.name = name; } }
|
Student
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| package org.example.client;
import java.io.ObjectInputStream; import java.io.Serializable; import java.util.List; import java.util.Map;
public class Student extends People implements Serializable { private static final long serialVersionUID = 1L;
private static Student student = new Student(111, "xxx", "ggg"); private transient String gender; private Map<String, Class<Object>> innerMap; private List<Student> friends;
public void setFriends(List<Student> friends) { System.out.println("Student setFriends call"); this.friends = friends; }
public void getFriends(List<Student> friends) { System.out.println("Student getFriends call"); this.friends = friends; }
public Map getInnerMap() { System.out.println("Student getInnerMap call"); return innerMap; }
public void setInnerMap(Map innerMap) { System.out.println("Student setInnerMap call"); this.innerMap = innerMap; }
public String getGender() { System.out.println("Student getGender call"); return gender; }
public void setGender(String gender) { System.out.println("Student setGender call"); this.gender = gender; }
public Student() { System.out.println("Student default constructor call"); }
public Student(int id, String name, String gender) { System.out.println("Student custom constructor call"); this.id = id; this.name = name; this.gender = gender; }
private void readObject(ObjectInputStream ObjectInputStream) { System.out.println("Student readObject call"); }
private Object readResolve() { System.out.println("Student readResolve call");
return student; }
@Override public int hashCode() { System.out.println("Student hashCode call"); return super.hashCode(); }
@Override protected void finalize() throws Throwable { System.out.println("Student finalize call");
super.finalize(); }
@Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", innerMap=" + innerMap + ", friends=" + friends + '}'; } }
|
Serialize and DeSerialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package org.example.client;
import com.caucho.hessian.io.Hessian2Input; import com.caucho.hessian.io.Hessian2Output; import com.caucho.hessian.io.HessianInput; import com.caucho.hessian.io.HessianOutput;
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.sql.SQLData; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
public class HJSerializationTest {
public static <T> byte[] serialize(T t) { byte[] data = null; try { ByteArrayOutputStream os = new ByteArrayOutputStream(); HessianOutput output = new HessianOutput(os); output.writeObject(t); data = os.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return data; }
public static <T> T deserialize(byte[] data) { if (data == null) { return null; } Object result = null; try { ByteArrayInputStream is = new ByteArrayInputStream(data); HessianInput input = new HessianInput(is); result = input.readObject(); } catch (Exception e) { e.printStackTrace(); } return (T) result; }
public static void main(String[] args) { int id = 111; String name = "hessian"; String gender = "boy";
Map innerMap = new HashMap<String, Class<Object>>(); innerMap.put("1", ObjectInputStream.class); innerMap.put("2", SQLData.class);
Student friend = new Student(222, "hessian1", "boy"); List friends = new ArrayList<Student>(); friends.add(friend);
Student stu = new Student(); stu.setId(id); stu.setName(name); stu.setGender(gender); stu.setInnerMap(innerMap); stu.setFriends(friends);
System.out.println("---------------hessian serialize----------------"); byte[] obj = serialize(stu); System.out.println(new String(obj));
System.out.println("---------------hessian deserialize--------------"); Student student = deserialize(obj); System.out.println(student); } }
|
序列化
1.首先通过需要序列化的类,获取到相应的serializer,在通过这个serializer进行writeobject操作
2.一般对于自己写的class,他就会获取到defaultserializer
3.在获取serializer的过程中,他会去读取Object中的fields,并对应上serializer
4.获取完serializer,他会有一个将序列化的obj作为key,serializer作为value,加入到一个map和一个cachemap中
5.接着就是常规的获取field,然后在根据field的serializer写入数据了
大概过程就是
- 获取序列化对象相对应的serializer,并获得到fields,每个fields会依次对应上一个serializer
- 将serializer加入map和cachemap中
- 根据fields写入序列化数据
反序列化
首先看到他读取了序列化数据中的第一个字节,并判断是属于那种类型的,并在下面的switch语句中选择使用哪种Serializer去进行序列化,在这里是Map,注意这里的Map并不是说反序列化的类是Map类型的,而是所有Object类型都会被这个readMap处理用来反序列化
接下来就是常规的根据field然后deserialize
在这里的具体操作就是根据变量名获取到相应的deserialize
再在deserialize中获取value,并设置field
上面的操作最好还是要自己跟一遍
利用链
与kryo类似,hessian也是因为反序列化Map类型时会调用put方法
那利用点也是从hashCode与equals入手了
在这里就不重复造轮子了,可以参考这篇文章