Jackson JSON Java 解析器 API 示例教程

Jackson JSON Java Parser是非常受欢迎的,也被用于春季框架中。 Java JSON Processing API不是非常用户友好,也不提供从Json到Java对象的自动转换功能,反之亦然。幸运的是,我们有一些替代的API,我们可以用来处理JSON。在上一篇文章中,我们了解了 Google Gson API并看到了如何易用。

杰克逊JSONJava分析器

Jackson JSON Parser Java API Example Tutorial, ObjectMapper, JSON to Java Object, Java Object to JSON To use Jackson JSON Java API in our project, we can add it to the project build path or if you are using maven, we can add below dependency.

1<dependency>
2    <groupId>com.fasterxml.jackson.core</groupId>
3    <artifactId>jackson-databind</artifactId>
4    <version>2.2.3</version>
5</dependency>

jackson-databind jar 取决于 jackson-corejackson-annotations 库,所以如果您直接添加它们来构建路径,请确保您添加所有三种,否则您将收到运行时错误。Jackson JSON Parser API 提供了转换 JSON 到 POJO 对象的简单方法,并支持从 JSON 数据轻松转换到地图。

杰克逊JSON例子

对于 JSON 到 POJO/Java 对象转换的例子,我们将采取一个复杂的例子,包含嵌入式对象和数组。我们将使用 JSON 对象中的数组、列表和地图进行转换。

 1{
 2  "id": 123,
 3  "name": "Pankaj",
 4  "permanent": true,
 5  "address": {
 6    "street": "Albany Dr",
 7    "city": "San Jose",
 8    "zipcode": 95129
 9  },
10  "phoneNumbers": [
11    123456,
12    987654
13  ],
14  "role": "Manager",
15  "cities": [
16    "Los Angeles",
17    "New York"
18  ],
19  "properties": {
20    "age": "29 years",
21    "salary": "1000 USD"
22  }
23}

以下是对应 json 数据的 java 类。

 1package com.journaldev.jackson.model;
 2
 3public class Address {
 4    
 5    private String street;
 6    private String city;
 7    private int zipcode;
 8    
 9    public String getStreet() {
10    	return street;
11    }
12    public void setStreet(String street) {
13    	this.street = street;
14    }
15    public String getCity() {
16    	return city;
17    }
18    public void setCity(String city) {
19    	this.city = city;
20    }
21    public int getZipcode() {
22    	return zipcode;
23    }
24    public void setZipcode(int zipcode) {
25    	this.zipcode = zipcode;
26    }
27    
28    @Override
29    public String toString(){
30    	return getStreet() + ", "+getCity()+", "+getZipcode();
31    }
32}

地址类对应于 root json 数据中的内部对象。

 1package com.journaldev.jackson.model;
 2
 3import java.util.Arrays;
 4import java.util.List;
 5import java.util.Map;
 6
 7public class Employee {
 8
 9    private int id;
10    private String name;
11    private boolean permanent;
12    private Address address;
13    private long[] phoneNumbers;
14    private String role;
15    private List<String> cities;
16    private Map<String, String> properties;
17    
18    public int getId() {
19    	return id;
20    }
21    public void setId(int id) {
22    	this.id = id;
23    }
24    public String getName() {
25    	return name;
26    }
27    public void setName(String name) {
28    	this.name = name;
29    }
30    public boolean isPermanent() {
31    	return permanent;
32    }
33    public void setPermanent(boolean permanent) {
34    	this.permanent = permanent;
35    }
36    public Address getAddress() {
37    	return address;
38    }
39    public void setAddress(Address address) {
40    	this.address = address;
41    }
42    public long[] getPhoneNumbers() {
43    	return phoneNumbers;
44    }
45    public void setPhoneNumbers(long[] phoneNumbers) {
46    	this.phoneNumbers = phoneNumbers;
47    }
48    public String getRole() {
49    	return role;
50    }
51    public void setRole(String role) {
52    	this.role = role;
53    }
54    
55    @Override
56    public String toString(){
57    	StringBuilder sb = new StringBuilder();
58    	sb.append("***** Employee Details *****\n");
59    	sb.append("ID="+getId()+"\n");
60    	sb.append("Name="+getName()+"\n");
61    	sb.append("Permanent="+isPermanent()+"\n");
62    	sb.append("Role="+getRole()+"\n");
63    	sb.append("Phone Numbers="+Arrays.toString(getPhoneNumbers())+"\n");
64    	sb.append("Address="+getAddress()+"\n");
65    	sb.append("Cities="+Arrays.toString(getCities().toArray())+"\n");
66    	sb.append("Properties="+getProperties()+"\n");
67    	sb.append("*****************************");
68    	
69    	return sb.toString();
70    }
71    public List<String> getCities() {
72    	return cities;
73    }
74    public void setCities(List<String> cities) {
75    	this.cities = cities;
76    }
77    public Map<String, String> getProperties() {
78    	return properties;
79    }
80    public void setProperties(Map<String, String> properties) {
81    	this.properties = properties;
82    }
83}

