序列化(五)

序列化回调接口实现分析

内部注册的序列化

fastjson针对常用的类型已经注册了序列化实现方案:

注册的类型序列化实例是否支持序列化是否支持反序列化
BooleanBooleanCodec
CharacterCharacterCodec
ByteIntegerCodec
ShortIntegerCodec
IntegerIntegerCodec
LongLongCodec
FloatFloatCodec
DoubleDoubleSerializer-
BigDecimalBigDecimalCodec
BigIntegerBigIntegerCodec
StringStringCodec
byte[]PrimitiveArraySerializer-
short[]PrimitiveArraySerializer-
int[]PrimitiveArraySerializer-
long[]PrimitiveArraySerializer-
float[]PrimitiveArraySerializer-
double[]PrimitiveArraySerializer-
boolean[]PrimitiveArraySerializer-
char[]PrimitiveArraySerializer-
Object[]ObjectArrayCodec
ClassMiscCodec
SimpleDateFormatMiscCodec
CurrencyMiscCodec
TimeZoneMiscCodec
InetAddressMiscCodec
Inet4AddressMiscCodec
Inet6AddressMiscCodec
InetSocketAddressMiscCodec
FileMiscCodec
AppendableAppendableSerializer-
StringBufferAppendableSerializer-
StringBuilderAppendableSerializer-
CharsetToStringSerializer-
PatternToStringSerializer-
LocaleToStringSerializer-
URIToStringSerializer-
URLToStringSerializer-
UUIDToStringSerializer-
AtomicBooleanAtomicCodec
AtomicIntegerAtomicCodec
AtomicLongAtomicCodec
AtomicReferenceReferenceCodec
AtomicIntegerArrayAtomicCodec
AtomicLongArrayAtomicCodec
WeakReferenceReferenceCodec
SoftReferenceReferenceCodec
LinkedListCollectionCodec

BooleanCodec序列化

其实理解了前面分析SerializeWriter, 接下来的内容比较容易理解, BooleanCodec 序列化实现 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是boolean值, 如果为null,
* 并且序列化开启WriteNullBooleanAsFalse特性, 输出false
*/
Boolean value = (Boolean) object;
if (value == null) {
out.writeNull(SerializerFeature.WriteNullBooleanAsFalse);
return;
}

if (value.booleanValue()) {
out.write("true");
} else {
out.write("false");
}
}

BooleanCodec序列化实现主要判断是否开启如果为null值是否输出false,否则输出boolean字面量值。

CharacterCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

Character value = (Character) object;
if (value == null) {
/** 字符串为空,输出空字符串 */
out.writeString("");
return;
}

char c = value.charValue();
if (c == 0) {
/** 空白字符,输出unicode空格字符 */
out.writeString("\u0000");
} else {
/** 输出字符串值 */
out.writeString(value.toString());
}
}

IntegerCodec序列化

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
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

Number value = (Number) object;

/** 当前object是整形值, 如果为null,
* 并且序列化开启WriteNullNumberAsZero特性, 输出0
*/
if (value == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}

/** 判断整形或者长整型,直接输出 */
if (object instanceof Long) {
out.writeLong(value.longValue());
} else {
out.writeInt(value.intValue());
}

/** 如果开启WriteClassName特性,输出具体值类型 */
if (out.isEnabled(SerializerFeature.WriteClassName)) {
Class<?> clazz = value.getClass();
if (clazz == Byte.class) {
out.write('B');
} else if (clazz == Short.class) {
out.write('S');
}
}
}

LongCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是长整形值, 如果为null,
* 并且序列化开启WriteNullNumberAsZero特性, 输出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
} else {
long value = ((Long) object).longValue();
out.writeLong(value);

/** 如果长整型值范围和整型相同,显示添加L 标识为long */
if (out.isEnabled(SerializerFeature.WriteClassName)
&& value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE
&& fieldType != Long.class
&& fieldType != long.class) {
out.write('L');
}
}
}

Long类型序列化会特殊标识值落在整数范围内,如果开启WriteClassName序列化特性,会追加L字符。

FloatCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是float值, 如果为null,
* 并且序列化开启WriteNullNumberAsZero特性, 输出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}

float floatValue = ((Float) object).floatValue();
if (decimalFormat != null) {
/** 转换一下浮点数值格式 */
String floatText = decimalFormat.format(floatValue);
out.write(floatText);
} else {
out.writeFloat(floatValue, true);
}
}

BigDecimalCodec序列化

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
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是BigDecimal值, 如果为null,
* 并且序列化开启WriteNullNumberAsZero特性, 输出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
} else {
BigDecimal val = (BigDecimal) object;

String outText;
/** 如果序列化开启WriteBigDecimalAsPlain特性,搞定度输出不会包含指数e */
if (out.isEnabled(SerializerFeature.WriteBigDecimalAsPlain)) {
outText = val.toPlainString();
} else {
outText = val.toString();
}
out.write(outText);

if (out.isEnabled(SerializerFeature.WriteClassName) && fieldType != BigDecimal.class && val.scale() == 0) {
out.write('.');
}
}
}

BigIntegerCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是BigInteger值, 如果为null,
* 并且序列化开启WriteNullNumberAsZero特性, 输出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}

BigInteger val = (BigInteger) object;
out.write(val.toString());
}

StringCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
public void write(JSONSerializer serializer, String value) {
SerializeWriter out = serializer.out;

/** 当前object是string值, 如果为null,
* 并且序列化开启WriteNullStringAsEmpty特性, 输出空串""
*/
if (value == null) {
out.writeNull(SerializerFeature.WriteNullStringAsEmpty);
return;
}

out.writeString(value);
}

PrimitiveArraySerializer序列化

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

if (object == null) {
/** 当前object是数组值, 如果为null,
* 并且序列化开启WriteNullListAsEmpty特性, 输出空串""
*/
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}

/** 循环写int数组 */
if (object instanceof int[]) {
int[] array = (int[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeInt(array[i]);
}
out.write(']');
return;
}

/** 循环写short数组 */
if (object instanceof short[]) {
short[] array = (short[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeInt(array[i]);
}
out.write(']');
return;
}

/** 循环写long数组 */
if (object instanceof long[]) {
long[] array = (long[]) object;

out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeLong(array[i]);
}
out.write(']');
return;
}

/** 循环写boolean数组 */
if (object instanceof boolean[]) {
boolean[] array = (boolean[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.write(array[i]);
}
out.write(']');
return;
}

/** 循环写float数组 */
if (object instanceof float[]) {
float[] array = (float[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}

float item = array[i];
if (Float.isNaN(item)) {
out.writeNull();
} else {
out.append(Float.toString(item));
}
}
out.write(']');
return;
}

/** 循环写double数组 */
if (object instanceof double[]) {
double[] array = (double[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}

double item = array[i];
if (Double.isNaN(item)) {
out.writeNull();
} else {
out.append(Double.toString(item));
}
}
out.write(']');
return;
}

/** 写字节数组 */
if (object instanceof byte[]) {
byte[] array = (byte[]) object;
out.writeByteArray(array);
return;
}

/** char数组当做字符串 */
char[] chars = (char[]) object;
out.writeString(chars);
}

ObjectArrayCodec序列化

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
92
93
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
SerializeWriter out = serializer.out;

Object[] array = (Object[]) object;

/** 当前object是数组对象, 如果为null,
* 并且序列化开启WriteNullListAsEmpty特性, 输出空串[]
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}

int size = array.length;

int end = size - 1;

/** 当前object是数组对象, 如果为没有元素, 输出空串[] */
if (end == -1) {
out.append("[]");
return;
}

SerialContext context = serializer.context;
serializer.setContext(context, object, fieldName, 0);

try {
Class<?> preClazz = null;
ObjectSerializer preWriter = null;
out.append('[');

/**
* 如果开启json格式化,循环输出数组对象,
* 会根据数组元素class类型查找序列化实例输出
*/
if (out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.incrementIndent();
serializer.println();
for (int i = 0; i < size; ++i) {
if (i != 0) {
out.write(',');
serializer.println();
}
serializer.write(array[i]);
}
serializer.decrementIdent();
serializer.println();
out.write(']');
return;
}

for (int i = 0; i < end; ++i) {
Object item = array[i];

if (item == null) {
out.append("null,");
} else {
if (serializer.containsReference(item)) {
serializer.writeReference(item);
} else {
Class<?> clazz = item.getClass();

/** 如果当前序列化元素和前一次class类型相同,避免再一次class类型查找序列化实例 */
if (clazz == preClazz) {
preWriter.write(serializer, item, null, null, 0);
} else {
preClazz = clazz;
/** 查找数组元素class类型的序列化器 序列化item */
preWriter = serializer.getObjectWriter(clazz);
preWriter.write(serializer, item, null, null, 0);
}
}
out.append(',');
}
}

Object item = array[end];

if (item == null) {
out.append("null]");
} else {
if (serializer.containsReference(item)) {
serializer.writeReference(item);
} else {
serializer.writeWithFieldName(item, end);
}
out.append(']');
}
} finally {
serializer.context = context;
}
}

