json.parser性能_Jackson JSON Java Parser API示例教程

json.parser性能

Jackson JSON Java Parser is very popular and used in Spring framework too. Java JSON Processing API is not very user friendly and doesn’t provide features for automatic transformation from Json to Java object and vice versa. Luckily we have some alternative APIs that we can use for JSON processing. In last article we learned about Google Gson API and saw how easy to use it.

Jackson JSON Java Parser非常流行,并且也用于Spring框架。 Java JSON处理API并不是非常用户友好,并且不提供自动从Json转换为Java对象(反之亦然)的功能。 幸运的是,我们有一些可用于JSON处理的替代API。 在上一篇文章中,我们了解了Google Gson API,并了解了它的易用性。

杰克逊JSON Java解析器 (Jackson JSON Java Parser)

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.


要在我们的项目中使用Jackson JSON Java API,我们可以将其添加到项目构建路径中;如果您使用的是maven,则可以在下面添加依赖项。

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

jackson-databind jar depends on jackson-core and jackson-annotations libraries, so if you are adding them directly to build path, make sure you add all three otherwise you will get runtime error.

jackson-databind jar依赖于jackson-corejackson-annotations库,因此,如果直接将它们添加到构建路径,请确保将所有三个都添加,否则会出现运行时错误。

Jackson JSON Parser API provides easy way to convert JSON to POJO Object and supports easy conversion to Map from JSON data. Jackson supports generics too and directly converts them from JSON to object.

Jackson JSON Parser API提供了将JSON转换为POJO对象的简便方法,并支持从JSON数据轻松转换为Map。 Jackson也支持泛型,并将其直接从JSON转换为对象。

杰克逊JSON示例 (Jackson JSON Example)

For our example for JSON to POJO/Java object conversion, we will take a complex example with nested object and arrays. We will use arrays, list and Map in java objects for conversion. Our complex json is stored in a file employee.txt with below structure:

对于从JSON到POJO / Java对象转换的示例,我们将使用一个嵌套对象和数组的复杂示例。 我们将在java对象中使用数组,列表和Map进行转换。 我们的复杂json存储在文件employee.txt中,其结构如下:

{
  "id": 123,
  "name": "Pankaj",
  "permanent": true,
  "address": {
    "street": "Albany Dr",
    "city": "San Jose",
    "zipcode": 95129
  },
  "phoneNumbers": [
    123456,
    987654
  ],
  "role": "Manager",
  "cities": [
    "Los Angeles",
    "New York"
  ],
  "properties": {
    "age": "29 years",
    "salary": "1000 USD"
  }
}

We have following java classes corresponding to the json data.

我们有以下与json数据相对应的java类。

package com.journaldev.jackson.model;

public class Address {
	
	private String street;
	private String city;
	private int zipcode;
	
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public int getZipcode() {
		return zipcode;
	}
	public void setZipcode(int zipcode) {
		this.zipcode = zipcode;
	}
	
	@Override
	public String toString(){
		return getStreet() + ", "+getCity()+", "+getZipcode();
	}
}

Address class corresponds to the inner object in the root json data.

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