现在让我们看看如何使用杰克逊 JSON 分析器 API 将 JSON 转换为 java 对象。

 1package com.journaldev.jackson.json;
 2
 3import java.io.File;
 4import java.io.IOException;
 5import java.io.StringWriter;
 6import java.nio.file.Files;
 7import java.nio.file.Paths;
 8import java.util.ArrayList;
 9import java.util.HashMap;
10import java.util.Iterator;
11import java.util.List;
12import java.util.Map;
13
14import com.fasterxml.jackson.core.type.TypeReference;
15import com.fasterxml.jackson.databind.JsonNode;
16import com.fasterxml.jackson.databind.ObjectMapper;
17import com.fasterxml.jackson.databind.SerializationFeature;
18import com.fasterxml.jackson.databind.node.ObjectNode;
19import com.journaldev.jackson.model.Address;
20import com.journaldev.jackson.model.Employee;
21
22public class JacksonObjectMapperExample {
23
24    public static void main(String[] args) throws IOException {
25    	
26    	//read json file data to String
27    	byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
28    	
29    	//create ObjectMapper instance
30    	ObjectMapper objectMapper = new ObjectMapper();
31    	
32    	//convert json string to object
33    	Employee emp = objectMapper.readValue(jsonData, Employee.class);
34    	
35    	System.out.println("Employee Object\n"+emp);
36    	
37    	//convert Object to json string
38    	Employee emp1 = createEmployee();
39    	//configure Object mapper for pretty print
40    	objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
41    	
42    	//writing to console, can write to any output stream such as file
43    	StringWriter stringEmp = new StringWriter();
44    	objectMapper.writeValue(stringEmp, emp1);
45    	System.out.println("Employee JSON is\n"+stringEmp);
46    }
47    
48    public static Employee createEmployee() {
49
50    	Employee emp = new Employee();
51    	emp.setId(100);
52    	emp.setName("David");
53    	emp.setPermanent(false);
54    	emp.setPhoneNumbers(new long[] { 123456, 987654 });
55    	emp.setRole("Manager");
56
57    	Address add = new Address();
58    	add.setCity("Bangalore");
59    	add.setStreet("BTM 1st Stage");
60    	add.setZipcode(560100);
61    	emp.setAddress(add);
62
63    	List<String> cities = new ArrayList<String>();
64    	cities.add("Los Angeles");
65    	cities.add("New York");
66    	emp.setCities(cities);
67
68    	Map<String, String> props = new HashMap<String, String>();
69    	props.put("salary", "1000 Rs");
70    	props.put("age", "28 years");
71    	emp.setProperties(props);
72
73    	return emp;
74    }
75
76}

当我们在程序上运行时,你会得到以下的输出。

 1Employee Object
 2***** Employee Details *****
 3ID=123
 4Name=Pankaj
 5Permanent=true
 6Role=Manager
 7Phone Numbers=[123456, 987654]
 8Address=Albany Dr, San Jose, 95129
 9Cities=[Los Angeles, New York]
10Properties={age=29 years, salary=1000 USD}
11*****************************
12Employee JSON is
13//printing same as above json file data

com.fasterxml.jackson.databind.ObjectMapper是杰克逊API中提供 readValue() 和 writeValue() 方法的最重要的类,可以将 JSON 转换为 Java ObjectJava Object 转换为 JSONObjectMapper 类可以重复使用,我们可以将其作为 Singleton 对象进行初始化。

杰克逊 JSON - 将 JSON 转换为地图

有时我们在 data.txt 文件中有一个 JSON 对象,如下:

1{
2  "name": "David",
3  "role": "Manager",
4  "city": "Los Angeles"
5}

我们想要将其转换为地图,而不是用相同的属性和密钥的Java对象,我们可以很容易地在Jackson JSON API中使用以下两种方法进行:

 1//converting json to Map
 2byte[] mapData = Files.readAllBytes(Paths.get("data.txt"));
 3Map<String,String> myMap = new HashMap<String, String>();
 4
 5ObjectMapper objectMapper = new ObjectMapper();
 6myMap = objectMapper.readValue(mapData, HashMap.class);
 7System.out.println("Map is: "+myMap);
 8
 9//another way
10myMap = objectMapper.readValue(mapData, new TypeReference<HashMap<String,String>>() {});
11System.out.println("Map using TypeReference: "+myMap);

一旦我们执行上方的片段,我们得到以下输出:

1Map is: {name=David, role=Manager, city=Los Angeles}
2Map using TypeReference: {name=David, role=Manager, city=Los Angeles}

杰克逊JSON - 阅读特定的JSON密钥

有时我们有 json 数据,我们只对几个密钥值感兴趣,所以在这种情况下将整个 JSON 转换为对象并不是一个好主意。Jackson JSON API 提供了阅读 json 数据的选项,如 DOM Parser,我们可以通过此阅读 JSON 对象的特定元素。

 1//read json file data to String
 2byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
 3
 4//create ObjectMapper instance
 5ObjectMapper objectMapper = new ObjectMapper();
 6
 7//read JSON like DOM Parser
 8JsonNode rootNode = objectMapper.readTree(jsonData);
 9JsonNode idNode = rootNode.path("id");
10System.out.println("id = "+idNode.asInt());
11
12JsonNode phoneNosNode = rootNode.path("phoneNumbers");
13Iterator<JsonNode> elements = phoneNosNode.elements();
14while(elements.hasNext()){
15    JsonNode phone = elements.next();
16    System.out.println("Phone No = "+phone.asLong());
17}

当我们执行以上代码片段时,我们会得到跟踪输出。

1id = 123
2Phone No = 123456
3Phone No = 987654

杰克逊JSON - 编辑JSON文档

Jackson JSON Java API 提供有用的方法来添加、编辑和删除 JSON 数据中的密钥,然后我们可以将其保存为新的 json 文件或将其写入任何流。

 1byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
 2
 3ObjectMapper objectMapper = new ObjectMapper();
 4
 5//create JsonNode
 6JsonNode rootNode = objectMapper.readTree(jsonData);
 7
 8//update JSON data
 9((ObjectNode) rootNode).put("id", 500);
10//add new key value
11((ObjectNode) rootNode).put("test", "test value");
12//remove existing key
13((ObjectNode) rootNode).remove("role");
14((ObjectNode) rootNode).remove("properties");
15objectMapper.writeValue(new File("updated_emp.txt"), rootNode);

如果您要执行上述代码并搜索新文件,您会注意到它没有角色属性键,您还会注意到id值被更新到500,并在更新_emp.txt文件中添加一个新的测试键。

杰克逊 JSON 流媒体 API 示例

Jackson JSON Java API 还提供流媒体支持,在处理大型 json 数据时有帮助,因为它将整个文件读取为代币,并且使用更少的内存。 流媒体 API 的唯一问题是,我们需要在分析 JSON 数据时照顾所有代币。

 1package com.journaldev.jackson.json;
 2
 3import java.io.File;
 4import java.io.IOException;
 5import java.util.ArrayList;
 6import java.util.HashMap;
 7import java.util.List;
 8
 9import com.fasterxml.jackson.core.JsonFactory;
10import com.fasterxml.jackson.core.JsonParseException;
11import com.fasterxml.jackson.core.JsonParser;
12import com.fasterxml.jackson.core.JsonToken;
13import com.journaldev.jackson.model.Address;
14import com.journaldev.jackson.model.Employee;
15
16public class JacksonStreamingReadExample {
17
18    public static void main(String[] args) throws JsonParseException, IOException {
19    	
20    	//create JsonParser object
21    	JsonParser jsonParser = new JsonFactory().createParser(new File("employee.txt"));
22    	
23    	//loop through the tokens
24    	Employee emp = new Employee();
25    	Address address = new Address();
26    	emp.setAddress(address);
27    	emp.setCities(new ArrayList<String>());
28    	emp.setProperties(new HashMap<String, String>());
29    	List<Long> phoneNums = new ArrayList<Long>();
30    	boolean insidePropertiesObj=false;
31    	
32    	parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
33    	
34    	long[] nums = new long[phoneNums.size()];
35    	int index = 0;
36    	for(Long l :phoneNums){
37    		nums[index++] = l;
38    	}
39    	emp.setPhoneNumbers(nums);
40    	
41    	jsonParser.close();
42    	//print employee object
43    	System.out.println("Employee Object\n\n"+emp);
44    }
45
46    private static void parseJSON(JsonParser jsonParser, Employee emp,
47    		List<Long> phoneNums, boolean insidePropertiesObj) throws JsonParseException, IOException {
48    	
49    	//loop through the JsonTokens
50    	while(jsonParser.nextToken() != JsonToken.END_OBJECT){
51    		String name = jsonParser.getCurrentName();
52    		if("id".equals(name)){
53    			jsonParser.nextToken();
54    			emp.setId(jsonParser.getIntValue());
55    		}else if("name".equals(name)){
56    			jsonParser.nextToken();
57    			emp.setName(jsonParser.getText());
58    		}else if("permanent".equals(name)){
59    			jsonParser.nextToken();
60    			emp.setPermanent(jsonParser.getBooleanValue());
61    		}else if("address".equals(name)){
62    			jsonParser.nextToken();
63    			//nested object, recursive call
64    			parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
65    		}else if("street".equals(name)){
66    			jsonParser.nextToken();
67    			emp.getAddress().setStreet(jsonParser.getText());
68    		}else if("city".equals(name)){
69    			jsonParser.nextToken();
70    			emp.getAddress().setCity(jsonParser.getText());
71    		}else if("zipcode".equals(name)){
72    			jsonParser.nextToken();
73    			emp.getAddress().setZipcode(jsonParser.getIntValue());
74    		}else if("phoneNumbers".equals(name)){
75    			jsonParser.nextToken();
76    			while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
77    				phoneNums.add(jsonParser.getLongValue());
78    			}
79    		}else if("role".equals(name)){
80    			jsonParser.nextToken();
81    			emp.setRole(jsonParser.getText());
82    		}else if("cities".equals(name)){
83    			jsonParser.nextToken();
84    			while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
85    				emp.getCities().add(jsonParser.getText());
86    			}
87    		}else if("properties".equals(name)){
88    			jsonParser.nextToken();
89    			while(jsonParser.nextToken() != JsonToken.END_OBJECT){
90    				String key = jsonParser.getCurrentName();
91    				jsonParser.nextToken();
92    				String value = jsonParser.getText();
93    				emp.getProperties().put(key, value);
94    			}
95    		}
96    	}
97    }
98
99}

