Java JSON 示例
欢迎来到Java JSON示例教程。JSON(JavaScript对象表示法)是一种基于文本的轻量级技术,用于生成易于阅读的格式化数据。JSON以键值对的形式表示对象数据。我们还可以有嵌套的JSON对象,并且它提供了一种简便的方式来表示数组。
Java JSON 可以被改写成 “Java的JSON” 或者 “Java中的JSON” 。
JSON 在 Web 应用或作为服务器响应中被广泛使用,因为它比 XML 更轻量且更紧凑。JSON 对象易于阅读和编写,大多数技术都提供对 JSON 对象的支持。这就是为什么 Java Web 服务中的 JSON 非常流行。JSR353 最终纳入 Java EE 7,它是 Java 的 JSON 处理 API。jsonp 是 Java JSON 处理 API 的参考实现。我们可以通过添加以下依赖项在 Maven 项目中使用它。
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.2</version>
</dependency>
如果您使用的是GlassFish 4.0,则可以将范围保持为provided,因为它已经包含在服务器中。JSON API为JSON处理提供了两种方法:
-
- 对象模型 API – 它类似于 DOM 解析器,适用于小型对象。
- 流式 API – 它类似于 StaX 解析器,适用于大型对象,您不希望将整个对象保存在内存中。
Java JSON API的一些重要接口是:
-
- javax.json.JsonReader: 我们可以使用这个类来读取JSON对象或数组为JsonObject。我们可以从Json类或JsonReaderFactory获得JsonReader。
javax.json.JsonWriter: 我们可以使用这个类将JSON对象写入输出流。
javax.json.stream.JsonParser: 这个类作为一个拉动式解析器,在读取JSON对象时提供流式支持。
javax.json.stream.JsonGenerator: 我们可以使用这个类以流式方式将JSON对象写入输出源。
javax.json.Json: 这个类是用于创建JSON处理对象的工厂类。该类提供了创建这些对象及其对应工厂的最常用方法。工厂类提供了创建这些对象的各种方式。
javax.json.JsonObject: JsonObject代表一个不可变的JSON对象值。
让我们使用简单的程序来了解Java JSON API的使用,我们有一个JSON对象存储在名为employee.txt的文件中;
{
"id":123,
"name":"Pankaj Kumar",
"permanent":true,
"address":{
"street":"El Camino Real",
"city":"San Jose",
"zipcode":95014
},
"phoneNumbers":[9988664422, 1234567890],
"role":"Developer"
}
我们有Java bean类,它们表示了上述的JSON格式:
package com.Olivia.model;
import java.util.Arrays;
public class Employee {
private int id;
private String name;
private boolean permanent;
private Address address;
private long[] phoneNumbers;
private String role;
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());
sb.append("\n*****************************");
return sb.toString();
}
}
package com.Olivia.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();
}
}
我已经重写了toString()方法,以返回人类可读的字符串表示形式,这将在我们的JSON实现类中使用。
Java JSON 读取示例
package com.Olivia.json;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import com.Olivia.model.Address;
import com.Olivia.model.Employee;
public class EmployeeJSONReader {
public static final String JSON_FILE="employee.txt";
public static void main(String[] args) throws IOException {
InputStream fis = new FileInputStream(JSON_FILE);
//create JsonReader object
JsonReader jsonReader = Json.createReader(fis);
/**
* We can create JsonReader from Factory also
JsonReaderFactory factory = Json.createReaderFactory(null);
jsonReader = factory.createReader(fis);
*/
//get JsonObject from JsonReader
JsonObject jsonObject = jsonReader.readObject();
//we can close IO resource and JsonReader now
jsonReader.close();
fis.close();
//Retrieve data from JsonObject and create Employee bean
Employee emp = new Employee();
emp.setId(jsonObject.getInt("id"));
emp.setName(jsonObject.getString("name"));
emp.setPermanent(jsonObject.getBoolean("permanent"));
emp.setRole(jsonObject.getString("role"));
//reading arrays from json
JsonArray jsonArray = jsonObject.getJsonArray("phoneNumbers");
long[] numbers = new long[jsonArray.size()];
int index = 0;
for(JsonValue value : jsonArray){
numbers[index++] = Long.parseLong(value.toString());
}
emp.setPhoneNumbers(numbers);
//reading inner object from json object
JsonObject innerJsonObject = jsonObject.getJsonObject("address");
Address address = new Address();
address.setStreet(innerJsonObject.getString("street"));
address.setCity(innerJsonObject.getString("city"));
address.setZipcode(innerJsonObject.getInt("zipcode"));
emp.setAddress(address);
//print employee bean information
System.out.println(emp);
}
}
执行这个程序很直观,感觉就像从HashMap获取参数一样。JsonReaderFactory实现了工厂设计模式。当我们执行上述程序后,就会得到以下输出。
***** Employee Details *****
ID=123
Name=Pankaj Kumar
Permanent=true
Role=Developer
Phone Numbers=[9988664422, 1234567890]
Address=El Camino Real, San Jose, 95014
*****************************
Java JSON 写入示例
package com.Olivia.json;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;
import com.Olivia.model.Address;
import com.Olivia.model.Employee;
public class EmployeeJSONWriter {
public static void main(String[] args) throws FileNotFoundException {
Employee emp = createEmployee();
JsonObjectBuilder empBuilder = Json.createObjectBuilder();
JsonObjectBuilder addressBuilder = Json.createObjectBuilder();
JsonArrayBuilder phoneNumBuilder = Json.createArrayBuilder();
for (long phone : emp.getPhoneNumbers()) {
phoneNumBuilder.add(phone);
}
addressBuilder.add("street", emp.getAddress().getStreet())
.add("city", emp.getAddress().getCity())
.add("zipcode", emp.getAddress().getZipcode());
empBuilder.add("id", emp.getId())
.add("name", emp.getName())
.add("permanent", emp.isPermanent())
.add("role", emp.getRole());
empBuilder.add("phoneNumbers", phoneNumBuilder);
empBuilder.add("address", addressBuilder);
JsonObject empJsonObject = empBuilder.build();
System.out.println("Employee JSON String\n"+empJsonObject);
//write to file
OutputStream os = new FileOutputStream("emp.txt");
JsonWriter jsonWriter = Json.createWriter(os);
/**
* We can get JsonWriter from JsonWriterFactory also
JsonWriterFactory factory = Json.createWriterFactory(null);
jsonWriter = factory.createWriter(os);
*/
jsonWriter.writeObject(empJsonObject);
jsonWriter.close();
}
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);
return emp;
}
}
当我们运行上述应用程序时,我们会得到以下的响应。
Employee JSON String
{"id":100,"name":"David","permanent":false,"role":"Manager","phoneNumbers":[123456,987654],"address":{"street":"BTM 1st Stage","city":"Bangalore","zipcode":560100}}
JSON对象也被保存在emp.txt文件中。JsonObjectBuilder实现了建造者模式,使其非常易于使用。
Java JSON 解析器示例
Java的JsonParser是一个拉解析器,我们可以通过next()方法读取下一个元素,该方法返回一个Event对象。javax.json.stream.JsonParser.Event是一个枚举类型,使其类型安全且易于使用。我们可以在switch case中使用它来设置我们的Java bean属性。
package com.Olivia.json;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import com.Olivia.model.Address;
import com.Olivia.model.Employee;
public class EmployeeJSONParser {
public static final String FILE_NAME = "employee.txt";
public static void main(String[] args) throws IOException {
InputStream fis = new FileInputStream(FILE_NAME);
JsonParser jsonParser = Json.createParser(fis);
/**
* We can create JsonParser from JsonParserFactory also with below code
* JsonParserFactory factory = Json.createParserFactory(null);
* jsonParser = factory.createParser(fis);
*/
Employee emp = new Employee();
Address address = new Address();
String keyName = null;
List<Long> phoneNums = new ArrayList<Long>();
while (jsonParser.hasNext()) {
Event event = jsonParser.next();
switch (event) {
case KEY_NAME:
keyName = jsonParser.getString();
break;
case VALUE_STRING:
setStringValues(emp, address, keyName, jsonParser.getString());
break;
case VALUE_NUMBER:
setNumberValues(emp, address, keyName, jsonParser.getLong(), phoneNums);
break;
case VALUE_FALSE:
setBooleanValues(emp, address, keyName, false);
break;
case VALUE_TRUE:
setBooleanValues(emp, address, keyName, true);
break;
case VALUE_NULL:
// don't set anything
break;
default:
// we are not looking for other events
}
}
emp.setAddress(address);
long[] nums = new long[phoneNums.size()];
int index = 0;
for(Long l :phoneNums){
nums[index++] = l;
}
emp.setPhoneNumbers(nums);
System.out.println(emp);
//close resources
fis.close();
jsonParser.close();
}
private static void setNumberValues(Employee emp, Address address,
String keyName, long value, List<Long> phoneNums) {
switch(keyName){
case "zipcode":
address.setZipcode((int)value);
break;
case "id":
emp.setId((int) value);
break;
case "phoneNumbers":
phoneNums.add(value);
break;
default:
System.out.println("Unknown element with key="+keyName);
}
}
private static void setBooleanValues(Employee emp, Address address,
String key, boolean value) {
if("permanent".equals(key)){
emp.setPermanent(value);
}else{
System.out.println("Unknown element with key="+key);
}
}
private static void setStringValues(Employee emp, Address address,
String key, String value) {
switch(key){
case "name":
emp.setName(value);
break;
case "role":
emp.setRole(value);
break;
case "city":
address.setCity(value);
break;
case "street":
address.setStreet(value);
break;
default:
System.out.println("Unknown Key="+key);
}
}
}
当我们需要编写逻辑来解析数据时,主要复杂性就出现了,有时候可能会变得复杂。由于我们与JsonReader读取相同的文件,因此输出与EmployeeJsonReader程序相同。
Java 的 JsonGenerator 示例
package com.Olivia.json;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.json.Json;
import javax.json.stream.JsonGenerator;
import com.Olivia.model.Employee;
public class EmployeeJSONGenerator {
public static void main(String[] args) throws IOException {
OutputStream fos = new FileOutputStream("emp_stream.txt");
JsonGenerator jsonGenerator = Json.createGenerator(fos);
/**
* We can get JsonGenerator from Factory class also
* JsonGeneratorFactory factory = Json.createGeneratorFactory(null);
* jsonGenerator = factory.createGenerator(fos);
*/
Employee emp = EmployeeJSONWriter.createEmployee();
jsonGenerator.writeStartObject(); // {
jsonGenerator.write("id", emp.getId()); // "id":123
jsonGenerator.write("name", emp.getName());
jsonGenerator.write("role", emp.getRole());
jsonGenerator.write("permanent", emp.isPermanent());
jsonGenerator.writeStartObject("address") //start of address object
.write("street", emp.getAddress().getStreet())
.write("city",emp.getAddress().getCity())
.write("zipcode",emp.getAddress().getZipcode())
.writeEnd(); //end of address object
jsonGenerator.writeStartArray("phoneNumbers"); //start of phone num array
for(long num : emp.getPhoneNumbers()){
jsonGenerator.write(num);
}
jsonGenerator.writeEnd(); // end of phone num array
jsonGenerator.writeEnd(); // }
jsonGenerator.close();
}
}
Json生成器非常易于使用,对于大数据具有良好的性能。关于Java JSON处理API就是这些。我们学习了Java JSON解析器、读取和写入的示例。您可以从下面的链接下载Java项目并进行实验。
下载Java JSON项目
参考资料:JSONLint – 一个用于验证JSON数据的优秀网络工具,JSON处理参考实现JSR353 JCP页面。