package com.journaldev.jackson.model;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Employee {

	private int id;
	private String name;
	private boolean permanent;
	private Address address;
	private long[] phoneNumbers;
	private String role;
	private List<String> cities;
	private Map<String, String> properties;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public boolean isPermanent() {
		return permanent;
	}
	public void setPermanent(boolean permanent) {
		this.permanent = permanent;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public long[] getPhoneNumbers() {
		return phoneNumbers;
	}
	public void setPhoneNumbers(long[] phoneNumbers) {
		this.phoneNumbers = phoneNumbers;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
	
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("***** Employee Details *****\n");
		sb.append("ID="+getId()+"\n");
		sb.append("Name="+getName()+"\n");
		sb.append("Permanent="+isPermanent()+"\n");
		sb.append("Role="+getRole()+"\n");
		sb.append("Phone Numbers="+Arrays.toString(getPhoneNumbers())+"\n");
		sb.append("Address="+getAddress()+"\n");
		sb.append("Cities="+Arrays.toString(getCities().toArray())+"\n");
		sb.append("Properties="+getProperties()+"\n");
		sb.append("*****************************");
		
		return sb.toString();
	}
	public List<String> getCities() {
		return cities;
	}
	public void setCities(List<String> cities) {
		this.cities = cities;
	}
	public Map<String, String> getProperties() {
		return properties;
	}
	public void setProperties(Map<String, String> properties) {
		this.properties = properties;
	}
}

Employee is the java bean representing the root json object. Now let’s see how can we transform JSON to java object using Jackson JSON parser API.

Employee是代表根json对象的Java bean。 现在,让我们看看如何使用杰克逊JSON解析器API将JSON转换为Java对象。

package com.journaldev.jackson.json;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.journaldev.jackson.model.Address;
import com.journaldev.jackson.model.Employee;


public class JacksonObjectMapperExample {

	public static void main(String[] args) throws IOException {
		
		//read json file data to String
		byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
		
		//create ObjectMapper instance
		ObjectMapper objectMapper = new ObjectMapper();
		
		//convert json string to object
		Employee emp = objectMapper.readValue(jsonData, Employee.class);
		
		System.out.println("Employee Object\n"+emp);
		
		//convert Object to json string
		Employee emp1 = createEmployee();
		//configure Object mapper for pretty print
		objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
		
		//writing to console, can write to any output stream such as file
		StringWriter stringEmp = new StringWriter();
		objectMapper.writeValue(stringEmp, emp1);
		System.out.println("Employee JSON is\n"+stringEmp);
	}
	
	public static Employee createEmployee() {

		Employee emp = new Employee();
		emp.setId(100);
		emp.setName("David");
		emp.setPermanent(false);
		emp.setPhoneNumbers(new long[] { 123456, 987654 });
		emp.setRole("Manager");

		Address add = new Address();
		add.setCity("Bangalore");
		add.setStreet("BTM 1st Stage");
		add.setZipcode(560100);
		emp.setAddress(add);

		List<String> cities = new ArrayList<String>();
		cities.add("Los Angeles");
		cities.add("New York");
		emp.setCities(cities);

		Map<String, String> props = new HashMap<String, String>();
		props.put("salary", "1000 Rs");
		props.put("age", "28 years");
		emp.setProperties(props);

		return emp;
	}

}

When we run above program, you will get following output.

当我们运行上述程序时,您将获得以下输出。

Employee Object
***** Employee Details *****
ID=123
Name=Pankaj
Permanent=true
Role=Manager
Phone Numbers=[123456, 987654]
Address=Albany Dr, San Jose, 95129
Cities=[Los Angeles, New York]
Properties={age=29 years, salary=1000 USD}
*****************************
Employee JSON is
//printing same as above json file data

com.fasterxml.jackson.databind.ObjectMapper is the most important class in Jackson API that provides readValue() and writeValue() methods to transform JSON to Java Object and Java Object to JSON.

com.fasterxml.jackson.databind.ObjectMapper是Jackson API中最重要的类,它提供readValue()和writeValue()方法以将JSON转换为Java Object和将Java Object转换为JSON

ObjectMapper class can be reused and we can initialize it once as Singleton object. There are so many overloaded versions of readValue() and writeValue() methods to work with byte array, File, input/output stream and Reader/Writer objects.

ObjectMapper类可以重用,并且可以将其作为Singleton对象初始化一次。 有很多重载版本的readValue()和writeValue()方法可用于字节数组,File,输入/输出流和Reader / Writer对象。

杰克逊JSON –将JSON转换为地图 (Jackson JSON – Converting JSON to Map)

Sometimes we have a JSON object like below, in data.txt file:

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

{
  "name": "David",
  "role": "Manager",
  "city": "Los Angeles"
}

and we want to convert it to a Map and not to java object with same properties and keys. We can do it very easily in Jackson JSON API with two methods with below code:

并且我们希望将其转换为Map而不是具有相同属性和键的java对象。 我们可以使用下面的代码通过两种方法在Jackson JSON API中非常轻松地完成此操作:

//converting json to Map
byte[] mapData = Files.readAllBytes(Paths.get("data.txt"));
Map<String,String> myMap = new HashMap<String, String>();

ObjectMapper objectMapper = new ObjectMapper();
myMap = objectMapper.readValue(mapData, HashMap.class);
System.out.println("Map is: "+myMap);

//another way
myMap = objectMapper.readValue(mapData, new TypeReference<HashMap<String,String>>() {});
System.out.println("Map using TypeReference: "+myMap);

Once we execute above snippet, we get following output:

一旦执行了上面的代码片段,我们将得到以下输出:

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

Jackson JSON –读取特定的JSON密钥 (Jackson JSON – Read Specific JSON Key)

Sometimes we have json data and we are interested in only few of the keys values, so in that case converting whole JSON to object is not a good idea. Jackson JSON API provides option to read json data as tree like DOM Parser and we can read specific elements of JSON object through this. Below code provides snippet to read specific entries from json file.

有时我们拥有json数据,而我们只对几个键值感兴趣,因此在这种情况下,将整个JSON转换为对象不是一个好主意。 Jackson JSON API提供了像DOM Parser这样的树形式读取JSON数据的选项,我们可以通过此方法读取JSON对象的特定元素。 以下代码提供了从json文件读取特定条目的代码段。

//read json file data to String
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));

