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