ObjectArrayCodec序列化主要判断是否开启格式化输出json,如果是输出添加适当的缩进。针对数组元素不一样会根据元素class类型查找具体的序列化器输出,这里优化了如果元素相同的元素避免冗余的查找序列化器。

MiscCodec序列化

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
SerializeWriter out = serializer.out;

if (object == null) {
out.writeNull();
return;
}

Class<?> objClass = object.getClass();

String strVal;
if (objClass == SimpleDateFormat.class) {
String pattern = ((SimpleDateFormat) object).toPattern();

/** 输出SimpleDateFormat类型的类型 */
if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (object.getClass() != fieldType) {
out.write('{');
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
serializer.write(object.getClass().getName());
out.writeFieldValue(',', "val", pattern);
out.write('}');
return;
}
}

/** 转换SimpleDateFormat对象成pattern字符串 */
strVal = pattern;
} else if (objClass == Class.class) {
Class<?> clazz = (Class<?>) object;
/** 转换Class对象成name字符串 */
strVal = clazz.getName();
} else if (objClass == InetSocketAddress.class) {
InetSocketAddress address = (InetSocketAddress) object;

InetAddress inetAddress = address.getAddress();
/** 转换InetSocketAddress对象成地址和端口字符串 */
out.write('{');
if (inetAddress != null) {
out.writeFieldName("address");
serializer.write(inetAddress);
out.write(',');
}
out.writeFieldName("port");
out.writeInt(address.getPort());
out.write('}');
return;
} else if (object instanceof File) {
/** 转换File对象成文件路径字符串 */
strVal = ((File) object).getPath();
} else if (object instanceof InetAddress) {
/** 转换InetAddress对象成主机地址字符串 */
strVal = ((InetAddress) object).getHostAddress();
} else if (object instanceof TimeZone) {
TimeZone timeZone = (TimeZone) object;
/** 转换TimeZone对象成时区id字符串 */
strVal = timeZone.getID();
} else if (object instanceof Currency) {
Currency currency = (Currency) object;
/** 转换Currency对象成币别编码字符串 */
strVal = currency.getCurrencyCode();
} else if (object instanceof JSONStreamAware) {
JSONStreamAware aware = (JSONStreamAware) object;
aware.writeJSONString(out);
return;
} else if (object instanceof Iterator) {
Iterator<?> it = ((Iterator<?>) object);
/** 迭代器转换成数组码字符串 [,,,] */
writeIterator(serializer, out, it);
return;
} else if (object instanceof Iterable) {
/** 迭代器转换成数组码字符串 [,,,] */
Iterator<?> it = ((Iterable<?>) object).iterator();
writeIterator(serializer, out, it);
return;
} else if (object instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) object;
Object objKey = entry.getKey();
Object objVal = entry.getValue();

/** 输出map的Entry值 */
if (objKey instanceof String) {
String key = (String) objKey;

if (objVal instanceof String) {
String value = (String) objVal;
out.writeFieldValueStringWithDoubleQuoteCheck('{', key, value);
} else {
out.write('{');
out.writeFieldName(key);
/** 根据value的class类型查找序列化器并输出 */
serializer.write(objVal);
}
} else {
/** 根据key、value的class类型查找序列化器并输出 */
out.write('{');
serializer.write(objKey);
out.write(':');
serializer.write(objVal);
}
out.write('}');
return;
} else if (object.getClass().getName().equals("net.sf.json.JSONNull")) {
out.writeNull();
return;
} else {
throw new JSONException("not support class : " + objClass);
}

out.writeString(strVal);
}

MiscCodec序列化的主要思想是吧JDK内部常用的对象简化处理,比如TimeZone只保留id输出,极大地降低了输出字节大小。