//create ObjectMapper instance
ObjectMapper objectMapper = new ObjectMapper();

//read JSON like DOM Parser
JsonNode rootNode = objectMapper.readTree(jsonData);
JsonNode idNode = rootNode.path("id");
System.out.println("id = "+idNode.asInt());

JsonNode phoneNosNode = rootNode.path("phoneNumbers");
Iterator<JsonNode> elements = phoneNosNode.elements();
while(elements.hasNext()){
	JsonNode phone = elements.next();
	System.out.println("Phone No = "+phone.asLong());
}

We get following output when we execute above code snippet.

当执行上面的代码片段时,我们得到以下输出。

id = 123
Phone No = 123456
Phone No = 987654

杰克逊JSON –编辑JSON文档 (Jackson JSON – Edit JSON Document)

Jackson JSON Java API provide useful methods to add, edit and remove keys from JSON data and then we can save it as new json file or write it to any stream. Below code shows us how to do this easily.

Jackson JSON Java API提供了有用的方法来添加,编辑和删除JSON数据中的密钥,然后我们可以将其另存为新的json文件或将其写入任何流。 下面的代码向我们展示了如何轻松地做到这一点。

byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));

ObjectMapper objectMapper = new ObjectMapper();

//create JsonNode
JsonNode rootNode = objectMapper.readTree(jsonData);

//update JSON data
((ObjectNode) rootNode).put("id", 500);
//add new key value
((ObjectNode) rootNode).put("test", "test value");
//remove existing key
((ObjectNode) rootNode).remove("role");
((ObjectNode) rootNode).remove("properties");
objectMapper.writeValue(new File("updated_emp.txt"), rootNode);

If you will execute above code and look for the new file, you will notice that it doesn’t have “role” and “properties” key. You will also notice that “id” value is updated to 500 and a new key “test” is added to updated_emp.txt file.

如果执行上述代码并查找新文件,您会注意到它没有“ role”和“ properties”键。 您还将注意到,“ id”值已更新为500,并且新的键“ test”已添加到updated_emp.txt文件。

杰克逊JSON流API示例 (Jackson JSON Streaming API Example)

Jackson JSON Java API also provide streaming support that is helpful in working with large json data because it reads the whole file as tokens and uses less memory. The only problem with streaming API is that we need to take care of all the tokens while parsing the JSON data.

Jackson JSON Java API还提供了流支持,这在处理大型json数据时非常有用,因为它可以将整个文件读取为令牌并使用较少的内存。 流API的唯一问题是,在解析JSON数据时,我们需要照顾所有令牌。

If we have json data as {“role”:”Manager”} then we will get following tokens in order – { (start object), “role” (key name), “Manager” (key value) and } (end object). Colon (:) is the delimiter in JSON and hence not considered as a token.

