Java 使用流API和JSON解析器进行JSON解析-混合模式
假设我有一个文件Java 使用流API和JSON解析器进行JSON解析-混合模式,java,json,Java,Json,假设我有一个文件sample.json,其中包含一个对象数组,如下所示 [ {Name: "ABC", "email" : "abc@123.com", "city" : "NewYork"}, {Name: "XYZ", "email" : "xyz@123.com", "city" : "NewJersey"}] 我正在使用TestNG框架和GSON库解析JSON 下面是我想要解析JSON对象的类。我的目标是按数组中的名称过滤对象,并仅返回该对象。 我使用流式API来避免一次返回json文
sample.json
,其中包含一个对象数组,如下所示
[ {Name: "ABC", "email" : "abc@123.com", "city" : "NewYork"}, {Name: "XYZ", "email" : "xyz@123.com", "city" : "NewJersey"}]
我正在使用TestNG框架和GSON库解析JSON
下面是我想要解析JSON对象的类。我的目标是按数组中的名称过滤对象,并仅返回该对象。
我使用流式API来避免一次返回json文件中的所有数据
public class JSON{
private JsonObject jsonObject;
@Test
public void readJSON(){
getJSONObject("C:\\..\\sample.json", "ABC");
readData("email");
}
public JsonObject getJSONObject(fileName, Name){
JsonReader jsonReader = new JsonReader(new FileReader(fileName));
jsonReader.beginArray();
while (jsonReader.hasNext()){
str = jsonReader.nextString();
If (str.equals(Name)){
System.out.println("Found Name");
// To get the object - we can use fromJson(jsonReader, Person.class),
// where Person.class defines all the json variables as class variables.
// But I want to use JsonParser or something like that to return just this object which has the Name "ABC"
}
}
} }
我不想创建Person类并使用fromJSON的原因是,我将此函数用于不同类型的JSON字符串。所以我不喜欢为不同的字符串创建不同的类。我想使用其他的东西,只返回所需的对象。另外,我不知道如何使用流式API方法的hasNext()遍历数组以找到所需的对象
欢迎您的任何意见。谢谢。第三方库 如果在加载整个Json文档时没有资源/性能问题,我建议您提供类似Xpath的访问权限,以选择所需的匹配项 但是,我假设您希望流式传输Json数据,因为它会导致您实际测量/测试的实际问题。有人说我有一个好朋友,但我没有这方面的经验 这让我想到了你们可以使用的其他替代方案,我发现它似乎可以解决你们的问题 自己动手 我开始使用您最初的问题为您编写一段代码,但我发现自己必须在传输Json时创建每个Person类,这似乎是您试图避免的。如果您想坚持使用“滚动您自己的”方法,而不是我提到的第三方库,请告诉我
我用这篇文章来帮助我理解如何在流媒体传输时解析Json令牌。我不推荐流媒体API,使用它真的很痛苦。但是在您的情况下,如果您只想从一个数组中提取一个对象,这是可能的
JsonReader reader = new JsonReader(new StringReader(
"[ {Name: \"ABC\", \"email\" : \"abc@123.com\", \"city\" : \"NewYork\"}, {Name: \"XYZ\", \"email\" : \"xyz@123.com\", \"city\" : \"NewJersey\"}]\n"));
String target = "ABC";
ArrayList<String> names = new ArrayList<String>();
reader.setLenient(true);
reader.beginArray();
while(reader.hasNext()) {
reader.beginObject();
// peek is your best friend in this world, as it tells you what object you're looking at
while(reader.peek() != JsonToken.END_OBJECT) {
if(reader.peek() == JsonToken.NAME) {
String name = reader.nextName();
if(name.equals("Name")) {
if(reader.nextString().equals(target)) {
// I'm just printing these out right now but you could construct an object and set variables instead.
while(reader.peek() == JsonToken.NAME) {
switch (reader.nextName()) {
case "email":
System.out.println("Found email for " + target + " " + reader.nextString());
break;
case "city":
System.out.println("Found city for " + target + " " + reader.nextString());
break;
}
}
}
}
}
//this is really the key to the parser which is to skip all the values that you're not interested in
reader.skipValue();
}
reader.endObject();
}
reader.endArray();
}
JsonReader=newjsonreader(newstringreader(
[{姓名:\'ABC\',\'email\':\'abc@123.com\“,”城市\“:\”纽约\“},{姓名:\”XYZ\“,\”电子邮件\“:\”xyz@123.com\“,”城市“:\”新泽西“}]\n”);
字符串target=“ABC”;
ArrayList name=新的ArrayList();
读者:setLenient(真);
reader.beginArray();
while(reader.hasNext()){
reader.beginObject();
//peek是你在这个世界上最好的朋友,因为它告诉你你在看什么东西
while(reader.peek()!=JsonToken.END_对象){
if(reader.peek()==JsonToken.NAME){
字符串名称=reader.nextName();
如果(名称等于(“名称”)){
if(reader.nextString().equals(target)){
//我现在只是把它们打印出来,但是你可以构造一个对象并设置变量。
while(reader.peek()==JsonToken.NAME){
开关(reader.nextName()){
案例“电子邮件”:
System.out.println(“为“+target+”“+reader.nextString()找到电子邮件”);
打破
案例“城市”:
System.out.println(“为“+target+”“+reader.nextString()找到城市”);
打破
}
}
}
}
}
//这确实是解析器的关键所在,它将跳过所有您不感兴趣的值
reader.skipValue();
}
reader.endObject();
}
reader.endArray();
}
谢谢您的回答。我是Java和Json新手。我希望使用流式API的唯一原因是json文件可能最终拥有大量的测试数据集,并且我可能只需要其中的几行就可以执行当前的执行。所以我不想一次把它们全部收回。我的目标是获取所需的对象,并将其分配给类中JsonObject类型的公共变量,并使用此对象在另一个函数中使用这种语法检索值(email,city)——JsonObject.get(“email”).toString。那么,有没有可能从你的函数中只返回那个对象呢?只要从电子邮件案例中返回,就会返回你想要的东西,避免扫描任何你不需要的东西。另外,您可以避免切换,只需使用if(“email.equals(reader.nextName()){return reader.nextString();}如果我想在一个函数中获取电子邮件,在另一个函数中获取城市,我必须迭代读卡器并验证它是否匹配Name=“ABC”两次都是,对。我想的是通过迭代一次来返回数组中的元素作为JsonObject,然后使用get方法在其上检索值。看起来我们不能从这个函数中仅返回该对象,并且已经实现了流式API来逐令牌迭代令牌。可能我可以在匹配为fou时创建一个字典第一次使用nd,以后使用它来检索值。这就是我要做的,创建一个映射并读取所有条目,然后将其传递回调用方。如果不考虑性能,开销将是最小的JsonPath非常方便。谢谢您让我知道。