JsonParser 是 jackson json 流媒体 API 来读 json 数据,我们正在使用它来读取来自文件的数据,然后使用 parseJSON() 方法来循环通过代币并处理它们来创建我们的 java 对象. 请注意,parseJSON() 方法被重复称为地址,因为它是在 json 数据中嵌入的对象。

 1package com.journaldev.jackson.json;
 2
 3import java.io.FileOutputStream;
 4import java.io.IOException;
 5import java.util.Set;
 6
 7import com.fasterxml.jackson.core.JsonFactory;
 8import com.fasterxml.jackson.core.JsonGenerator;
 9import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
10import com.journaldev.jackson.model.Employee;
11
12public class JacksonStreamingWriteExample {
13
14    public static void main(String[] args) throws IOException {
15    	Employee emp = JacksonObjectMapperExample.createEmployee();
16
17    	JsonGenerator jsonGenerator = new JsonFactory()
18    			.createGenerator(new FileOutputStream("stream_emp.txt"));
19    	//for pretty printing
20    	jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
21    	
22    	jsonGenerator.writeStartObject(); // start root object
23    	jsonGenerator.writeNumberField("id", emp.getId());
24    	jsonGenerator.writeStringField("name", emp.getName());
25    	jsonGenerator.writeBooleanField("permanent", emp.isPermanent());
26    	
27    	jsonGenerator.writeObjectFieldStart("address"); //start address object
28    		jsonGenerator.writeStringField("street", emp.getAddress().getStreet());
29    		jsonGenerator.writeStringField("city", emp.getAddress().getCity());
30    		jsonGenerator.writeNumberField("zipcode", emp.getAddress().getZipcode());
31    	jsonGenerator.writeEndObject(); //end address object
32    	
33    	jsonGenerator.writeArrayFieldStart("phoneNumbers");
34    		for(long num : emp.getPhoneNumbers())
35    			jsonGenerator.writeNumber(num);
36    	jsonGenerator.writeEndArray();
37    	
38    	jsonGenerator.writeStringField("role", emp.getRole());
39    	
40    	jsonGenerator.writeArrayFieldStart("cities"); //start cities array
41    	for(String city : emp.getCities())
42    		jsonGenerator.writeString(city);
43    	jsonGenerator.writeEndArray(); //closing cities array
44    	
45    	jsonGenerator.writeObjectFieldStart("properties");
46    		Set<String> keySet = emp.getProperties().keySet();
47    		for(String key : keySet){
48    			String value = emp.getProperties().get(key);
49    			jsonGenerator.writeStringField(key, value);
50    		}
51    	jsonGenerator.writeEndObject(); //closing properties
52    	jsonGenerator.writeEndObject(); //closing root object
53    	
54    	jsonGenerator.flush();
55    	jsonGenerator.close();
56    }
57
58}

JsonGenerator 与 JsonParser 相比,易于使用,这就是 Jackson JSON Parser Java API 的快速参考教程。 Jackson JSON Java API 易于使用,并为开发人员使用 JSON 数据的便利提供了许多选项。

下载杰克逊JSON项目

参考: Jackson GitHub 页面

Published At
Categories with 技术
Tagged with
comments powered by Disqus