jackson序列化

jackson的序列化有坑, 可能会导致死循环, 栈溢出

1
2
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)

所以慎重使用jackson序列化, 当存在A,B循环引用的时候就会存在该序列化问题

同样的还有注解lombok 的 @Data注解, 同样有该风险

栈溢出的case

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

package me.huakai.domain.api;

import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

/**
* 测试循环引用的 toString 和 toJson 方法
* @author xiang.rao created on 3/7/18 9:15 PM
* @version $Id$
*/
@Slf4j
public class CircleReferenceSerializableTest {


@Test
public void testJson() {
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
String encodeA = JSONObject.toJSON(a).toString();
log.info("encodeA:{}", encodeA);
}

@Test
public void testToString() {
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
log.info("a:{}", a);
}
}

@Getter
@Setter
class A {
private B b;

@Override
public String toString() {
return "A{" +
"b=" + b +
'}';
}
}


@Getter
@Setter
@ToString
class B {
private A a;

@Override
public String toString() {
return "B{" +
"a=" + a +
'}';
}
}

jackson 结合redis序列化, 反序列化时候有坑

如果value存储的不是bean对象, 是基本的整数类型, int, long, biginteger. jackson会根据数字长度去决定反序列化的结果是什么类型. 这时候可能和程序希望的类型不一致

如果value 是bean对象, 就没有该问题

参考

http://the-whiteboard.github.io/java/debugging/warstory/2017/03/12/dangers-of-objects-from-json.html

https://stackoverflow.com/questions/34238153/spring-data-redis-java-lang-classcastexception