如果我们将json数据作为{“ role”:“ Manager”},那么我们将按顺序获得以下标记– {(起始对象),“ role”(键名),“ Manager”(键值)和}(结束对象) )。 冒号(:)是JSON中的定界符,因此不视为令牌。

package com.journaldev.jackson.json;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.journaldev.jackson.model.Address;
import com.journaldev.jackson.model.Employee;

public class JacksonStreamingReadExample {

	public static void main(String[] args) throws JsonParseException, IOException {
		
		//create JsonParser object
		JsonParser jsonParser = new JsonFactory().createParser(new File("employee.txt"));
		
		//loop through the tokens
		Employee emp = new Employee();
		Address address = new Address();
		emp.setAddress(address);
		emp.setCities(new ArrayList<String>());
		emp.setProperties(new HashMap<String, String>());
		List<Long> phoneNums = new ArrayList<Long>();
		boolean insidePropertiesObj=false;
		
		parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
		
		long[] nums = new long[phoneNums.size()];
		int index = 0;
		for(Long l :phoneNums){
			nums[index++] = l;
		}
		emp.setPhoneNumbers(nums);
		
		jsonParser.close();
		//print employee object
		System.out.println("Employee Object\n\n"+emp);
	}

	private static void parseJSON(JsonParser jsonParser, Employee emp,
			List<Long> phoneNums, boolean insidePropertiesObj) throws JsonParseException, IOException {
		
		//loop through the JsonTokens
		while(jsonParser.nextToken() != JsonToken.END_OBJECT){
			String name = jsonParser.getCurrentName();
			if("id".equals(name)){
				jsonParser.nextToken();
				emp.setId(jsonParser.getIntValue());
			}else if("name".equals(name)){
				jsonParser.nextToken();
				emp.setName(jsonParser.getText());
			}else if("permanent".equals(name)){
				jsonParser.nextToken();
				emp.setPermanent(jsonParser.getBooleanValue());
			}else if("address".equals(name)){
				jsonParser.nextToken();
				//nested object, recursive call
				parseJSON(jsonParser, emp, phoneNums, insidePropertiesObj);
			}else if("street".equals(name)){
				jsonParser.nextToken();
				emp.getAddress().setStreet(jsonParser.getText());
			}else if("city".equals(name)){
				jsonParser.nextToken();
				emp.getAddress().setCity(jsonParser.getText());
			}else if("zipcode".equals(name)){
				jsonParser.nextToken();
				emp.getAddress().setZipcode(jsonParser.getIntValue());
			}else if("phoneNumbers".equals(name)){
				jsonParser.nextToken();
				while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
					phoneNums.add(jsonParser.getLongValue());
				}
			}else if("role".equals(name)){
				jsonParser.nextToken();
				emp.setRole(jsonParser.getText());
			}else if("cities".equals(name)){
				jsonParser.nextToken();
				while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
					emp.getCities().add(jsonParser.getText());
				}
			}else if("properties".equals(name)){
				jsonParser.nextToken();
				while(jsonParser.nextToken() != JsonToken.END_OBJECT){
					String key = jsonParser.getCurrentName();
					jsonParser.nextToken();
					String value = jsonParser.getText();
					emp.getProperties().put(key, value);
				}
			}
		}
	}

}

JsonParser is the jackson json streaming API to read json data, we are using it to read data from the file and then parseJSON() method is used to loop through the tokens and process them to create our java object. Notice that parseJSON() method is called recursively for “address” because it’s a nested object in the json data. For parsing arrays, we are looping through the json document.

JsonParser是用于读取json数据的杰克逊json流API,我们使用它从文件中读取数据,然后使用parseJSON()方法遍历令牌并对其进行处理以创建我们的java对象。 请注意,parseJSON()方法是为“地址”递归调用的,因为它是json数据中的嵌套对象。 对于解析数组,我们遍历了json文档。

We can use JsonGenerator class to generate json data with streaming API.

我们可以使用JsonGenerator类通过流API生成json数据。

package com.journaldev.jackson.json;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Set;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.journaldev.jackson.model.Employee;

public class JacksonStreamingWriteExample {

