1. Streaming API将JSON内容分为读写事件。JsonReader和JsonWriter将数据读/写为令牌, 称为JsonToken。
2. 它是处理JSON的三种方法中最强大的方法。它具有最低的开销, 并且在读/写操作中非常快。它类似于XML的Stax解析器。
3. 例子
3.1. 新建一个名为GsonStream的Java项目, 同时添加相关jar包。
3.2. 新建Student.java
package com.fj.s;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Boolean isMale;
private Integer[] sanWei;
private Collection<String> familyMembers;
private Map<String, String> scores;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean isMale() {
return isMale;
}
public void setMale(Boolean isMale) {
this.isMale = isMale;
}
public Integer[] getSanWei() {
return sanWei;
}
public void setSanWei(Integer[] sanWei) {
this.sanWei = sanWei;
}
public Collection<String> getFamilyMembers() {
return familyMembers;
}
public void setFamilyMembers(Collection<String> familyMembers) {
this.familyMembers = familyMembers;
}
public Map<String, String> getScores() {
return scores;
}
public void setScores(Map<String, String> scores) {
this.scores = scores;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", isMale=" + isMale + ", sanWei=" + Arrays.toString(sanWei)
+ ", familyMembers=" + familyMembers + ", scores=" + scores + "]";
}
}
3.3. 新建App1.java
package com.fj.s;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
public class App1 {
public static void main(String args[]) {
String jsonString = "{\"id\":1111,\"name\":\"张三\",\"isMale\":false,\"sanWei\":[100,90,85],\"familyMembers\":[\"爸爸\",\"妈妈\",\"妹妹\"],\"scores\":{\"chinese\":\"90\",\"english\":\"90\",\"math\":\"100\"}}";
JsonReader reader = new JsonReader(new StringReader(jsonString));
Student student = new Student();
try {
handleJsonObject(reader, student);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(student);
}
private static void handleJsonObject(JsonReader reader, Student student) throws IOException {
reader.beginObject();
String fieldName = null;
Map<String, String> scores = null;
while (reader.hasNext()) {
JsonToken token = reader.peek();
if (token.equals(JsonToken.BEGIN_ARRAY)) {
handleJsonArray(reader, fieldName, student);
} else if (token.equals(JsonToken.END_OBJECT)) {
reader.endObject();
return;
} else {
if (token.equals(JsonToken.NAME)) {
// 获取当前字段名
fieldName = reader.nextName();
}
switch (fieldName) {
case "scores":
token = reader.peek();
scores = new HashMap<String, String>();
student.setScores(scores);
handleJsonObject(reader, student);
break;
case "id":
token = reader.peek();
student.setId(reader.nextInt());
break;
case "name":
token = reader.peek();
student.setName(reader.nextString());
break;
case "isMale":
token = reader.peek();
student.setMale(reader.nextBoolean());
break;
case "chinese":
token = reader.peek();
student.getScores().put(fieldName, reader.nextString());
break;
case "english":
token = reader.peek();
student.getScores().put(fieldName, reader.nextString());
break;
case "math":
token = reader.peek();
student.getScores().put(fieldName, reader.nextString());
break;
}
}
}
}
private static void handleJsonArray(JsonReader reader, String fieldName, Student student) throws IOException {
reader.beginArray();
Collection<String> familyMembers = null;
List<Integer> sanWei = null;
while (true) {
JsonToken token = reader.peek();
if (token.equals(JsonToken.END_ARRAY)) {
if("sanWei".equals(fieldName)) {
student.setSanWei(sanWei.toArray(new Integer[0]));
}
reader.endArray();
break;
} else if (token.equals(JsonToken.BEGIN_OBJECT)) {
handleJsonObject(reader, student);
} else if (token.equals(JsonToken.END_OBJECT)) {
reader.endObject();
} else {
switch (fieldName) {
case "sanWei":
if(sanWei == null) {
sanWei = new ArrayList<Integer>();
}
sanWei.add(reader.nextInt());
break;
case "familyMembers":
if(familyMembers == null) {
familyMembers = new ArrayList<String>();
student.setFamilyMembers(familyMembers);
}
familyMembers.add(reader.nextString());
break;
}
}
}
}
}
3.4. 运行App1.java
3.5. 新建App2.java
package com.fj.s;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
public class App2 {
public static void main(String[] args) {
Type studentType = new TypeToken<Student>(){}.getType();
String jsonString = "{\"id\":1111,\"name\":\"张三\",\"isMale\":false,\"sanWei\":[100,90,85],\"familyMembers\":[\"爸爸\",\"妈妈\",\"妹妹\"],\"scores\":{\"chinese\":\"90\",\"english\":\"90\",\"math\":\"100\"}}";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
// T fromJson(Reader json, Class<T> classOfT)将指定的json读取器反序列化为指定类的对象。
Reader stringReader = new StringReader(jsonString);
System.out.println(gson.fromJson(stringReader, Student.class));
// T fromJson(Reader json, Type typeOfT)将指定的json读取器按指定类型的适配器将其反序列化为对象。
try {
Reader fileReader = new FileReader("student.json");
System.out.println((Student)gson.fromJson(fileReader, studentType));
fileReader.close();
} catch (JsonIOException | JsonSyntaxException | IOException e) {
e.printStackTrace();
}
// T fromJson(JsonReader reader, Type typeOfT)将指定的JsonReader按指定类型的适配器将其反序列化为对象。
JsonReader jsonReader = new JsonReader(new StringReader(jsonString));
System.out.println((Student)gson.fromJson(jsonReader, studentType));
}
}
3.6. 运行App2.java, 在项目目录下生成student.json
3.7. 新建App3.java
package com.fj.s;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonWriter;
public class App3 {
public static void main(String args[]) {
Type studentType = new TypeToken<Student>(){}.getType();
Student student = new Student();
student.setId(1111);
student.setName("张三");
student.setMale(false);
Integer[] sanWei = {100,90,85};
student.setSanWei(sanWei);
Collection<String> familyMembers = new ArrayList<String>();
familyMembers.add("爸爸");
familyMembers.add("妈妈");
familyMembers.add("妹妹");
student.setFamilyMembers(familyMembers);
Map<String, String> scores = new HashMap<String, String>();
scores.put("chinese", "90");
scores.put("math", "100");
scores.put("english", "90");
student.setScores(scores);
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
try {
// void toJson(Object src, Type typeOfSrc, JsonWriter writer)将指定的对象按指定类型的适配器将其序列化为writer。写入字符串流。
Writer stringWriter = new StringWriter();
gson.toJson(student, studentType, new JsonWriter(stringWriter));
System.out.println(stringWriter.toString());
stringWriter.close();
// void toJson(Object src, Appendable writer)将指定的对象序列化为writer。写入文件流。
FileWriter fileWriter = new FileWriter(new File("student.txt"));
gson.toJson(student, fileWriter);
fileWriter.flush();
fileWriter.close();
} catch (JsonIOException | IOException e) {
e.printStackTrace();
}
}
}
3.8. 运行App3.java, 在项目目录下生成student.txt