[英]GSON + parse json from webservice and get the json string for the particular JsonObject
我有从Web服务读取json的情况。 这个Json是包含大量数据的节点数组
我要实现的目标:
需要执行步骤2,因为Java impl将调用另一个服务,该服务又需要每个节点的json进行进一步处理。
为了达到这个目的,我尝试了什么:
我的问题:
staff.json:
[
{
"name": "Joe",
"age" : 35,
"position": "dev",
"salary": 10000,
"skills":[ "angular", "aws", "java"],
"Organistaion" : "Test",
"WorkType": "Full-time"
},
{
"name": "John",
"age" : 29,
"position": "dev",
"salary": 10000,
"skills":[ "python", "c#", "java"],
"Organistaion" : "Test",
"WorkType": "Full-time"
}
]
Staff.java:
public class Staff {
private String name;
private int age;
private String staffJson;
.......
}
StaffSandbox.java:
public class StaffSandbox {
public static void main (String s[]) {
Gson gson = new Gson();
try (Reader reader = new FileReader("C:\\staff.json")) { // for sample code use file
// Step 1
List<Staff> staffs = gson.fromJson(reader, new TypeToken<List<Staff>>() {}.getType());
staffs.forEach(System.out::println);
// Step 2
String json = new String(Files.readAllBytes(Paths.get(("C:\\staff.json"))));
JsonArray jsonElement = gson.fromJson(json, JsonArray.class);
System.out.println( gson.toJson(jsonElement.get(0)).toString());
// Step 3
for (int i = 0; i < json.size(); i++) {
// Read the node Id and match with corresponding Staff object and add the json to it
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
我使用正确的方法吗? 两次解析Json可以吗? 有没有更好的方法来实现这一目标?
并不是的。 您可避免读取文件两次+节省大量的存储在你的第二个读:你正在阅读整个文件的字节数组首先转换成字符串转换为JSON阵列。 对大型文件测试此方法,您可能会遇到OutOfMemoryError
。
我并不热衷于使用JsonReader,但这会是一个更好的解决方案吗? 如果可以,如何辩解?
JsonReader
以流式处理的方式标记化JSON输入,并且在许多情况下JsonReader
您提供很多帮助。
如果我对您的理解正确,那么您只需要以下内容:
private static void zip(final Gson gson, final Reader reader, final Consumer<? super JsonObject> consumer)
throws IOException {
// The next two lines request some stuff from the given Gson instance
final TypeAdapter<JsonObject> jsonObjectTypeAdapter = gson.getAdapter(JsonObject.class);
final JsonReader jsonReader = gson.newJsonReader(reader);
// Ensure that the very first token is array begin `[`
jsonReader.beginArray();
// And read all the array elements
while ( jsonReader.hasNext() ) {
// JsonReader does not consume entire input stream and can read necessary JSON token only
final JsonObject incomingJsonObject = jsonObjectTypeAdapter.read(jsonReader);
// And this is what we generate
final JsonObject outgoingJsonObject = new JsonObject();
outgoingJsonObject.add("name", incomingJsonObject.get("name"));
outgoingJsonObject.add("age", incomingJsonObject.get("age"));
outgoingJsonObject.add("staffJson", new JsonPrimitive(incomingJsonObject.toString()));
// Once a "staff row" is ready to use, just delegate it elsewhere
consumer.accept(outgoingJsonObject);
}
jsonReader.endArray();
}
请注意,上面的示例未使用与Staff
一样的Java映射。 如果需要,可以使用Gson.toJsonTree()
和Gson.fromJson()
将JsonElement
转换为Java映射,反之亦然。 此外,您甚至可以直接将输出写入指定的JsonWriter
甚至不创建outgoingJsonObject
实例(简单的R / W管道:从输入读取==>处理==>写入输出)。
使用示例(请注意,不能两次或多次使用Reader
;使用方实现使用不同的策略:将每个新生成的JsonObject
直接刷新到System.out
(您可以处理非常大的数据集);或将所有此类对象收集到列出,然后做任何您想做的事情(集合必须容纳在内存中):
try ( final Reader reader = getPackageResourceReader(Q43105667.class, "staff.json") ) {
zip(gson, reader, System.out::println);
}
try ( final Reader reader = getPackageResourceReader(Q43105667.class, "staff.json") ) {
final Collection<JsonObject> list = new ArrayList<>();
zip(gson, reader, list::add);
System.out.println(list);
}
{ “名”: “乔”, “年龄”:35, “staffJson”: “{\\” 名称\\ “:\\” 乔\\ “\\ ”年龄\\“:35 \\ ”位置\\“:\\” 开发\\”,\\ “薪水\\”:10000,\\ “技能\\”:[\\ “角\\”,\\ “AWS \\” \\ “的java \\”],\\ “Organistaion \\”:\\ “测试\\”,\\ “WorkType \\”:\\ “全职\\”}“
{ “名”: “约翰”, “年龄”:29, “staffJson”: “{\\” 名称\\ “:\\” 约翰\\ “\\ ”年龄\\“:29 \\ ”位置\\“:\\” 开发\\”,\\ “工资\\”:10000,\\ “技能\\”:\\ “蟒蛇\\”,\\ “C#\\”,\\ “的java \\”] \\ “Organistaion \\”:\\ “测试\\”,\\ “WorkType \\”:\\ “全职\\”}“
[{ “名称”: “乔”, “年龄”:35, “staffJson”: “{\\” 名称\\ “:\\” 乔\\ “\\ ”年龄\\“:35,\\ ”位置\\“:\\” dev的\\”,\\ “薪水\\”:10000,\\ “技能\\”:[\\ “角\\”,\\ “AWS \\” \\ “的java \\”],\\ “Organistaion \\”:\\ “测试\\”, \\“ WorkType \\”:\\“全职\\”}“},{” name“:” John“,” age“:29,” staffJson“:” {\\“ name \\”:\\“ John \\”, \\ “年龄\\”:29 \\ “位置\\”:\\ “开发\\”,\\ “工资\\”:10000,\\ “技能\\”:\\ “蟒蛇\\”,\\ “C#\\”,\\“的java \\ “] \\” Organistaion \\ “:\\” 测试\\ “\\ ”WorkType \\“:\\ ”全职\\“}”}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.