JackSon概述

前言

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配置和构建。这个工厂实例是线程安全的。其主要功能如图:
在这里插入图片描述
主要设计思想

  1. 流式(Streaming):此概念和Java8中的Stream流是不同的。这里指的是IO流,因此具有最低的开销和最快的读/写操作(记得关流哦)
  2. 增量模式(incremental
    mode):它表示每个部分一个一个地往上增加,类似于垒砖。使用此流式API读写JSON的方式使用的均是增量模式
  3. 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)所在的模块

另要具备以下的基础知识:

主要参考

懂了这些,方敢在简历上说会用Jackson写JSON
JSON字符串是如何被解析的?JsonParser了解一下
Jackson原来是这样写JSON的
Java Jackson @JsonTypeInfo 多态类型处理
Jackson 框架的高阶应用

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值