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
參考: