Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用流API和JSON解析器进行JSON解析-混合模式_Java_Json - Fatal编程技术网

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非常方便。谢谢您让我知道。