	public static void main(String[] args) throws IOException {
		Employee emp = JacksonObjectMapperExample.createEmployee();

		JsonGenerator jsonGenerator = new JsonFactory()
				.createGenerator(new FileOutputStream("stream_emp.txt"));
		//for pretty printing
		jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
		
		jsonGenerator.writeStartObject(); // start root object
		jsonGenerator.writeNumberField("id", emp.getId());
		jsonGenerator.writeStringField("name", emp.getName());
		jsonGenerator.writeBooleanField("permanent", emp.isPermanent());
		
		jsonGenerator.writeObjectFieldStart("address"); //start address object
			jsonGenerator.writeStringField("street", emp.getAddress().getStreet());
			jsonGenerator.writeStringField("city", emp.getAddress().getCity());
			jsonGenerator.writeNumberField("zipcode", emp.getAddress().getZipcode());
		jsonGenerator.writeEndObject(); //end address object
		
		jsonGenerator.writeArrayFieldStart("phoneNumbers");
			for(long num : emp.getPhoneNumbers())
				jsonGenerator.writeNumber(num);
		jsonGenerator.writeEndArray();
		
		jsonGenerator.writeStringField("role", emp.getRole());
		
		jsonGenerator.writeArrayFieldStart("cities"); //start cities array
		for(String city : emp.getCities())
			jsonGenerator.writeString(city);
		jsonGenerator.writeEndArray(); //closing cities array
		
		jsonGenerator.writeObjectFieldStart("properties");
			Set<String> keySet = emp.getProperties().keySet();
			for(String key : keySet){
				String value = emp.getProperties().get(key);
				jsonGenerator.writeStringField(key, value);
			}
		jsonGenerator.writeEndObject(); //closing properties
		jsonGenerator.writeEndObject(); //closing root object
		
		jsonGenerator.flush();
		jsonGenerator.close();
	}

}

JsonGenerator is easy to use in comparison to JsonParser.

与JsonParser相比,JsonGenerator易于使用。

That’s all for quick reference tutorial to Jackson JSON Parser Java API. Jackson JSON Java API is easy to use and provide a lot of options for the ease of developers working with JSON data. Download project from below link and play around with it to explore more options about Jackson Json API.

这就是杰克逊JSON解析器Java API的快速参考教程。 Jackson JSON Java API易于使用,并为开发人员使用JSON数据提供了许多选项。 从下面的链接下载项目并试用它,以探索有关Jackson Json API的更多选项。

Reference: Jackson GitHub Page

参考: Jackson GitHub页面

翻译自: https://www.journaldev.com/2324/jackson-json-java-parser-api-example-tutorial

json.parser性能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Jackson库来处理大型JSON,以下是使用StreamingAPI来处理JSON示例代码: ```java import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import java.io.IOException; import java.io.InputStream; public class JsonStreamingExample { public static void main(String[] args) throws IOException { InputStream inputStream = JsonStreamingExample.class.getResourceAsStream("/large.json"); JsonFactory jsonFactory = new JsonFactory(); JsonParser jsonParser = jsonFactory.createParser(inputStream); while (jsonParser.nextToken() != JsonToken.END_OBJECT) { String fieldName = jsonParser.getCurrentName(); if ("data".equals(fieldName)) { jsonParser.nextToken(); while (jsonParser.nextToken() != JsonToken.END_ARRAY) { String dataFieldName = jsonParser.getCurrentName(); if ("id".equals(dataFieldName)) { jsonParser.nextToken(); System.out.println("id: " + jsonParser.getValueAsString()); } else if ("name".equals(dataFieldName)) { jsonParser.nextToken(); System.out.println("name: " + jsonParser.getValueAsString()); } else { jsonParser.skipChildren(); } } } else { jsonParser.skipChildren(); } } jsonParser.close(); } } ``` 以上代码假设JSON文件的格式如下: ```json { "data": [ { "id": "1", "name": "John" }, { "id": "2", "name": "Jane" } ] } ``` 代码中使用了JsonParser来遍历JSONJsonToken来判断当前解析到的JSON元素类型,skipChildren方法来跳过不需要处理的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值