前言
JSON作为WEB的通信格式被广泛运用着。随之,Java的有多个JSON库产生,你至少应该用过/听过这三种:Jackson、Gson、Fastjson。Jackson是一个简单的、功能强大的、基于Java的应用库。它可以很方便完成Java对象和Json对象(xml文档or其它格式)进行互转。也是Spring家族的默认JSON/XML解析器。
JSON的生成
以下是json生成的例子
public void serialize() throws IOException {
JsonFactory jsonFactory = new JsonFactory();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (JsonGenerator jsonGenerator = jsonFactory.createGenerator(byteArrayOutputStream, JsonEncoding.UTF8)) {
jsonGenerator.useDefaultPrettyPrinter();
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "yoyo");
jsonGenerator.writeNumberField("age", 18);
jsonGenerator.writeEndObject();
}
System.out.println( byteArrayOutputStream.toString());
}
很容易的得出方法是围绕着JsonGenerator
JsonGenerator
主要负责生成json,提供生成json的抽象方法。
public abstract class JsonGenerator {
// 设置各种组件规则
public enum Feature {
// 自动关闭目标(流)。
// true:调用JsonGenerator#close()便会自动关闭底层的I/O流
// false:底层I/O流请手动关闭
AUTO_CLOSE_TARGET(true),
// 是否自动补全json
// true:开启自动补齐,缺少‘{’ ‘[’字符会帮忙补全
// false:关闭
AUTO_CLOSE_JSON_CONTENT(true),
// 底层假如是带有缓冲区的I/O写数据流时
// true:当JsonGenerator调用close()/flush()方法时,自动强刷I/O流里面的数据
// false:请手动处理
FLUSH_PASSED_TO_STREAM(true),
// JSON对象字段名是否为使用""双引号括起来.
// true:字段名使用""括起来 -> 遵循JSON规范
// false:字段名不使用""括起来 -> 不遵循JSON规范
QUOTE_FIELD_NAMES(true),
// float/double的[NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY]特殊值。用“”的方式输出
// true: "NaN" "-Infinity" "Infinity" -> 遵循JSON规范
// flase: NaN -Infinity Infinity -> 不遵循JSON规范
QUOTE_NON_NUMERIC_NUMBERS(true),
// 强制将所有数字写成字符串,即使底层数据格式真的是数字。
// true:所有数字强制写为字符串
// false:不做处理
WRITE_NUMBERS_AS_STRINGS(false),
// 控制写java.math.BigDecimal的行为:
// true:使用BigDecimal#toPlainString()方法输出
// false: 使用默认输出方式(取决于BigDecimal是如何构造的)
WRITE_BIGDECIMAL_AS_PLAIN(false),
// 超过0-127的字符,直接使用\uxxxx的统一编码方式输出
// true: 统一编码方式输出
// false: 不做处理
ESCAPE_NON_ASCII(false),
// 是否去严格的检测重复属性名。
// true:检测是否有重复字段名,若有,则抛出JsonParseException异常
// false:不检测JSON对象重复的字段名,即:相同字段名都要解析
STRICT_DUPLICATE_DETECTION(false),
// 如果底层流是protobuf等第三方协议模拟的,其要求的必传字段,我们没有,是否忽略
// true: 忽略底层的要求
// false: 抛出JsonProcessingException异常
IGNORE_UNKNOWN(false),
;
}
// 解决json中的各种类型分割符,方便自定义
protected PrettyPrinter _cfgPrettyPrinter;
// 确定jackson的版本
// @see PackageVersion
// @see Versioned
Version version();
// 把缓存区的数据提交到OutputStream中
// @see Flushable
void flush() throws IOException;
// 关闭管道
// @see Closeable
// @see AutoCloseable
public void close() throws IOException;
}
PrettyPrinter
json中的各种类型分割符及文本输出格式
// 将json中的一些分割符提取出来,用于自定义
// @see MinimalPrettyPrinter 单行的json
// @see DefaultPrettyPrinter 格式化后的json
public interface PrettyPrinter
{
// 定义默认三种符号
// objectFieldValueSeparator 对象Field-Value用 ":"。例:{Field:Value}
// objectEntrySeparator 对象与对象用 ","。例:{{},{}}
// arrayValueSeparator 数组中的值用 ","。例:[{},{}]
public final static Separators DEFAULT_SEPARATORS = Separators.createDefaultInstance();
// 2个json root对象的分割符号
// 例: {} 分割符号位置 {}
public final static SerializedString DEFAULT_ROOT_VALUE_SEPARATOR = new SerializedString(" ");
// 定义JsonGenerator中插入“2个json root对象的分割符号”
// @see DEFAULT_ROOT_VALUE_SEPARATOR
void writeRootValueSeparator(JsonGenerator gen) throws IOException;
// 定义向JsonGenerator中插入,对象起始符号,默认为 “{”
void writeStartObject(JsonGenerator gen) throws IOException;
// 定义向JsonGenerator中插入,对象结束符号,默认为 “}”
// nrOfEntries 缩进参数
void writeEndObject(JsonGenerator gen, int nrOfEntries) throws IOException;
// 定义向JsonGenerator中插入,对象与对象分割符号
// @see objectEntrySeparator
void writeObjectEntrySeparator(JsonGenerator gen) throws IOException;
// 定义向JsonGenerator中插入,对象Field-Value分割符号
// @see objectFieldValueSeparator
void writeObjectFieldValueSeparator(JsonGenerator gen) throws IOException;
// 定义向JsonGenerator中插入,数组起始符号,默认为 “[”
void writeStartArray(JsonGenerator gen) throws IOException;
// 定义向JsonGenerator中插入,数组结束符号,默认为 “]”
void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException;
// 定义向JsonGenerator中插入,数组中的值分割符号
// @see arrayValueSeparator
void writeArrayValueSeparator(JsonGenerator gen) throws IOException;
// 对象开始家的缩进判断输入
void beforeArrayValues(JsonGenerator gen) throws IOException;
// 数组开始家的缩进判断输入
void beforeObjectEntries(JsonGenerator gen) throws IOException;
}
GeneratorBase
实现JsonGenerator的部分定义。偏向json组装
public class GeneratorBase
{
// jdk char默认使用的utf-16, 配合unicode高低位设计表示4字节字符
public final static int SURR1_FIRST = 0xD800;
public final static int SURR1_LAST = 0xDBFF;
public final static int SURR2_FIRST = 0xDC00;
public final static int SURR2_LAST = 0xDFFF;
// 默认的FEATURES设置
protected final static int DERIVED_FEATURES_MASK =
Feature.WRITE_NUMBERS_AS_STRINGS.getMask()
| Feature.ESCAPE_NON_ASCII.getMask()
| Feature.STRICT_DUPLICATE_DETECTION.getMask()
;
// json组装时当前动作的文本信息
protected final static String WRITE_BINARY = "write a binary value";
protected final static String WRITE_BOOLEAN = "write a boolean value";
protected final static String WRITE_NULL = "write a null";
protected final static String WRITE_NUMBER = "write a number";
protected final static String WRITE_RAW = "write a raw (unencoded) value";
protected final static String WRITE_STRING = "write a string";
// json中 DECIMAL的精度设置
protected final static int MAX_BIG_DECIMAL_SCALE = 9999;
// 一个Object-json的转换工具,后面介绍
protected ObjectCodec _objectCodec;
// features存储字段
// @see DERIVED_FEATURES_MASK
protected int _features;
// 是否将数值按字符打印
// @see Feature#WRITE_NUMBERS_AS_STRINGS
protected boolean _cfgNumbersAsStrings;
// Generator运行上下文
protected JsonWriteContext _writeContext;
// Generator是否关闭
protected boolean _closed;
}
JsonWriteContext
json的组装上下文。检查组装时的错误
public class JsonStreamContext
{
// 表示对象类型,Root,数组,对象
protected final static int TYPE_ROOT = 0;
protected final static int TYPE_ARRAY = 1;
protected final static int TYPE_OBJECT = 2;
// 对象类型
protected int _type;
// 对象中最大实体的下标
protected int _index;
}
public class JsonWriteContext
{
// 各状态write规则
// 当插入 _index = 0实体时,写入成功
public final static int STATUS_OK_AS_IS = 0;
// 当插入 _index > 0实体时,写入成功,但要在写入前,加“,”分割符
// @see objectEntrySeparator
// @see arrayValueSeparator
public final static int STATUS_OK_AFTER_COMMA = 1;
// 当插入value时,写入成功,但要在写入前,加“:”分割符
// @see objectEntrySeparator
public final static int STATUS_OK_AFTER_COLON = 2;
// 当root对象,插入第二个json时的分割符
// @see DEFAULT_ROOT_VALUE_SEPARATOR
public final static int STATUS_OK_AFTER_SPACE = 3;
// 当插入name时,写入失败,应该写value
// 当前对象不是Object,却在写Field
// 当前对象是Object,但已经有Field了
public final static int STATUS_EXPECT_VALUE = 4;
// 当插入value时,写入失败,应该写name
// 当前对象是Object,但没有Field了
public final static int STATUS_EXPECT_NAME = 5;
// 父亲操作对象
protected final JsonWriteContext _parent;
// 判断当前对象中name,是否重复
protected DupDetector _dups;
// 子操作对象,随着操作子级的变动而变动
protected JsonWriteContext _child;
// 当前正在操作的 FeildName
protected String _currentName;
// 当前正在操作的 FeildValue
protected Object _currentValue;
// 判断是否已经写了name,可以写value了
// @see STATUS_EXPECT_VALUE
protected boolean _gotName;
}
JsonGeneratorImpl
完善JsonGenerator的实现,偏向字符处理
public class JsonGeneratorImpl
{
// ASCII 权限数组,对其中一些字符进行控制
// ch == 0 直接输出
// ch > 0 加上\
// ch = -2 自定义转换 @see CharacterEscapes.getEscapeSequence
// ch == -1 unicode方式输出
protected final static int[] sOutputEscapes = CharTypes.get7BitOutputEscapes();
// 对底层io流缓存区管理对象
// @see BufferRecycler
final protected IOContext _ioContext;
// ASCII 权限数组 默认为 sOutputEscapes
protected int[] _outputEscapes = sOutputEscapes;
// 最大不转成unicode的字符值,如果ESCAPE_NON_ASCII为true
// @see Feature.ESCAPE_NON_ASCII
protected int _maximumNonEscapedChar;
// 字符转义工具,可自定义转义功能, 否则使用默认的 _outputEscapes
protected CharacterEscapes _characterEscapes;
// root对象中实体分割符
protected SerializableString _rootValueSeparator
= DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
// 是否给 json name写上“”
// @see QUOTE_FIELD_NAMES
protected boolean _cfgUnqNames;
}
UTF8JsonGenerator,WriterBasedJsonGenerator 根据各实编码的特点对JsonGenerator进行部分重写
JSON的解析
以下是json解析的例子
public void deserializer() throws Exception {
String TEST_JSON_STR = "{\"name\":\"yoyo\",\"age\":15}";
JsonFactory jsonFactory = new JsonFactory();
JsonParser jsonParser = jsonFactory.createParser(TEST_JSON_STR);
if (jsonParser.nextToken() != JsonToken.START_OBJECT) {
throw new IOException("起始位置没有大括号");
}
Person result = new Person();
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jsonParser.getCurrentName();
System.out.println(jsonParser.nextToken());
switch (fieldName) {
case "name":
result.setName(jsonParser.getValueAsString());
break;
case "age":
result.setAge(jsonParser.getValueAsInt());
break;
default:
throw new IOException("未知字段 '" + fieldName + "'");
}
}
System.out.println(result);
}
很容易的得出方法是围绕着JsonParser
JsonParser
定义一些Json解析的函数声明
public class JsonParser
{
// byte 的取值范围包括无符号的情况 【-127-255】
private final static int MIN_BYTE_I = (int) Byte.MIN_VALUE;
private final static int MAX_BYTE_I = (int) 255;
// short 的取值范围
private final static int MIN_SHORT_I = (int) Short.MIN_VALUE;
private final static int MAX_SHORT_I = (int) Short.MAX_VALUE;
// java中的几咱数值类型
public enum NumberType {
INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL
};
public enum Feature {
// 是否close自动关闭底层流
// @see JsonGenerator##AUTO_CLOSE_TARGET
AUTO_CLOSE_SOURCE(true),
// 是否允许/* */或者//这种类型的注释出现
ALLOW_COMMENTS(false),
// 开启后将支持Yaml格式的的注释,也就是#形式的注释语法
ALLOW_YAML_COMMENTS(false),
// 是否允许属性名「不带双引号""」
// @see JsonGenerator##QUOTE_FIELD_NAMES
ALLOW_UNQUOTED_FIELD_NAMES(false),
// 是否允许属性名支持单引号,也就是使用''包裹
ALLOW_SINGLE_QUOTES(false),
// 是否允许JSON字符串包含非引号「控制字符」(值小于32的ASCII字符,包含制表符和换行符)。
// 由于JSON规范要求对所有控制字符使用引号,这是一个非标准的特性,因此默认禁用
ALLOW_UNQUOTED_CONTROL_CHARS(false),
// 是否允许**反斜杠**转义任何字符
// 例: {"aa":"\\"}, \\不合法
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false),
// 是否允许像00001这样的“数字”出现
ALLOW_NUMERIC_LEADING_ZEROS(false),
// 是否允许一些解析器识别一组**“非数字”(如NaN)**作为合法的浮点数值
ALLOW_NON_NUMERIC_NUMBERS(false),
// 是否允许支持「JSON数组中」“缺失”值
// 例: [value1, , value3]
ALLOW_MISSING_VALUES(false),
// 是否允许最后一个多余的逗号(一定是最后一个)
ALLOW_TRAILING_COMMA(false),
// 是否允许JSON串有两个相同的属性key,默认是「允许的」
// @see JsonGenerator##STRICT_DUPLICATE_DETECTION
STRICT_DUPLICATE_DETECTION(false),
// 是否忽略「没有定义」的属性key
// @see JsonGenerator#IGNORE_UNKNOWN
IGNORE_UNDEFINED(false),
// 是否构建JsonLocation对象来表示每个part的来源
// @see JsonParser#getCurrentLocation()
INCLUDE_SOURCE_IN_LOCATION(true),
}
// 具体的参数配置
protected int _features;
// 协助信息打印的工具
protected transient RequestPayload _requestPayload;
}
ParserMinimalBase
实现JsonParser的部份功能,主要偏向定义字符规则
public abstract class ParserMinimalBase
{
// 控制符中的空白字符,用来跳过的
protected final static int INT_TAB = '\t';
protected final static int INT_LF = '\n';
protected final static int INT_CR = '\r';
protected final static int INT_SPACE = 0x0020;
// json中的标记字符,用来跳过的
protected final static int INT_LBRACKET = '[';
protected final static int INT_RBRACKET = ']';
protected final static int INT_LCURLY = '{';
protected final static int INT_RCURLY = '}';
protected final static int INT_QUOTE = '"';
protected final static int INT_APOS = '\'';
protected final static int INT_BACKSLASH = '\\';
protected final static int INT_SLASH = '/';
protected final static int INT_ASTERISK = '*';
protected final static int INT_COLON = ':';
protected final static int INT_COMMA = ',';
protected final static int INT_HASH = '#';
// 数值字符(包括null),用来判断非法数值
protected final static int INT_0 = '0';
protected final static int INT_9 = '9';
protected final static int INT_MINUS = '-';
protected final static int INT_PLUS = '+';
protected final static int INT_PERIOD = '.';
protected final static int INT_e = 'e';
protected final static int INT_E = 'E';
protected final static char CHAR_NULL = '\0';
// 数值类型
protected final static int NR_UNKNOWN = 0;
protected final static int NR_INT = 0x0001;
protected final static int NR_LONG = 0x0002;
protected final static int NR_BIGINT = 0x0004;
protected final static int NR_DOUBLE = 0x008;
protected final static int NR_BIGDECIMAL = 0x0010;
protected final static int NR_FLOAT = 0x020;
// 各数值的取值范围
protected final static BigInteger BI_MIN_INT = BigInteger.valueOf(Integer.MIN_VALUE);
protected final static BigInteger BI_MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
protected final static BigInteger BI_MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE);
protected final static BigInteger BI_MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
protected final static BigDecimal BD_MIN_LONG = new BigDecimal(BI_MIN_LONG);
protected final static BigDecimal BD_MAX_LONG = new BigDecimal(BI_MAX_LONG);
protected final static BigDecimal BD_MIN_INT = new BigDecimal(BI_MIN_INT);
protected final static BigDecimal BD_MAX_INT = new BigDecimal(BI_MAX_INT);
protected final static long MIN_INT_L = (long) Integer.MIN_VALUE;
protected final static long MAX_INT_L = (long) Integer.MAX_VALUE;
protected final static double MIN_LONG_D = (double) Long.MIN_VALUE;
protected final static double MAX_LONG_D = (double) Long.MAX_VALUE;
protected final static double MIN_INT_D = (double) Integer.MIN_VALUE;
protected final static double MAX_INT_D = (double) Integer.MAX_VALUE;
// 错误信息的最大长度
protected final static int MAX_ERROR_TOKEN_LENGTH = 256;
// 当前正常访问字符并结合上文判断出的类型
protected JsonToken _currToken;
}
ParserBase
实现JsonParser的部份功能,主要对字符流解析的处理
public abstract class ParserBase extends ParserMinimalBase
{
// 对底层io流缓存区管理对象
// @see BufferRecycler
final protected IOContext _ioContext;
// JsonParser组件的状态
protected boolean _closed;
// buffer 中当前读取的字符下标
protected int _inputPtr;
// buffer 中有效的字符数
protected int _inputEnd;
// 全文已被加载过的字符坐标 = buffer 中首字符在全文偏移量 - 1
protected long _currInputProcessed;
// 正在处理文本的行坐标,如果文标中不存在换行符,则一直为1
protected int _currInputRow = 1;
// 当前行,相对buffer的坐标,可能为负值
protected int _currInputRowStart;
//*** location-start **//
// 当前输入字符相对文件的坐标:currInputProcessed + ptr
protected long _tokenInputTotal;
// 当前输入字符相对文本的行坐标
protected int _tokenInputRow = 1;
// 当前输入字符相对当前行首字符的坐标: _inputPtr - _currInputRowStart
protected int _tokenInputCol;
//*** location-end **//
// 解析运行上下文
protected JsonReadContext _parsingContext;
// 下一个Token,作用处理 feildName 然后 next必须是value
protected JsonToken _nextToken;
// 文本缓存区,buffer
protected final TextBuffer _textBuffer;
// 临时buffer, 复制返回 Buffer用于FileName内容
protected char[] _nameCopyBuffer;
// 用来控制FileName重复访问而导致 _nameCopyBuffer 内容重复组装
protected boolean _nameCopied;
// 包装字节数组,方便字节操作.类似 StringBuilder
protected ByteArrayBuilder _byteArrayBuilder;
// 针对value的字节码,使用_byteArrayBuilder造出来的
// 与_nameCopyBuffer作用相似
protected byte[] _binaryValue;
// 数值value的类型
protected int _numTypesValid = NR_UNKNOWN;
// 各数值类型的值
// 与 _binaryValue作用相似
protected int _numberInt;
protected long _numberLong;
protected double _numberDouble;
protected BigInteger _numberBigInt;
protected BigDecimal _numberBigDecimal;
// int类型是否为-
protected boolean _numberNegative;
// 表示数值类型的整数部份长度
protected int _intLength;
// 数值类型的小数部分长度
protected int _fractLength;
// 数值类型的指数部分长度
protected int _expLength;
}
ReaderBasedJsonParser,UTF8StreamJsonParser 根据各实编码的特点对JsonGenerator进行部分重写
JSON总结
JsonGenerator和JsonParser两者都是使用JsonFactory配置和构建。这个工厂实例是线程安全的。其主要功能如图:
主要设计思想
- 流式(Streaming):此概念和Java8中的Stream流是不同的。这里指的是IO流,因此具有最低的开销和最快的读/写操作(记得关流哦)
- 增量模式(incremental
mode):它表示每个部分一个一个地往上增加,类似于垒砖。使用此流式API读写JSON的方式使用的均是增量模式 - JsonToken:每一部分都是一个独立的Token(有不同类型的Token),最终被“拼凑”起来就是一个JSON。这是流式API里很重要的一个抽象概念。
JSON高级应用
Streaming流处理模块,确实能高效率的实现json的序列和反序列。但对程序员不太友好.JsonSon引入了数据绑在模块及树形模块。
@Test
public void codecTest() throws Exception {
Person person = new Person();
person.setAge(18);
person.setName("yoyo");
JsonFactory jsonFactory = new JsonFactory();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectCodec objectCodec = new ObjectMapper();
try (JsonGenerator jsonGenerator = jsonFactory.createGenerator(byteArrayOutputStream, JsonEncoding.UTF8)) {
jsonGenerator.setCodec(objectCodec);
jsonGenerator.writeObject(person);
}
String jsonStr = byteArrayOutputStream.toString();
System.out.println(jsonStr);
try (JsonParser jsonParser = jsonFactory.createParser(jsonStr)) {
jsonParser.setCodec(objectCodec);
Person _person = jsonParser.readValueAs(Person.class);
System.out.println(_person);
}
try (JsonParser jsonParser = jsonFactory.createParser(jsonStr)) {
jsonParser.setCodec(objectCodec);
TreeNode treeNode = jsonParser.readValueAsTree();
System.out.println(treeNode.at("/name"));
}
}
很容易的得出方法是围绕着ObjectMapper
TreeCodec
树形解析器,提供json-树形的解析器
public abstract class TreeCodec
{
// 从解析器中读取数据转成-树形
public abstract <T extends TreeNode> T readTree(JsonParser p) throws IOException, JsonProcessingException;
// 从将树形写入生成器中
public abstract void writeTree(JsonGenerator g, TreeNode tree) throws IOException, JsonProcessingException;
public abstract TreeNode createArrayNode();
public abstract TreeNode createObjectNode();
// 根据树形内容创建解析器
public abstract JsonParser treeAsTokens(TreeNode node);
}
TreeNode
json树形结构定义树形的一些操作
public interface TreeNode
{
// 返回当前节点的token类型
JsonToken asToken();
// 返回当前节点值的类型
JsonParser.NumberType numberType();
// 当前节点子节点数
int size();
// 节点是否有value值
boolean isValueNode();
// 是否容器结点 array, object
boolean isContainerNode();
// 是否虚拟节点,防止null异常用的
boolean isMissingNode();
// 略
boolean isArray();
boolean isObject();
TreeNode get(String fieldName);
TreeNode get(int index);
// 找不到,返回MissingNode
TreeNode path(String fieldName);
TreeNode path(int index);
// 根据路径去查找
TreeNode at(JsonPointer ptr);
TreeNode at(String jsonPointerExpression) throws IllegalArgumentException;
// 根据当前节点创建json解析器
JsonParser traverse();
JsonParser traverse(ObjectCodec codec);
}
ObjectCodec
定义对实体-json的映射提供接口
public abstract class ObjectCodec
{
// 通过class+json解析器到实体
public abstract <T> T readValue(JsonParser p, Class<T> valueType)
throws IOException;
public abstract <T> T readValue(JsonParser p, TypeReference<?> valueTypeRef)
throws IOException;
public abstract <T> T readValue(JsonParser p, ResolvedType valueType)
throws IOException;
// 通过class+json解析器到实体列表
public abstract <T> Iterator<T> readValues(JsonParser p, Class<T> valueType)
throws IOException;
public abstract <T> Iterator<T> readValues(JsonParser p, TypeReference<?> valueTypeRef)
throws IOException;
public abstract <T> Iterator<T> readValues(JsonParser p, ResolvedType valueType)
throws IOException;
// 将对象通过Json生成器序列化
public abstract void writeValue(JsonGenerator gen, Object value) throws IOException;
}
ObjectMapper
利用JAVA的反射机制,对ObjectCodec的实现
public class ObjectMapper{
public enum DefaultTyping {
// 当类里的属性声明为一个Object时,会对该属性进行序列化和反序列化,并且明确规定类名
// 例: {"age":10,"name":"yoyo","object":["jackson.JavaLangObject$MySex",{"sex":100}]}
// object 被翻译成 "object":["com.l1nk3r.jackson.l1nk3r",{"length":100}]
JAVA_LANG_OBJECT,
// 除了JAVA_LANG_OBJECT提到的特征,当类里有 Interface 、 AbstractClass 声明对象时,也可以被支持
// 例: {"age":10,"name":"yoyo","object":["jackson.JavaLangObject$MySex",{"sex":0}]}
// 此时object 是Interface声明的
// jackson的默认选项。
OBJECT_AND_NON_CONCRETE,
// 除了上文提到的特征,还支持上文全部类型的Array类型。
// 例: {"age":10,"name":"yoyo","object":["[Ljava.lang.Object;",[["jackson.JavaLangObject$MySex",{"sex":0}]]]}
// 此时object 是数组声明的
NON_CONCRETE_AND_ARRAYS,
// 包括上文提到的所有特征, 还支持非final对象的翻译,除了少数(String、Boolean、Integer、Double)
// 例: ["jackson.JavaLangObject$People",{"age":10,"name":"yoyo","object":["[Ljava.lang.Object;",[["jackson.JavaLangObject$MySex",{"sex":0}]]]}]
// 如果在 People class类上面加上final,就和NON_CONCRETE_AND_ARRAYS 结果一样
NON_FINAL
}
// 默认树形的结构JsonNode
private final static JavaType JSON_NODE_TYPE =
SimpleType.constructUnsafe(JsonNode.class);
// 默认注解解析器
protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector();
// 默认的一些工具每件配置
protected final static BaseSettings DEFAULT_BASE = new BaseSettings(
null, // cannot share global ClassIntrospector any more (2.5+)
DEFAULT_ANNOTATION_INTROSPECTOR,
null, TypeFactory.defaultInstance(),
null, StdDateFormat.instance, null,
Locale.getDefault(),
null, // to indicate "use Jackson default TimeZone" (UTC since Jackson 2.7)
Base64Variants.getDefaultVariant() // 2.1
);
// json工厂,用于创建 JsonParser 和 JsonGenerator
protected final JsonFactory _jsonFactory;
// 类型工厂,封装基本类型和泛型
protected TypeFactory _typeFactory;
// 管理要被注入pojo的值
protected InjectableValues _injectableValues;
// 多态解析器
protected SubtypeResolver _subtypeResolver;
// bean的最终配置集
protected final ConfigOverrides _configOverrides;
// 扩展配置
// @see MixInResolver
protected SimpleMixInResolver _mixIns;
// 序列化配置
protected SerializationConfig _serializationConfig;
// 序列化工厂, 可创建不同类型的序列化类
protected SerializerFactory _serializerFactory;
// 序列上下文
// 1. 缓存已解析好的javaType-JsonSerializer的缓存机制
// 2. 提供全局的上下文功能,如果全局时间格式,view, Attr
// 核心逻辑:
// 1. 根据对象构建JavaType与之对应的JsonSerializer
// 2. JsonSerializer使用的是外观模式,根据属性具体类型层层序列化下去
protected DefaultSerializerProvider _serializerProvider;
// 反序列化配置
protected DeserializationConfig _deserializationConfig;
// 反序列化上下文,同_serializerProvider
protected DefaultDeserializationContext _deserializationContext;
// 类型模块的集合,主要用来防止重覆注册
// @see MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS
protected Set<Object> _registeredModuleTypes;
// root级的类型与对应的解析器缓存
final protected ConcurrentHashMap<JavaType, JsonDeserializer<Object>> _rootDeserializers
= new ConcurrentHashMap<JavaType, JsonDeserializer<Object>>(64, 0.6f, 2);
}
对象序列化过程
以JsonGenerator##writeObject 函数为入口。最终调用ObjectMapper##writeValue
// ObjectMapper##writeValue 省略了部分代码
public void writeValue(JsonGenerator g, Object value){
// 对象序列化参数
SerializationConfig config = getSerializationConfig();
// 1. 使用最新的配置和SerializerFactory去覆盖默认的。相当于初始化DefaultSerializerProvider
// 2. 调用DefaultSerializerProvider##serializeValue真正解析
_serializerProvider(config).serializeValue(g, value);
}
// DefaultSerializerProvider##serializeValue 省略了部分代码
public void serializeValue(JsonGenerator gen, Object value) {
// 获取对象的类型
final Class<?> cls = value.getClass();
// 根据类型查询对应的JsonSerializer解析类
final JsonSerializer<Object> ser = findTypedValueSerializer(cls, true, null);
// 使用 JsonSerializer 真正的去解析
_serialize(gen, value, ser);
}
针对SerializationConfig进行以下分析
MixInResolver
主要指供注册隐式和统一配置的方式。
public interface MixInResolver{
// 查找cls是否有对应 "mix-in"
// mix-in 作用是隐式标记注解,最后会和cls取个并集
// @see AnnotatedClassResolver
public Class<?> findMixInClassFor(Class<?> cls);
}
MapperConfig
部份对象映身配置,主要关系字段属性的转换关系
public enum MapperFeature{
// 是否使用注解配置,如果允许,则使用AnnotationIntrospector扫描配置
// @see AnnotationIntrospector
USE_ANNOTATIONS(true),
// 使用get方法设置,如果属性是 Map/Collection
// @see BeanDeserializerFactory##_isSetterlessType
USE_GETTERS_AS_SETTERS(true),
// 忽略 transient 修饰的属性
PROPAGATE_TRANSIENT_MARKER(false),
// 该特性决定是否使用creator方法来根据公共构造函数以
// 枚举使用“valueOf”的静态单参数方法来创建实例
// 如果不开启只能使用参构造
AUTO_DETECT_CREATORS(true),
// 这个特性决定是否非静态field被当做属性。如果true,则所有公共成员field都被当做属性, 否则只有注解,才会被当做属性field。
AUTO_DETECT_FIELDS(true),
// 获取getter方法,规则前缀为get。
AUTO_DETECT_GETTERS(true),
// 获取getter方法,规则前缀为is
AUTO_DETECT_IS_GETTERS(true),
// 获取setter方法,规则前缀为set
AUTO_DETECT_SETTERS(true),
// 获取的getter方法需要setter方法认证。如果没有setter则getter不通过
REQUIRE_SETTERS_FOR_GETTERS(false),
// 利用java反射,设值final字段
ALLOW_FINAL_FIELDS_AS_MUTATORS(true),
// 对内部属性(没有对应 getter方法)使用反射设置值
INFER_PROPERTY_MUTATORS(true),
// 内部属性使用构造的方式注入
// @see JsonCreator
INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES(true),
// 当访问属性时候,提升访问权限
// 如果设置为true, 则通过反射调用方法AccessibleObject#setAccessible 来允许访问不能访问的对象。
CAN_OVERRIDE_ACCESS_MODIFIERS(true),
// AccessibleObject#setAccessible 具体的参数值
// true 指示反射的对象在使用时应该取消 Java 语言访问检查
// false 反射的对象应该实施 Java 语言访问检查
// 目的是动态的可以开关反射设置,而不是设了就没法关
OVERRIDE_PUBLIC_ACCESS_MODIFIERS(true),
// 序列化时,class特征:使用的是静态类型,还是实际运行类型
USE_STATIC_TYPING(false),
// 抽象类型反序列化,是否使用默认类型
// @ee JsonTypeInfo.defaultImpl
USE_BASE_TYPE_AS_DEFAULT_IMPL(false),
// 是否启用注解视图功能, 一个pojo 利用JsonView开启多视图
// @see JsonView
DEFAULT_VIEW_INCLUSION(true),
// 是否对属性使用排序,默认排序按照字母顺序。
SORT_PROPERTIES_ALPHABETICALLY(false),
// 序列化时,忽略字段大小写
ACCEPT_CASE_INSENSITIVE_PROPERTIES(false),
// 序列化时,忽略枚举大小写
ACCEPT_CASE_INSENSITIVE_ENUMS(false),
// 属性使用包装名,如果开启
USE_WRAPPER_NAME_AS_PROPERTY_NAME(false),
// 设置转换模式,true为xml
USE_STD_BEAN_NAMING(false),
// 序列化属性别名
// @see JsonProperty
ALLOW_EXPLICIT_PROPERTY_RENAMING(false),
// 启用此功能,字符串“true” 可转成boolean "1.0" 转成double
ALLOW_COERCION_OF_SCALARS(true),
// 忽略重覆的模块注册
// @see ObjectMapper.registerModule()
IGNORE_DUPLICATE_MODULE_REGISTRATIONS(true),
// 2 json merge 时发全冲突,自动略过
IGNORE_MERGE_FOR_UNMERGEABLE(true);
}
public final class BaseSettings{
// 世界统一时区
private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("UTC");
// 根据配置,封闭类的序列化基本信息
// @see BeanDescription
protected final ClassIntrospector _classIntrospector;
// 注解解析器,解决pojo上的注解功能
protected final AnnotationIntrospector _annotationIntrospector;
// 自定义序列化名称规则,作用是全局的
protected final PropertyNamingStrategy _propertyNamingStrategy;
// 提供工具类,将JVM的类型和非虚拟机的类型统一。
// 例如:List<String> 的形式
protected final TypeFactory _typeFactory;
// 提供时间格式化工具
protected final DateFormat _dateFormat;
// 提供工具类的构造入口,方便每三方切入
// @see SpringHandlerInstantiator
protected final HandlerInstantiator _handlerInstantiator;
// 地区
protected final Locale _locale;
// 时区
protected final TimeZone _timeZone;
// base64加解码工具
protected final Base64Variant _defaultBase64;
}
public abstract class MapperConfig{
// 针对对象属性是否序列化用户的配置
// @see JsonInclude
protected final static JsonInclude.Value EMPTY_INCLUDE = JsonInclude.Value.empty();
// 针对对象属性序列化格式的用户配置
// @see JsonFormat
protected final static JsonFormat.Value EMPTY_FORMAT = JsonFormat.Value.empty();
// MapperFeature配置的存储
protected final int _mapperFeatures;
// 提供一些容器工具类
protected final BaseSettings _base;
}
MapperConfigBase
主要关系视图,格式,多态等大体的配置
public abstract class MapperConfigBase{
// 影响配置的注解声明
protected final static ConfigOverride EMPTY_OVERRIDE = ConfigOverride.empty();
// 枚举的映射配置
private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);
// 默认的映射配置
private final static int AUTO_DETECT_MASK =
MapperFeature.AUTO_DETECT_FIELDS.getMask()
| MapperFeature.AUTO_DETECT_GETTERS.getMask()
| MapperFeature.AUTO_DETECT_IS_GETTERS.getMask()
| MapperFeature.AUTO_DETECT_SETTERS.getMask()
| MapperFeature.AUTO_DETECT_CREATORS.getMask()
;
// 对MixInResolver的简单实现
// @see MixInResolver
protected final SimpleMixInResolver _mixIns;
// 交类型查找器
protected final SubtypeResolver _subtypeResolver;
// 序列化 json 的根名
// 例: {_rootName:{...}}
// @jsonRootName
protected final PropertyName _rootName;
// 设置此对应视图
// @JsonView
protected final Class<?> _view;
// 用于属性权限控制
protected final ContextAttributes _attributes;
// 如果 rootName 不存在,则用此类查找
protected final RootNameLookup _rootNames;
// 注解的配置
// @EMPTY_OVERRIDE
protected final ConfigOverrides _configOverrides;
}
SerializationConfig
序列化时,独有的配置。反序列化并不会使用到
public enum SerializationFeature{
// 是否开启rootName功能
// @see MapperConfigBase##_rootName
WRAP_ROOT_VALUE(false),
// 开启如果PrettyPrinter不存在,是否用_handlerInstantiator创建
// @see BaseSettings##_handlerInstantiator
INDENT_OUTPUT(false),
// 是如是空对象,序列化时报错
FAIL_ON_EMPTY_BEANS(true),
// 序列化时,对象内的属性是本对象,则报错
FAIL_ON_SELF_REFERENCES(true),
// 是否包装成JsonMappingException异常,扔出
WRAP_EXCEPTIONS(true),
// 是否支持扁平化序列化
// @JsonUnwrapped
FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS(true),
// 如果序列化的对象支持CLOSEABLE, 是否自动关闭
CLOSE_CLOSEABLE(false),
// 序列化时,写value后直接提交
FLUSH_AFTER_WRITE_VALUE(true),
// 序列化时,将data类型包装用TIMESTAMPS,以数值形势输出
WRITE_DATES_AS_TIMESTAMPS(true),
WRITE_DATE_KEYS_AS_TIMESTAMPS(false),
WRITE_DATES_WITH_ZONE_ID(false),
WRITE_DURATIONS_AS_TIMESTAMPS(true),
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS(true),
// char[] 序列化时,以字符串string形式输出
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false),
// 枚举 序列化时,以toString方式输出
// 默认是 name()
WRITE_ENUMS_USING_TO_STRING(false),
// 枚举 序列化时,以数值方式输出
WRITE_ENUMS_USING_INDEX(false),
// 对单个 array对象是不平铺输出
// false: { "arrayProperty" : [ 1 ] }
// true: { "arrayProperty" : 1 }
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED(false),
// 序列化时,Map按key字典顺序输出
ORDER_MAP_ENTRIES_BY_KEYS(false),
// 配置优化(让许多配置不生效),一帮情况都开着,除非有性能问题
EAGER_SERIALIZER_FETCH(true),
// map中key相同判断使用 equel
// 默认: ==
// @see IdentityHashMap
USE_EQUALITY_FOR_OBJECT_ID(false)
;
}
public final class SerializationConfig{
// 属性过滤器
protected final FilterProvider _filterProvider;
// 格式化输出
// @see DefaultPrettyPrinter
protected final PrettyPrinter _defaultPrettyPrinter;
// 序列化实体绑定配置
// @see SerializationFeature
protected final int _serFeatures;
// json生成配置
// @see JsonGenerator.Feature
protected final int _generatorFeatures;
// 现在配置和默认配置的差异
// @see _generatorFeatures
protected final int _generatorFeaturesToChange;
// 序列化格式策略
@see FormatFeature
protected final int _formatWriteFeatures;
// 现在配置和默认配置的差异
// @see _formatWriteFeatures
protected final int _formatWriteFeaturesToChange;
}
对象反序列化过程
以JsonParser##readValueAs 函数为入口。最终调用ObjectMapper##readValue
// ObjectMapper##readValue 省略了部份代码
public <T> T readValue(JsonParser p, Class<T> valueType) {
// 1.获取反序列化配置
// 2.根据给点的参数确定反序化后的类型
// 3.调用ObjectMapper##_readValue真正解析
return (T) _readValue(getDeserializationConfig(), p, _typeFactory.constructType(valueType));
}
// ObjectMapper##_readValue 省略了部份代码
protected Object _readValue(DeserializationConfig cfg, JsonParser p,
JavaType valueType) {
// 根据反序列化配置创建反序死上下文
final DeserializationContext ctxt = createDeserializationContext(p, cfg);
// 根据反序列化类型找到对应的JsonDeserializer
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType);
// 由JsonDeserializer开始正常反序列化
Object result = deser.deserialize(p, ctxt);
return result;
}
针对DeserializationConfig进行以下分析
DeserializationConfig
反序列化时,独有的配置。序列化并不会使用到
public enum DeserializationFeature {
// float的适配decimal
USE_BIG_DECIMAL_FOR_FLOATS(false),
// int的适配bigInteger
USE_BIG_INTEGER_FOR_INTS(false),
// int的适配LONG
USE_LONG_FOR_INTS(false),
// 使用 Obeject[] 解析 json的 []
// 默认是 List
USE_JAVA_ARRAY_FOR_JSON_ARRAY(false),
// 发现json中字段,没有对应的setter时报错
FAIL_ON_UNKNOWN_PROPERTIES(true),
// java 基本类型,如果在json中是null时报错
FAIL_ON_NULL_FOR_PRIMITIVES(false),
// 当json中数值属应对应实体中是枚举报错
FAIL_ON_NUMBERS_FOR_ENUMS(false),
// 反序列化时的类型错误
// @see JsonTypeInfo
FAIL_ON_INVALID_SUBTYPE(true),
// 当json中存在相同的key报错
FAIL_ON_READING_DUP_TREE_KEY(false),
// 发现json中,存在设置忽略的属性,如果有。则报错
FAIL_ON_IGNORED_PROPERTIES(false),
// 反序列化时,ID生成策略失败则报错
FAIL_ON_UNRESOLVED_OBJECT_IDS(true),
// 实体对象中属性在json中找不到,则报错
FAIL_ON_MISSING_CREATOR_PROPERTIES(false),
// 实体对象中属性在json中为空,则报错
FAIL_ON_NULL_CREATOR_PROPERTIES(false),
// 反序列化时,找不到EXTERNAL_TYPE对应的属性序列化报错
FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY(true),
// json 已结束,后面还有字符则报错
FAIL_ON_TRAILING_TOKENS(false),
// 把反序列化时的异常封装,不封装Error,catch异常之后,抛出IOException。默认封装异常。
WRAP_EXCEPTIONS(true),
// json 中是单个值对应实体类是数组, 是否强制转换
ACCEPT_SINGLE_VALUE_AS_ARRAY(false),
// 不支持json中发现单值的数组
UNWRAP_SINGLE_VALUE_ARRAYS(false),
// 不支持 rootName方式的json
// @see SerializationFeature#WRAP_ROOT_VALUE
UNWRAP_ROOT_VALUE(false),
// 空字符对应实体的null
ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(false),
// 空数组对应实体的null
ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT(false),
// 支持用int接收float
ACCEPT_FLOAT_AS_INT(true),
// 支持用string方式转换枚举
READ_ENUMS_USING_TO_STRING(false),
// 末识别的枚举设置为null
READ_UNKNOWN_ENUM_VALUES_AS_NULL(false),
// 末识别的枚举使用默认值
READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE(false),
// 时间cuo精确到秒
READ_DATE_TIMESTAMPS_AS_NANOSECONDS(true),
// 时间适配系统的时区
ADJUST_DATES_TO_CONTEXT_TIME_ZONE(true),
// 配置优化(让许多配置不生效),一帮情况都开着,除非有性能问题
EAGER_DESERIALIZER_FETCH(true);
}
public final class DeserializationConfig{
// 反序列化,问题监听器
protected final LinkedNode<DeserializationProblemHandler> _problemHandlers;
// 树形结构对象工厂类
protected final JsonNodeFactory _nodeFactory;
// 反序列化对象绑定配置
// @see DeserializationFeature
protected final int _deserFeatures;
// 反序化json解析配置
// @see JsonParser#Feature
protected final int _parserFeatures;
// 反序化json解析配置与默认值差异
// @see _parserFeatures
protected final int _parserFeaturesToChange;
// 反序列化json解析格式配置
protected final int _formatReadFeatures;
// 反序列化json解析格式配置与默认差异
// @see _formatReadFeatures
protected final int _formatReadFeaturesToChange;
}
总结
Jackson目前有3个核心模块:
- Streaming流处理模块(jackson-core):定义底层处理流的API:JsonPaser和JsonGenerator等,并包含特定于json的实现。
- Annotations标准注解模块(jackson-annotations):包含标准的Jackson注解
- Databind数据绑定模块(jackson-databind):在streaming包上实现数据绑定(和对象序列化)支持;它依赖于上面的两个模块,也是Jackson的高层API(如ObjectMapper)所在的模块
另要具备以下的基础知识:
- 字符编码《字符编码》
- 如果获取反射的类型《Java获得泛型类型》
主要参考
《懂了这些,方敢在简历上说会用Jackson写JSON》
《JSON字符串是如何被解析的?JsonParser了解一下》
《Jackson原来是这样写JSON的》
《Java Jackson @JsonTypeInfo 多态类型处理》
《Jackson 框架的高阶应用》