gson 解析json_Gson示例教程解析JSON

gson 解析json

Welcome to Gson Example Tutorial. In last post we looked at the Java JSON API and you can easily tell that it’s not convenient to use it. Whether you have to convert JSON to Java Object or otherwise, you need to write a lot of code that is tightly coupled with the JSON structure.

欢迎使用Gson示例教程。 在上一篇文章中,我们研究了Java JSON API ,您可以很容易地看出使用它并不方便。 无论您是否必须将JSON转换为Java Object,都需要编写大量与JSON结构紧密结合的代码。

格森 (Gson)

I started looking out for some other JSON parser API that can do the transformation itself and found about Google Gson. Gson is an open source code and it’s used a lot in working with JSON and Java. Gson uses Java Reflection to provide simple methods to convert JSON to java and vice versa.

我开始寻找其他可以自行完成转换的JSON解析器API,并找到了有关Google Gson的信息。 Gson是一个开放源代码,在JSON和Java中已被大量使用。 Gson使用Java Reflection提供简单的方法来将JSON转换为Java,反之亦然。

格森·Maven (Gson Maven)

You can download Gson jar file from google code website or if you are using maven then all you need is to add it’s dependency like below.

您可以从Google代码网站下载Gson jar文件,或者如果您使用的是maven,则只需添加它的依赖项,如下所示。

<dependencies>
    <!--  Gson dependency -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
    </dependency>
</dependencies>

Gson is very powerful API and it supports Java Generics. Gson API also supports out of the box JSON to Java Object conversion if the object field names are same as in json. If we want to use different name for java bean and json, then we can use @SerializedName java annotation and map the variables in JSON and Java Class.

Gson是非常强大的API,它支持Java泛型 。 如果对象字段名称与json中的相同,则Gson API还支持将JSON转换为Java Object。 如果要为Java bean和json使用不同的名称,则可以使用@SerializedName java批注并在JSON和Java类中映射变量。

格森的例子 (Gson Example)

Let’s look at a complex Gson example that involves nested object and array in JSON and we will map it to java bean properties of type List, Map, Array etc.

让我们看一个复杂的Gson示例,该示例涉及JSON中的嵌套对象和数组,并将其映射到类型为List,Map,Array等的Java bean属性。

employee.txt

employee.txt

{
  "empID": 100,
  "name": "David",
  "permanent": false,
  "address": {
    "street": "BTM 1st Stage",
    "city": "Bangalore",
    "zipcode": 560100
  },
  "phoneNumbers": [
    123456,
    987654
  ],
  "role": "Manager",
  "cities": [
    "Los Angeles",
    "New York"
  ],
  "properties": {
    "age": "28 years",
    "salary": "1000 Rs"
  }
}

Let’s create the java bean classes to convert JSON to Java Object.

让我们创建Java Bean类以将JSON转换为Java Object。

Employee.java

Employee.java

package com.journaldev.json.model;

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

import com.google.gson.annotations.SerializedName;

public class Employee {

	@SerializedName("empID")
	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;
	}
}

Address.java

Address.java

package com.journaldev.json.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();
	}
}

Here is the java program showing Gson example to parse JSON.

这是显示Gson示例以解析JSON的Java程序。

EmployeeGsonExample.java

EmployeeGsonExample.java

package com.journaldev.json.gson;

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

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.journaldev.json.model.Address;
import com.journaldev.json.model.Employee;

public class EmployeeGsonExample {

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

		// Get Gson object
		Gson gson = new GsonBuilder().setPrettyPrinting().create();

		// read JSON file data as String
		String fileData = new String(Files.readAllBytes(Paths
				.get("employee.txt")));

		// parse json string to object
		Employee emp1 = gson.fromJson(fileData, Employee.class);

		// print object data
		System.out.println("\n\nEmployee Object\n\n" + emp1);

		// create JSON String from Object
		String jsonEmp = gson.toJson(emp);
		System.out.print(jsonEmp);

	}

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

Gson is the main class that exposes the methods fromJson() and toJson() for conversion. For default implementation, we can create this object directly or we can use GsonBuilder class that provide useful options for conversion such as pretty printing, field naming convention, excluding fields, date format etc.

Gson是主要类,它公开了fromJson()toJson()进行转换。 对于默认实现,我们可以直接创建此对象,也可以使用GsonBuilder类,该类提供了有用的转换选项,例如漂亮的打印,字段命名约定,排除字段,日期格式等。

When you will run above gson example program, we will get following output for java object.

当您在gson示例程序上方运行时,我们将为java对象获得以下输出。

