网络传输数据需要定义一种数据格式,比较一下各种协议的性能:
序列化时间 | 反序列化时间 | 大小 | 压缩后大小 | |
---|---|---|---|---|
java序列化 | 8654 | 43787 | 889 | 541 |
hessian | 6725 | 10460 | 501 | 313 |
protobuf | 2964 | 1745 | 239 | 149 |
thrift | 3177 | 1949 | 349 | 197 |
avro | 3520 | 1948 | 221 | 133 |
json-lib | 45788 | 149741 | 485 | 263 |
jackson | 3052 | 4161 | 503 | 271 |
fastjson | 2595 | 1472 | 468 | 251 |
测试数据:https://github.com/eishay/jvm-serializers/wiki/TestValue
这是一个468bytes的JSON Bytes测试,从测试结果来看,无论序列化和反序列化,json的性能已经不是瓶颈。今天重点关注了jackson的实现。
jackson对json的实现主要可以分为2部分parser和deserialize ,分别通过JsonParser和JsonDeserializer实现。
1.JsonParser
ReaderBasedParser是JsonParser的最终实现,继承关系如下:
public abstract class JsonParser {
}
public abstract class JsonParserMinimalBase extends JsonParser{
}
public abstract class JsonParserBase extends JsonParserMinimalBase{
}
public final class ReaderBasedParser extends JsonParserBase{
}
JsonParser 定义了基本的读取API。可以通过JsonFactory
来创建 JsonParser,其实parser就是做词法分析,实际上就是把输入的json字符串转换成char[],每次一个字符的读取,JsonToken是一个enum,定义了json中有用的token type:
public enum JsonToken{
START_OBJECT("{"),
/**
* START_OBJECT is returned when encountering '}'
* which signals ending of an Object value
*/
END_OBJECT("}"),
/**
* START_OBJECT is returned when encountering '['
* which signals starting of an Array value
*/
START_ARRAY("["),
/**
* START_OBJECT is returned when encountering ']'
* which signals ending of an Array value
*/
END_ARRAY("]"),
}
2. JsonDeserializer
JsonDeserializer其实是string---->各种java类型的发序列化实现,jackson根据ava类型定义了不同的Deserializer,比如UntypedObjectDeserializer,CollectionDeserializer,ObjectArrayDeserializer,StringCollectionDeserializer,PrimitiveOrWrapperDeserializer
3.jackson一些小技巧
允许单引号:
String json = "{'photoId': '1012309', 'id': '1001'}";
JsonFactory factory = new JsonFactory();
ObjectMapper objectMapper = new ObjectMapper(factory);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
JsonParser jsonParser = factory.createJsonParser(json);
nul对象转换成空字符:
package com.duitang.dboss.resolve.json;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
public class NullStringSerializer extends JsonSerializer<Object> {
public final static NullStringSerializer instance = new NullStringSerializer();
private NullStringSerializer(){
super();
}
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString("");
}
}
StdSerializerProvider sp = new StdSerializerProvider();
sp.setNullValueSerializer(NullStringSerializer.instance);
objectMapper = new ObjectMapper(jsonFactory);
objectMapper.setSerializerProvider(sp);