将Gson 2.2.4与嵌套对象和JsonReader一起用于流式传输。
JSON:
{
"name": "David",
"address": {
"city": "Bangalore"
},
"role": "Manager"
}
POJO课程:
public class Data {
private String name;
private String role;
private Address address;
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString(){
return getName() + "::"+getRole()+"::"+getAddress().getCity();
}
}
public class Address {
private String city;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
我的代码:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
public class TestReader {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("test.txt");
InputStreamReader isr = new InputStreamReader(is);
JsonReader reader = new JsonReader(isr);
Data data = new Data();
data.setAddress(new Address());
String key = null;
while (reader.hasNext()) {
JsonToken token = reader.peek();
switch (token) {
case BEGIN_OBJECT:
reader.beginObject();
break;
case END_OBJECT:
reader.endObject();
break;
case BEGIN_ARRAY:
reader.beginArray();
break;
case END_ARRAY:
reader.endArray();
break;
case NAME:
key = reader.nextName();
break;
case STRING:
if ("name".equals(key))
data.setName(reader.nextString());
else if ("role".equals(key))
data.setRole(reader.nextString());
else if ("city".equals(key))
data.getAddress().setCity(reader.nextString());
break;
case NULL:
reader.nextNull();
break;
case END_DOCUMENT:
break;
default:
break;
}
}
reader.close();
System.out.println(data);
}
}
它打印“David :: null :: Bangalore”并且无法在嵌套对象之后解析任何内容。如果我将JSON更改为
{
"name": "David",
"role": "Manager",
"address": {
"city": "Bangalore"
}
}
它工作正常并打印“David :: Manager :: Bangalore”。尝试了很多,但不确定我错过了什么。
答案 0 :(得分:2)
由于JSON本质上是递归的,因此您的方法也应如此。那就是你需要再次调用Address对象而不是Data。
所以我修复了你的代码(我管理它,以一种天真的方式)来处理这个特定的情况。如果你有一个更复杂的结构,当然方法也会变得更复杂。
package stackoverflow.questions.q19282973;
import java.io.*;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
public class TestReader {
public static void main(String[] args) throws IOException {
String json = "{\"name\": \"David\",\"address\": {\"city\": \"Bangalore\"},\"role\": \"Manager\"}";
String json2 = "{\"name\": \"David\",\"role\": \"Manager\",\"address\": {\"city\": \"Bangalore\"}}";
InputStream is = new ByteArrayInputStream(json2.getBytes("UTF-8"));
InputStreamReader isr = new InputStreamReader(is);
JsonReader reader = new JsonReader(isr);
Data data = new Data();
data.setAddress(new Address());
String key = null;
key = read(reader, data, key);
reader.close();
System.out.println(data);
}
private static String read(JsonReader reader, Object obj, String key)
throws IOException {
while (reader.hasNext()) {
JsonToken token = reader.peek();
switch (token) {
case BEGIN_OBJECT:
reader.beginObject();
if ("address".equals(key)) {
while (reader.hasNext()) {
read(reader, ((Data) obj).getAddress(), key);
}
reader.endObject();
}
break;
case END_OBJECT:
reader.endObject();
break;
case BEGIN_ARRAY:
reader.beginArray();
break;
case END_ARRAY:
reader.endArray();
break;
case NAME:
key = reader.nextName();
break;
case STRING:
if (obj instanceof Data) {
Data data = (Data) obj;
if ("name".equals(key))
data.setName(reader.nextString());
else if ("role".equals(key))
data.setRole(reader.nextString());
}
if (obj instanceof Address) {
Address address = (Address) obj;
if ("city".equals(key))
address.setCity(reader.nextString());
}
break;
case NULL:
reader.nextNull();
break;
case END_DOCUMENT:
break;
default:
break;
}
}
return key;
}
}
但为什么要使用JsonReader ?它应该只用于特定情况,任何情况下它都是一个非常低级别的Gson类。
你只需要这样的东西
Data d = new Gson().fromJson(yourJsonString, Data.class) to parse.
或者,如果您只想解析JSON的特定部分,可以编写自己的反序列化器。