Employee Object

***** Employee Details *****
ID=100
Name=David
Permanent=false
Role=Manager
Phone Numbers=[123456, 987654]
Address=BTM 1st Stage, Bangalore, 560100
Cities=[Los Angeles, New York]
Properties={age=28 years, salary=1000 Rs}
*****************************

You can see how easy it is to use Gson and that’s why Gson is a very popular java API for JSON parsing.

您可以看到使用Gson多么容易,这就是为什么Gson是非常流行的JSON解析Java API的原因。

The above Gson example of JSON parsing is known as Object model because whole JSON is converted to object at once. Most of the times it’s enough for us but if JSON is really huge and we don’t want to have all of it in memory at once, Gson provides Streaming API too.

上面的JSON解析的Gson示例被称为对象模型,因为整个JSON会立即转换为对象。 在大多数情况下,这对我们来说已经足够了,但是如果JSON确实非常庞大并且我们不想一次将所有内容都存储在内存中,那么Gson也会提供Streaming API

Gson示例使用流API解析JSON (Gson Example Parse JSON using Streaming API)

Let’s see Gson example where we will use Streaming API for json to java object conversion.

让我们看一下Gson示例,在这里我们将使用Streaming API将json转换为java对象。

EmployeeGsonReader.java

EmployeeGsonReader.java

package com.journaldev.json.gson;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.journaldev.json.model.Address;
import com.journaldev.json.model.Employee;

public class EmployeeGsonReader {

	public static void main(String[] args) throws IOException {
		InputStream is = new FileInputStream("employee.txt");
		InputStreamReader isr = new InputStreamReader(is);
		
		//create JsonReader object
		JsonReader reader = new JsonReader(isr);
		
		//create objects
		Employee emp = new Employee();
		Address add = new Address();
		emp.setAddress(add);
		List<Long> phoneNums = new ArrayList<Long>();
		emp.setCities(new ArrayList<String>());
		emp.setProperties(new HashMap<String, String>());
		String key = null;
		boolean insidePropertiesObj=false;
		
		key = parseJSON(reader, emp, phoneNums, key, insidePropertiesObj);
		
		
		long[] nums = new long[phoneNums.size()];
		int index = 0;
		for(Long l :phoneNums){
			nums[index++] = l;
		}
		emp.setPhoneNumbers(nums);
		
		reader.close();
		//print employee object
		System.out.println("Employee Object\n\n"+emp);
	}
	
	

	private static String parseJSON(JsonReader reader, Employee emp,
			List<Long> phoneNums, String key, boolean insidePropertiesObj) throws IOException {
		
		//loop to read all tokens
				while(reader.hasNext()){
					//get next token
					JsonToken token = reader.peek();
					
					switch(token){
					case BEGIN_OBJECT:
						reader.beginObject();
						if("address".equals(key) || "properties".equals(key)){
							while(reader.hasNext()){
							parseJSON(reader, emp,phoneNums, key, insidePropertiesObj);
							}
							reader.endObject();
						}
						break;
					case END_OBJECT:
						reader.endObject();
						if(insidePropertiesObj) insidePropertiesObj=false;
						break;
					case BEGIN_ARRAY:
						reader.beginArray();
						if("phoneNumbers".equals(key) || "cities".equals(key)){
							while(reader.hasNext()){
								parseJSON(reader, emp,phoneNums, key, insidePropertiesObj);
								}
							reader.endArray();
						}
						break;
					case END_ARRAY:
						reader.endArray();
						break;
					case NAME:
						key = reader.nextName();
						if("properties".equals(key)) insidePropertiesObj=true;
						break;
					case BOOLEAN:
						if("permanent".equals(key)) emp.setPermanent(reader.nextBoolean());
						else{
							System.out.println("Unknown item found with key="+key);
							//skip value to ignore it
							reader.skipValue();
						}
						break;
					case NUMBER:
						if("empID".equals(key)) emp.setId(reader.nextInt());
						else if("phoneNumbers".equals(key)) phoneNums.add(reader.nextLong());
						else if("zipcode".equals(key)) emp.getAddress().setZipcode(reader.nextInt());
						else {
							System.out.println("Unknown item found with key="+key);
							//skip value to ignore it
							reader.skipValue();
						}
						break;
					case STRING:
						setStringValues(emp, key, reader.nextString(), insidePropertiesObj);
						break;
					case NULL:
						System.out.println("Null value for key"+key);
						reader.nextNull();
						break;
					case END_DOCUMENT:
						System.out.println("End of Document Reached");
						break;
					default:
						System.out.println("This part will never execute");
						break;
						
					}
				}
				return key;
	}



