0%

hessian反序列化

入门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入手了
在这里就不重复造轮子了,可以参考这篇文章