AppendableSerializer序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {

/** 当前object实现了Appendable接口, 如果为null,
* 并且序列化开启WriteNullStringAsEmpty特性, 输出空串""
*/
if (object == null) {
SerializeWriter out = serializer.out;
out.writeNull(SerializerFeature.WriteNullStringAsEmpty);
return;
}

/** 输出对象toString结果作为json串 */
serializer.write(object.toString());
}

ToStringSerializer序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
SerializeWriter out = serializer.out;

/** 如果为null, 输出空串"null" */
if (object == null) {
out.writeNull();
return;
}

/** 输出对象toString结果作为json串 */
String strVal = object.toString();
out.writeString(strVal);
}

AtomicCodec序列化

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
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

if (object instanceof AtomicInteger) {
AtomicInteger val = (AtomicInteger) object;
/** 获取整数输出 */
out.writeInt(val.get());
return;
}

if (object instanceof AtomicLong) {
AtomicLong val = (AtomicLong) object;
/** 获取长整数输出 */
out.writeLong(val.get());
return;
}

if (object instanceof AtomicBoolean) {
AtomicBoolean val = (AtomicBoolean) object;
/** 获取boolean值输出 */
out.append(val.get() ? "true" : "false");
return;
}

/** 当前object是原子数组类型, 如果为null,输出[] */
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}

/** 遍历AtomicIntegerArray,输出int数组类型 */
if (object instanceof AtomicIntegerArray) {
AtomicIntegerArray array = (AtomicIntegerArray) object;
int len = array.length();
out.write('[');
for (int i = 0; i < len; ++i) {
int val = array.get(i);
if (i != 0) {
out.write(',');
}
out.writeInt(val);
}
out.write(']');

return;
}

/** 遍历AtomicLongArray,输出long数组类型 */
AtomicLongArray array = (AtomicLongArray) object;
int len = array.length();
out.write('[');
for (int i = 0; i < len; ++i) {
long val = array.get(i);
if (i != 0) {
out.write(',');
}
out.writeLong(val);
}
out.write(']');
}

ReferenceCodec序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Object item;
/** 当前object是Reference类型,
* 调用get()查找对应的class序列化器输出
*/
if (object instanceof AtomicReference) {
AtomicReference val = (AtomicReference) object;
item = val.get();
} else {
item = ((Reference) object).get();
}
serializer.write(item);
}

CollectionCodec序列化

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
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;

/** 当前object是集合对象, 如果为null,
* 并且序列化开启WriteNullListAsEmpty特性, 输出空串[]
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}

Type elementType = null;
if (out.isEnabled(SerializerFeature.WriteClassName)
|| SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName))
{
/** 获取字段泛型类型 */
elementType = TypeUtils.getCollectionItemType(fieldType);
}

Collection<?> collection = (Collection<?>) object;

SerialContext context = serializer.context;
serializer.setContext(context, object, fieldName, 0);

if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (HashSet.class == collection.getClass()) {
out.append("Set");
} else if (TreeSet.class == collection.getClass()) {
out.append("TreeSet");
}
}

try {
int i = 0;
out.append('[');
for (Object item : collection) {

if (i++ != 0) {
out.append(',');
}

if (item == null) {
out.writeNull();
continue;
}

Class<?> clazz = item.getClass();

/** 获取整形类型值,输出 */
if (clazz == Integer.class) {
out.writeInt(((Integer) item).intValue());
continue;
}

/** 获取整形长类型值,输出并添加L标识(如果开启WriteClassName特性) */
if (clazz == Long.class) {
out.writeLong(((Long) item).longValue());

if (out.isEnabled(SerializerFeature.WriteClassName)) {
out.write('L');
}
continue;
}

/** 根据集合类型查找序列化实例处理,JavaBeanSerializer后面单独分析 */
ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz);
if (SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName)
&& itemSerializer instanceof JavaBeanSerializer) {
JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) itemSerializer;
javaBeanSerializer.writeNoneASM(serializer, item, i - 1, elementType, features);
} else {
itemSerializer.write(serializer, item, i - 1, elementType, features);
}
}
out.append(']');
} finally {
serializer.context = context;
}
}
感谢您的阅读,本文由 诣极的博客 版权所有。如若转载,请注明出处:诣极的博客(https://zonghaishang.github.io/2018/09/30/Fastjson源码解析-序列化(五)-json内部注册序列化解析/
序列化(四)
词法和语法解析(七)