	private static void setStringValues(Employee emp, String key,
			String value, boolean insidePropertiesObj) {
		if("name".equals(key)) emp.setName(value);
		else if("role".equals(key)) emp.setRole(value);
		else if("cities".equals(key)) emp.getCities().add(value);
		else if ("street".equals(key)) emp.getAddress().setStreet(value);
		else if("city".equals(key)) emp.getAddress().setCity(value);
		else{
			//add to emp properties map
			if(insidePropertiesObj){
				emp.getProperties().put(key, value);
			}else{
				System.out.println("Unknown data found with key="+key+" value="+value);
			}
			
		}
	}

}

Since JSON is a recursive language, we need to call our parsing method recursively for array and nested object. JsonToken is java enum returned by JsonReader next() method that we can use with conditional logic or switch case statements for conversion.

由于JSON是一种递归语言,因此我们需要为数组和嵌套对象递归调用解析方法。 JsonToken是JsonReader next()方法返回的Java枚举 ,我们可以将其与条件逻辑一起使用或切换case语句进行转换。

From the code above, you can understand that it’s not an easy implementation and if the JSON is really complex, then this code will become very hard to maintain. Avoid using it until unless there is no way to use Object based model.

从上面的代码中,您可以了解到这不是一个简单的实现,并且如果JSON确实很复杂,那么此代码将很难维护。 除非没有办法使用基于对象的模型,否则请避免使用它。

将对象写入文件的Gson示例 (Gson Example to Write Object to File)

Let’s see how we can write Employee object using Gson Streaming API.

让我们看看如何使用Gson Streaming API编写Employee对象。

EmployeeGsonWriter.java

EmployeeGsonWriter.java

package com.journaldev.json.gson;

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

import com.google.gson.stream.JsonWriter;
import com.journaldev.json.model.Employee;

public class EmployeeGsonWriter {

	public static void main(String[] args) throws IOException {
		Employee emp = EmployeeGsonExample.createEmployee();
		
		//writing on console, we can initialize with FileOutputStream to write to file
		OutputStreamWriter out = new OutputStreamWriter(System.out);
		JsonWriter writer = new JsonWriter(out);
		//set indentation for pretty print
		writer.setIndent("\t");
		//start writing
		writer.beginObject(); //{
		writer.name("id").value(emp.getId()); // "id": 123
		writer.name("name").value(emp.getName()); // "name": "David"
		writer.name("permanent").value(emp.isPermanent()); // "permanent": false
		writer.name("address").beginObject(); // "address": {
			writer.name("street").value(emp.getAddress().getStreet()); // "street": "BTM 1st Stage"
			writer.name("city").value(emp.getAddress().getCity()); // "city": "Bangalore"
			writer.name("zipcode").value(emp.getAddress().getZipcode()); // "zipcode": 560100
			writer.endObject(); // }
		writer.name("phoneNumbers").beginArray(); // "phoneNumbers": [
			for(long num : emp.getPhoneNumbers()) writer.value(num); //123456,987654
			writer.endArray(); // ]
		writer.name("role").value(emp.getRole()); // "role": "Manager"
		writer.name("cities").beginArray(); // "cities": [
			for(String c : emp.getCities()) writer.value(c); //"Los Angeles","New York"
			writer.endArray(); // ]
		writer.name("properties").beginObject(); //"properties": {
			Set<String> keySet = emp.getProperties().keySet();
			for(String key : keySet) writer.name("key").value(emp.getProperties().get(key));//"age": "28 years","salary": "1000 Rs"
			writer.endObject(); // }
		writer.endObject(); // }
		
		writer.flush();
		
		//close writer
		writer.close();
		
	}

}

Converting java object to JSON is comparatively easy than parsing with Gson streaming API. By default JsonWriter writes json in compact form but we can set indent for pretty printing.

与使用Gson流API进行解析相比,将Java对象转换为JSON相对容易。 默认情况下,JsonWriter以紧凑形式编写json,但我们可以设置缩进以进行漂亮的打印。

That’s all for Gson example tutorial, let me know if you face any issues with it. Download project from below link and play around with different options Gson provides.

这就是Gson示例教程的全部内容,如果您遇到任何问题,请告诉我。 从下面的链接下载项目,并尝试使用Gson提供的不同选项。

References:

参考文献:

Google-Gson on Google Code
Gson User Guide

Google Code上的Google-Gson
Gson用户指南

翻译自: https://www.journaldev.com/2321/gson-example-tutorial-parse-json

gson 解析json

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值