JSON 解析 (二)—— Jackson的使用


Jackson是基於Java語言的一種JSON和Java對象的數據處理工具。功能上簡單易用,性能上根據目前主流轉換工具比較,Jackson相對比較高效。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.4</version>
</dependency>

Jackson包含三個jar:

       1、jackson-core

  2、jackson-annotations

  3、jackson-databind

從Maven倉庫中可知三者的依賴關系:1和2相互獨立,3依賴1和2

 

Jackson的JSON庫提供了3種API:

  • Data Binding:最方便,也是最常用方式                    依賴jackson-databind
  • Tree Model:最靈活                                                   依賴jackson-databind
  • Streaming API:性能最好                                          只依賴jackson-core

一、Data Binding

1、序列化

 可使用ObjectMapper.writeValueAsString(Object obj)方法

UserInfo userInfo1 = new UserInfo();
userInfo1.setName("matt");
userInfo1.setAge(21);

UserInfo userInfo2 = new UserInfo();
userInfo2.setName("kevin");
userInfo2.setAge(15);

List<UserInfo> list = new ArrayList<UserInfo>();
list.add(userInfo1);
list.add(userInfo2);

Staff staff = new Staff();
staff.setUsers(list);
staff.setCount(list.size());

ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(staff);
System.out.println(json);
// 輸出:{"count":2,"users":[{"name":"matt","age":21},{"name":"kevin","age":15}]}

 可使用注解,實現序列化的細節控制,如  
    @JsonIgnore  忽略屬性
 @JsonFormat  日期格式化
 @JsonProperty  屬性重命名

 

2、反序列化

 實體的反序列化

Staff tmpStaff =  new ObjectMapper().readValue(json, Staff.class);  // 實體可包含泛型字段

 泛型的反序列化

List<UserInfo> tmpList = new ObjectMapper().readValue(json, new TypeReference<List<UserInfo>>() {});

 方法參數的反序列化

public class Company {
    public void printUsers(List<UserInfo> users) {
        for (UserInfo userInfo : users) {
            System.out.println(String.format("name:%s, age:%d", userInfo.getName(), userInfo.getAge()));
        }
    } 
}
String json = "[{\"name\":\"matt\",\"age\":21},{\"name\":\"kevin\",\"age\":15}]";
Method method = Company.class.getDeclaredMethods()[0];
Type type = method.getGenericParameterTypes()[0];
method.invoke(new Company(), objectMapper.readValue(json, TypeFactory.defaultInstance().constructType(type)));
// 輸出:
// name:matt, age:21
// name:kevin, age:15

 注:使用Method.getGenericParameterTypes()返回Type,其中包含方法定義時參數的泛型信息,因而可正常反序列化

 

二、Tree Model

1、序列化

 JsonNodeFactory生成樹節點,ObjectMapper.writeTree()和JsonGenerator負責輸出json字符串

StringWriter sw = new StringWriter();
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator jsonGenerator = jsonFactory.createGenerator(sw);

JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(false);
ObjectNode node1 = jsonNodeFactory.objectNode();
node1.put("aa", 89);
node1.put("bb", "abd");
ObjectNode node2 = jsonNodeFactory.objectNode();
node2.put("gr", 9);
node2.set("subnode", node1);
new ObjectMapper().writeTree(jsonGenerator, node2);
System.out.println(sw.toString());
// 輸出:{"gr":9,"subnode":{"aa":89,"bb":"abd"}}

2、反序列化

 ObjectMapper.readValue() 可把json字符串解析成JsonNode

String json = "[{\"name\":\"matt\",\"age\":21},{\"name\":\"kevin\",\"age\":15}]";
JsonNode node = new ObjectMapper().readValue(json, JsonNode.class);
JsonNode subNode = node.get(0);
System.out.println(subNode.get("name").asText());

 

三、Streaming API

1、序列化

 JsonGenerator提供序列化接口

JsonFactory jsonFactory = new JsonFactory();
// JsonFactory jsonFactory = new ObjectMapper().getFactory();
JsonGenerator jsonGenerator = jsonFactory.createGenerator(System.out);

jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", "matt");
jsonGenerator.writeNumberField("age", 10);
// jsonGenerator.writeObjectField("user", new UserInfo());    // 會拋異常
jsonGenerator.writeEndObject();

jsonGenerator.flush();
jsonGenerator.close();
// 輸出: {"name":"matt","age":10}

  序列化實體對象時,會拋異常: java.lang.IllegalStateException: No ObjectCodec defined for the generator, can only serialize simple wrapper types

  解決該問題的方法:使用ObjectMapper.getFactory() 創建JsonFactory 對象

 2、反序列化

 JsonParser提供反序列化功能,其工作方式是:將JSON分成一個Token序列(如START_OBJECT、END_OBJECT、FIELD_NAME等),迭代Token序列進行解析

 JsonParser通過nextToken()獲取Token,getCurrentName()獲取當前Field Name,getText()或getValueAsString()等獲取Value

String json = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
JsonFactory jsonFactory = new JsonFactory();
JsonParser jsonParser = jsonFactory.createParser(json);
jsonParser.nextToken();
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
    String name = jsonParser.getCurrentName();
    jsonParser.nextToken();
    String value = jsonParser.getText();
    System.out.println(String.format("%s: %s", name, value));
}
// 輸出:
// brand: Mercedes
// doors: 5

 

參考:

JSON之Jackson(一)

JSON之Jackson(二)

Jackson基礎教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM