詳情參閱:Jackson系列
注:下文涉及到的 jackson 源碼的版本為 2.11.0
1 Jackson介紹
(對應 Jackson系列 文章1)
Jackson是一個基於JVM平台(所以支持Java、Scala、Kotlin等語言)的數據(不限於JSON格式的數據)序列化、反序列化工具集,包括:JSON解析器(讀)/ JSON生成器(寫)、數據綁定庫(POJOs to and from JSON);並且提供了相關模塊來支持 Avro、BSON、CBOR、CSV、Smile、Properties、Protobuf、XML、YAML等數據格式,甚至還支持大數據格式模塊的設置。
特性
性能且穩定:低內存占用,對大/小JSON串解析、大/小對象的序列化表現均很優秀。
流行度高:是很多流行框架的默認選擇。
易使用:提供高層次的API,極大簡化了日常使用的難度。
無需自己手動創建映射:內置了絕大部分序列化時和Java類型的映射關系。
干凈的JSON:創建的JSON具有干凈、緊湊、體積小等特點。
無三方依賴:僅依賴於JDK。
可擴展性強:與GSON等其他庫相比的另一大特點是具有很強的可擴展性。
Spring生態加持:jackson是Spring家族的默認JSON/XML解析器。
其他:考慮安全性,預防JSON解析時的Dos攻擊(ByteQuadsCanonicalizer)等。
模塊
三個核心模塊:(說明:核心模塊的groupId均為:<groupId>com.fasterxml.jackson.core</groupId>,artifactId見下面各模塊所示)
json解析和生成的核心模塊(jackson-core):主要包括JsonParser、JsonGenerator、JsonFactory三個內容,分別用於解析JSON數據、生成JSON數據、配置和構建JsonParser與JsonGenerator。此模塊是jackson其他所有模塊的基礎,屬於low-level API。jackson-core 模塊提供了兩種處理JSON的方式(縱纜整個Jackson共三種):
數據流式API:讀取並將JSON內容寫入作為離散事件 -> JsonParser讀取數據,而JsonGenerator負責寫入數據。
樹模型:JSON文件在內存里以樹形式表示。此種方式也很靈活,它類似於XML的DOM解析,是層層嵌套的。這種模式下無需定義POJO就可以用它快速讀寫JSON數據,同時它也可以達到「模糊掉類型的概念」,做到更抽象和更公用。
Annotations標准注解模塊(jackson-annotations):包含標准的Jackson注解。
Databind數據綁定模塊(jackson-databind):在streaming包上實現數據綁定(和對象序列化)支持,它依賴於上面的兩個模塊,也是Jackson的high-level API(如ObjectMapper)所在的模塊。
實際應用級開發中,我們只會使用到Databind數據綁定模塊。
數據類型模塊:這些模塊為Jackson插件模塊(通過ObjectMapper.registerModule()注冊),並通過添加序列化器和反序列化器來支持各種常用的Java庫數據類型,以便Jackson databind包(ObjectMapper / ObjectReader / ObjectWriter)能夠順利讀寫/轉換這些類型。包括官方維護和非官方維護兩類。
官方維護:Guava、HPPC、PCollections、Hibernate、Joda、Java8、JSR310、JSR353 等(groupId統一為:<groupId>com.fasterxml.jackson.datatype</groupId>,且版本號和主版本號保持一致)。
第三方開源維護:jackson-datatype-bolts、jackson-datatype-commons-lang3 等。
數據格式模塊:Data format modules(數據格式模塊)提供對JSON之外的數據格式的支持。它們中的大多數只是實現streaming API抽象,以便數據綁定組件可以按原樣使用。兩類(groupId統一為<groupId>com.fasterxml.jackson.dataformat</groupId>,且版本號和主版本號保持一致):
Avro/CBOR/Ion/Protobuf/Smile(binary JSON) :這些均屬於二進制的數據格式,它們的artifactId為:<artifactId>jackson-dataformat-[FORMAT]</artifactId>
CSV/Properties/XML/YAML
JVM平台其他語言支持:Jackson是一個JVM平台的解析器,因此語言層面不局限於Java本身,還涵蓋了另外兩大主流JVM語言:Kotlin和Scala。兩類(groupId均為:<groupId>com.fasterxml.jackson.module</groupId>,版本號跟着主版本號走):
jackson-module-kotlin:處理kotlin源生類型
jackson-module-scala_[scala版本號]:處理scala源生類型
移動端簡化版(Jackson jr):Jackson databind(如ObjectMapper)是通用數據綁定的良好選擇,但它占用空間(Jar包大小)和啟動開銷在移動端等常見下較為笨重,故官方推出了更簡單、更小的庫——Jackson jr。它仍舊構建在Streaming API之上,但不依賴於databind和annotation。因此,它的大小(jar和運行時內存使用)要小得多,它的API非常緊湊,所以適合APP等移動端
2 Java數據轉成JSON數據(jackson-core之 JsonGenerator)
(對應 Jackson系列 文章2)
JsonGenerator是jackson-core提供的JSON數據生成器,用於將Java數據對象轉成JSON數據。
在應用開發層面一般不推薦直接使用JsonGenerator(而是用ObjectMapper),因為它的API比較底層比較靈活,因此易錯;但如果是框架開發,則很適合用這個(Spring MVC對JSON消息的轉換器 AbstractJackson2HttpMessageConverter 就用到了Jackson底層流式API -> JsonGenerator寫數據),因為它的性能更高,是ObjectMapper等的基礎。
如上圖所示,最終負責生成JSON數據的實現類有 WriterBasedJsonGenerator、UTF8JsonGenerator 兩種。
WriterBasedJsonGenerator:基於 java.io.Writer 來輸出JSON內容,由該Writer來處理字符編碼。
UTF8JsonGenerator:該實現類自己對Java數據進行UTF8字符編碼,編碼后的JSON數據內容直接輸出到OutputStream而不是借助Writer輸出。
基本使用:
寫key:JSON中的key只有String一種類型
寫value:Java中的數據類型多種多樣,但JSON中只有 【字符串、數值、布爾、null、數組、對象 】6種。
關於JsonGenerator中寫key、寫value的各種API使用示例可參閱本節首的文章。
writeFieldName
writeString、writeNumber、writeBoolean、writeNull、writeStartArray/writeArray、writeStartObject/writeObject
writeRaw、writeRawValue、writeBinary
等
JsonGenerator的 writeObject/writeTree 方法要求事先給JsonGenerator指定一個編解碼器 ObjectCodec/TreeCodec,否則會報錯。而Jackson里我們最為熟悉的API ObjectMapper 實際上就是一個ObjectCodec 的唯一實現,實現了序列化和反序列化、POJO、Tree Model 等操作。
(對應 Jackson系列 文章3)
JsonGenerator#Feature 枚舉類:

public enum Feature { // Low-level I/O AUTO_CLOSE_TARGET(true), AUTO_CLOSE_JSON_CONTENT(true), FLUSH_PASSED_TO_STREAM(true), // Quoting-related features @Deprecated QUOTE_FIELD_NAMES(true), @Deprecated QUOTE_NON_NUMERIC_NUMBERS(true), @Deprecated ESCAPE_NON_ASCII(false), @Deprecated WRITE_NUMBERS_AS_STRINGS(false), // Schema/Validity support features WRITE_BIGDECIMAL_AS_PLAIN(false), STRICT_DUPLICATE_DETECTION(false), IGNORE_UNKNOWN(false); ... }
StreamWriterFeature:
2.10版本新增的,用於完全替換上面的Feature,被JsonFactory所使用。目的:完全獨立的屬性配置,不依賴於任何后端格式,因為JsonGenerator並不局限於寫JSON,因此把Feature放在JsonGenerator作為內部類是不太合適的,所以單獨摘出來。
3 JSON數據轉成Java數據(jackson-core之 JsonParser)
(對應 Jackson系列 文章4)
關於JsonParser的基本使用及配置可參閱該文章。
如上圖所示,最終負責解析JSON數據的實現類有 ReaderBasedJsonParser、UTF8StreamJsonParser、UTF8SDataInputJsonParser、NonBlockingJsonParser 幾種。其中前兩種最常用,這兩種Parser的區別與前述Generator的兩種實現的區別類似。
JSON數據解析(反序列化)的配置項:
JsonParser#Feature 枚舉類:

public enum Feature { AUTO_CLOSE_SOURCE(true), ALLOW_COMMENTS(false), ALLOW_YAML_COMMENTS(false), ALLOW_UNQUOTED_FIELD_NAMES(false), ALLOW_SINGLE_QUOTES(false), @Deprecated ALLOW_UNQUOTED_CONTROL_CHARS(false), @Deprecated ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER(false), @Deprecated ALLOW_NUMERIC_LEADING_ZEROS(false), @Deprecated ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS(false), @Deprecated ALLOW_NON_NUMERIC_NUMBERS(false), @Deprecated ALLOW_MISSING_VALUES(false), @Deprecated ALLOW_TRAILING_COMMA(false), STRICT_DUPLICATE_DETECTION(false), IGNORE_UNDEFINED(false), INCLUDE_SOURCE_IN_LOCATION(true); }
比較值得一提的是 ALLOW_COMMENTS、ALLOW_YAML_COMMENTS ,開啟后將允許待解析的JSON數據里帶有注釋,包括 //good /* good */ # good 三種格式的注釋。
4 創建JsonParser、JsonGenerator (jackson-core之JsonFactory)
(對應 Jackson系列 文章5)
JsonFactory是Jackson的(最)主要工廠類,用於 配置和構建 JsonGenerator、JsonParser,可見其雖作為工廠類但職責並不單一。該這個工廠實例是「線程安全」的,因此可以重復使用。
基本API:
JsonFactory創建JsonParser、JsonGenerator實例的相關API:
編碼自動檢測:
從前面關於JsonParser、JsonGenerator的介紹可知兩者分別用於反序列化、序列化,因此都涉及到編碼問題。對於JsonParser,在解析輸入的文本內容時如何知道內容的編碼方式呢?這得益於jackson的編碼自動檢測機制:JsonFactory在創建JsonParser時會調用 ByteSourceJsonBootstrapper#constructParser -> detectEncoding 方法來檢測輸入內容的編碼。相關源碼:

public JsonParser constructParser(int parserFeatures, ObjectCodec codec, ByteQuadsCanonicalizer rootByteSymbols, CharsToNameCanonicalizer rootCharSymbols, int factoryFeatures) throws IOException { JsonEncoding enc = detectEncoding(); if (enc == JsonEncoding.UTF8) { /* and without canonicalization, byte-based approach is not performant; just use std UTF-8 reader * (which is ok for larger input; not so hot for smaller; but this is not a common case) */ if (JsonFactory.Feature.CANONICALIZE_FIELD_NAMES.enabledIn(factoryFeatures)) { ByteQuadsCanonicalizer can = rootByteSymbols.makeChild(factoryFeatures); return new UTF8StreamJsonParser(_context, parserFeatures, _in, codec, can, _inputBuffer, _inputPtr, _inputEnd, _bufferRecyclable); } } return new ReaderBasedJsonParser(_context, parserFeatures, constructReader(), codec, rootCharSymbols.makeChild(factoryFeatures)); }
JsonFactory的配置項:

/** * Enumeration that defines all on/off features that can only be * changed for {@link JsonFactory}. */ public enum Feature { // // // Symbol handling (interning etc) /** * Feature that determines whether JSON object field names are * to be canonicalized using {@link String#intern} or not: * if enabled, all field names will be intern()ed (and caller * can count on this being true for all such names); if disabled, * no intern()ing is done. There may still be basic * canonicalization (that is, same String will be used to represent * all identical object property names for a single document). *<p> * Note: this setting only has effect if * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no * canonicalization of any sort is done. *<p> * This setting is enabled by default. */ INTERN_FIELD_NAMES(true), /** * Feature that determines whether JSON object field names are * to be canonicalized (details of how canonicalization is done * then further specified by * {@link #INTERN_FIELD_NAMES}). *<p> * This setting is enabled by default. */ CANONICALIZE_FIELD_NAMES(true), /** * Feature that determines what happens if we encounter a case in symbol * handling where number of hash collisions exceeds a safety threshold * -- which almost certainly means a denial-of-service attack via generated * duplicate hash codes. * If feature is enabled, an {@link IllegalStateException} is * thrown to indicate the suspected denial-of-service attack; if disabled, processing continues but * canonicalization (and thereby <code>intern()</code>ing) is disabled) as protective * measure. *<p> * This setting is enabled by default. * * @since 2.4 */ FAIL_ON_SYMBOL_HASH_OVERFLOW(true), /** * Feature that determines whether we will use {@link BufferRecycler} with * {@link ThreadLocal} and {@link SoftReference}, for efficient reuse of * underlying input/output buffers. * This usually makes sense on normal J2SE/J2EE server-side processing; * but may not make sense on platforms where {@link SoftReference} handling * is broken (like Android), or if there are retention issues due to * {@link ThreadLocal} (see * <a href="https://github.com/FasterXML/jackson-core/issues/189">Issue #189</a> * for a possible case) *<p> * This setting is enabled by default. * * @since 2.6 */ USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING(true) ; /** * Whether feature is enabled or disabled by default. */ private final boolean _defaultState; /** * Method that calculates bit set (flags) of all features that * are enabled by default. */ public static int collectDefaults() { int flags = 0; for (Feature f : values()) { if (f.enabledByDefault()) { flags |= f.getMask(); } } return flags; } private Feature(boolean defaultState) { _defaultState = defaultState; } public boolean enabledByDefault() { return _defaultState; } public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } public int getMask() { return (1 << ordinal()); } }
JsonFactory的實例的創建共有三種方式:
直接new實例,此方式比較常用。
使用JsonFactoryBuilder構建(需要2.10或以上版本),這是推薦的使用方式。
SPI方式創建實例,此方式很少使用。
5 高層API之ObjectMapper
(對應 Jackson系列 文章6)
前面介紹的 jackson-core 模塊的 JsonParser、JsonGenerator、JsonFactory 都是底層API,雖然很靈活,但對用戶來說使用較為繁瑣。因此Jackson提供了更高層的API,即jackson-databind模塊。
jackson-databind 是Jackson提供的高層API,包含用於Jackson數據處理器的通用 「數據綁定功能」和「樹模型」。它構建在 jackson-core 模塊的API之上,並使用 jackson-annotations 進行配置。它是開發者使用得最多的方式,重要程度可見一斑。
雖然Jackson最初的用例是JSON數據綁定,但現在它也可以用於其它數據格式,只要提供 數據的解析器和生成器 的實現即可。但需要注意的是:類的命名在很多地方仍舊使用了“JSON”這個詞(比如JsonGenerator),盡管它與JSON格式沒有實際的硬依賴關系。
基本介紹
ObjectMapper 是jackson-databind模塊最為重要的一個類,它完成了coder對數據綁定的「幾乎所有功能」。主要功能如下:
- 提供解析和生成JSON的功能(最重要的功能)
- 普通POJO的序列化/反序列化
- JSON樹模型的讀/寫
- 可以被「高度定制」,以使用不同風格的JSON內容
- 使用Feature進行定制
- 使用可插拔
com.fasterxml.jackson.databind.Module
模塊來擴展/豐富功能 - 支持「更高級」的對象概念:比如多態泛型、對象標識
- 充當更為高級(更強大)的API:ObjectReader和ObjectWriter的「工廠」
ObjectReader
和ObjectWriter
底層亦是依賴於jackson-core的API實現讀寫- 支持豐富的數據格式,而不是局限於JSON格式。如自 2.10 版本起,提供了JsonMapper、YAMLMapper 子類,分別用於處理json數據、yaml 格式的數據(需額外導包)。
盡管絕大部分的讀/寫API都通過ObjectMapper暴露出去了,但有些功能還是只放在了ObjectReader/ObjectWriter里,比如對於讀/寫 「長序列」 的能力你只能通過ObjectReader#readValues(InputStream) / ObjectWriter#writeValues(OutputStream)去處理。
基本使用
詳情參閱本大節首的參考文章。
生成JSON數據(序列化)
主要API:
用的最多的是 writeValueAsString(obj) 方法
代碼示例及執行結果:

// 代碼 ObjectMapper objectMapper = new ObjectMapper(); System.out.println("----------寫簡單類型----------"); System.out.println(objectMapper.writeValueAsString(18)); System.out.println(objectMapper.writeValueAsString("YourBatman")); System.out.println("----------寫集合類型----------"); System.out.println(objectMapper.writeValueAsString(Arrays.asList(1, 2, 3))); System.out.println(objectMapper.writeValueAsString(new HashMap<String, String>() {{ put("zhName", "A哥"); put("enName", "YourBatman"); }})); System.out.println("----------寫POJO----------"); System.out.println(objectMapper.writeValueAsString(new Person("A哥", 18))); // 執行結果 18 "YourBatman" ----------寫集合類型---------- [1,2,3] {"zhName":"A哥","enName":"YourBatman"} ----------寫POJO---------- {"name":"A哥","age":18}
解析JSON數據(反序列化)
主要API:
用得最多的是 readValue(String content, Class<T> valueType) 方法
代碼示例及執行結果:

1 // 代碼 2 ObjectMapper objectMapper = new ObjectMapper(); 3 4 System.out.println("----------讀簡單類型----------"); 5 System.out.println(objectMapper.readValue("18", Integer.class)); 6 // 拋錯:JsonParseException 單獨的一個串,解析會拋錯 7 // System.out.println(objectMapper.readValue("YourBatman", String.class)); 8 9 System.out.println("----------讀集合類型----------"); 10 System.out.println(objectMapper.readValue("[1,2,3]", List.class)); 11 System.out.println(objectMapper.readValue("{\"zhName\":\"A哥\",\"enName\":\"YourBatman\"}", Map.class)); 12 13 System.out.println("----------讀POJO----------"); 14 System.out.println(objectMapper.readValue("{\"name\":\"A哥\",\"age\":18}", Person.class)); 15 16 17 18 System.out.println("----------讀集合類型 泛型問題----------"); 19 List<Long> ids = objectMapper.readValue("[1,2,3]", new TypeReference<List<Long>>() { 20 }); 21 Long id = ids.get(0); 22 System.out.println(id); 23 24 List<Long> list = objectMapper.readValue("[1,2,3]", List.class); 25 //Long id = list.get(0);// 因泛型擦除問題,會報類型轉換錯誤ClassCastException 26 27 28 29 // 執行結果 30 ----------讀簡單類型---------- 31 18 32 ----------讀集合類型---------- 33 [1, 2, 3] 34 {zhName=A哥, enName=YourBatman} 35 ----------讀POJO---------- 36 Person(name=A哥, age=18) 37 ----------讀集合類型 泛型問題---------- 38 1
需要特別注意泛型擦除問題:「若反序列化成為一個集合類型(Collection or Map),泛型會被擦除」,此時你應該使用readValue(String content, TypeReference<T> valueTypeRef)方法代替。詳情可參閱本大節首的參考文章。
6 TreeModel
(對應 Jackson系列 文章7)
雖然ObjectMapper在數據綁定上既可以處理簡單類型(如Integer、List、Map等),也能處理完全類型(如POJO),看似無所不能。但是,若有如下場景它依舊「不太好實現」:
碩大的JSON串中我只想要「某一個」(某幾個)屬性的值而已
臨時使用,我並不想創建一個POJO與之對應,只想直接使用「值」即可(類型轉換什么的我自己來就好)
數據結構高度「動態化」
TreeModel
為了解決這些問題,Jackson提供了強大的「樹模型」 API供以使用。樹模型雖然是jackson-core模塊里定義的,但是是由jackson-databind模塊實現的。
樹模型是JSON數據內存樹的表示形式,這是最靈活的表示,可以動態增減、從任意節點進行遍歷。。Jackson提供了樹模型API來「生成和解析」 JSON串,主要用到如下三個核心類:
JsonNode
:表示json節點,類似XML的DOM樹節點。可以往里面塞值,從而最終構造出一顆json樹。
JsonNodeFactory
:用來構造各種JsonNode節點的工廠。例如對象節點ObjectNode、數組節點ArrayNode等。
ObjectMapper
:實現JsonNode和JSON字符串的互轉。
代碼示例及執行結果:

1 // 代碼 2 JsonNodeFactory factory = JsonNodeFactory.instance; 3 4 System.out.println("------ValueNode值節點示例------"); 5 // 數字節點 6 JsonNode node = factory.numberNode(1); 7 System.out.println(node.isNumber() + ":" + node.intValue()); 8 9 // null節點 10 node = factory.nullNode(); 11 System.out.println(node.isNull() + ":" + node.asText()); 12 13 // missing節點 14 node = factory.missingNode(); 15 System.out.println(node.isMissingNode() + "_" + node.asText()); 16 17 // POJONode節點 18 node = factory.pojoNode(new Person("YourBatman", 18)); 19 System.out.println(node.isPojo() + ":" + node.asText()); 20 21 System.out.println("---" + node.isValueNode() + "---"); 22 23 24 System.out.println("------構建一個JSON結構數據------"); 25 ObjectNode rootNode = factory.objectNode(); 26 27 // 添加普通值節點 28 rootNode.put("zhName", "A哥"); // 效果完全同:rootNode.set("zhName", factory.textNode("A哥")) 29 rootNode.put("enName", "YourBatman"); 30 rootNode.put("age", 18); 31 32 // 添加數組容器節點 33 ArrayNode arrayNode = factory.arrayNode(); 34 arrayNode.add("java") 35 .add("javascript") 36 .add("python"); 37 rootNode.set("languages", arrayNode); 38 39 // 添加對象節點 40 ObjectNode dogNode = factory.objectNode(); 41 dogNode.put("name", "大黃") 42 .put("age", 3); 43 rootNode.set("dog", dogNode); 44 45 System.out.println(rootNode); 46 System.out.println(rootNode.get("dog").get("name")); 47 48 49 50 // 結果 51 52 ------ValueNode值節點示例------ 53 true:1 54 true:null 55 true_ 56 true:Person(name=YourBatman, age=18) 57 ---true--- 58 59 ------構建一個JSON結構數據------ 60 {"zhName":"A哥","enName":"YourBatman","age":18,"languages":["java","javascript","python"],"dog":{"name":"大黃","age":3}} 61 "大黃"
TreeModel數據的序列化與反序列化
ObjectMapper中提供了TreeModel數據的序列化、反序列化的實現。
序列化
相關API:
示例代碼及執行結果:

1 // 示例1 2 public void test1() { 3 ObjectMapper mapper = new ObjectMapper(); 4 5 Person person = new Person(); 6 person.setName("YourBatman"); 7 person.setAge(18); 8 9 person.setDog(new Person.Dog("旺財", 3)); 10 11 JsonNode node = mapper.valueToTree(person); 12 13 System.out.println(person); 14 // 遍歷打印所有屬性 15 Iterator<JsonNode> it = node.iterator(); 16 while (it.hasNext()) { 17 JsonNode nextNode = it.next(); 18 if (nextNode.isContainerNode()) { 19 if (nextNode.isObject()) { 20 System.out.println("狗的屬性:::"); 21 22 System.out.println(nextNode.get("name")); 23 System.out.println(nextNode.get("age")); 24 } 25 } else { 26 System.out.println(nextNode.asText()); 27 } 28 } 29 30 // 直接獲取 31 System.out.println("---------------------------------------"); 32 System.out.println(node.get("dog").get("name")); 33 System.out.println(node.get("dog").get("age")); 34 } 35 36 //示例1 結果 37 Person(name=YourBatman, age=18, dog=Person.Dog(name=旺財, age=3)) 38 YourBatman 39 18 40 狗的屬性::: 41 "旺財" 42 3 43 --------------------------------------- 44 "旺財" 45 3 46 47 48 // 示例2 49 public void test2() throws IOException { 50 ObjectMapper mapper = new ObjectMapper(); 51 52 JsonFactory factory = new JsonFactory(); 53 try (JsonGenerator jsonGenerator = factory.createGenerator(System.err, JsonEncoding.UTF8)) { 54 55 // 1、得到一個jsonNode(為了方便我直接用上面API生成了哈) 56 Person person = new Person(); 57 person.setName("YourBatman"); 58 person.setAge(18); 59 JsonNode jsonNode = mapper.valueToTree(person); 60 61 // 使用JsonGenerator寫到輸出流 62 mapper.writeTree(jsonGenerator, jsonNode); 63 } 64 } 65 66 //示例2結果 67 {"name":"YourBatman","age":18,"dog":null}
反序列化
相關API:
代碼示例:

public void test4() throws IOException { ObjectMapper mapper = new ObjectMapper(); String jsonStr = "{\"name\":\"YourBatman\",\"age\":18,\"dog\":{\"name\":\"旺財\",\"color\":\"WHITE\"},\"hobbies\":[\"籃球\",\"football\"]}"; JsonNode node = mapper.readTree(jsonStr); System.out.println(node.get("dog").get("color").asText()); } public void test5() throws JsonProcessingException { String jsonStr = "{\"name\":\"YourBatman\",\"age\":18}"; JsonNode node = new ObjectMapper().readTree(jsonStr); System.out.println("-------------向結構里動態添加節點------------"); // 動態添加一個myDiy節點,並且該節點還是ObjectNode節點 ((ObjectNode) node).with("myDiy").put("contry", "China"); System.out.println(node); }
可見,在只需要取出一個大json串中的少數幾個字段時用 TreeModel API 比較方便。