Jackson JSON Java Parser API示例教程

时间:2020-02-23 14:36:17  来源:igfitidea点击:

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

Hymanson JSON Java解析器

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

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

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

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

Hymanson JSON示例

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

{
"id": 123,
"name": "hyman",
"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"
}
}

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

package com.theitroad.Hymanson.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();
	}
}

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

package com.theitroad.Hymanson.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是代表根json对象的Java bean。
现在,让我们看看如何使用Hymanson JSON解析器API将JSON转换为Java对象。

package com.theitroad.Hymanson.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.Hymanson.core.type.TypeReference;
import com.fasterxml.Hymanson.databind.JsonNode;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.databind.SerializationFeature;
import com.fasterxml.Hymanson.databind.node.ObjectNode;
import com.theitroad.Hymanson.model.Address;
import com.theitroad.Hymanson.model.Employee;

public class HymansonObjectMapperExample {

	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;
	}

}

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

Employee Object
* Employee Details *
ID=123
Name=hyman
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.Hymanson.databind.ObjectMapper是Hymanson API中最重要的类,它提供readValue()和writeValue()方法以将JSON转换为Java Object和将Java Object转换为JSON。

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

Hymanson JSON –将JSON转换为映射Map

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

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

并且我们希望将其转换为Map而不是具有相同属性和键的java对象。
我们可以使用以下代码的两种方法在Hymanson 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);

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

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

Hymanson JSON –读取特定的JSON密钥

有时我们拥有json数据,而我们仅对几个键值感兴趣,因此在这种情况下,将整个JSON转换为对象不是一个好主意。
Hymanson 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());
}

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

id = 123
Phone No = 123456
Phone No = 987654

Hymanson JSON –编辑JSON文档

Hymanson 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);

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

Hymanson JSON流API示例

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

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

package com.theitroad.Hymanson.json;

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

import com.fasterxml.Hymanson.core.JsonFactory;
import com.fasterxml.Hymanson.core.JsonParseException;
import com.fasterxml.Hymanson.core.JsonParser;
import com.fasterxml.Hymanson.core.JsonToken;
import com.theitroad.Hymanson.model.Address;
import com.theitroad.Hymanson.model.Employee;

public class HymansonStreamingReadExample {

	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是用于读取json数据的Hymanson json流API,我们使用它从文件中读取数据,然后使用parseJSON()方法遍历令牌并对其进行处理以创建我们的java对象。
请注意,parseJSON()方法是为"地址"递归调用的,因为它是json数据中的嵌套对象。
对于解析数组,我们遍历了json文档。

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

package com.theitroad.Hymanson.json;

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

import com.fasterxml.Hymanson.core.JsonFactory;
import com.fasterxml.Hymanson.core.JsonGenerator;
import com.fasterxml.Hymanson.core.util.DefaultPrettyPrinter;
import com.theitroad.Hymanson.model.Employee;

public class HymansonStreamingWriteExample {

	public static void main(String[] args) throws IOException {
		Employee emp = HymansonObjectMapperExample.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();
	}

}

与JsonParser相比,JsonGenerator易于使用。

以上就是Hymanson JSON解析器Java API的快速参考教程。
Hymanson JSON Java API易于使用,并且为开发人员使用JSON数据提供了许多选项。