Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.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 使用JSONpath验证是否存在根节点数组_Java_Json_Rest_Hamcrest - Fatal编程技术网

Java 使用JSONpath验证是否存在根节点数组

Java 使用JSONpath验证是否存在根节点数组,java,json,rest,hamcrest,Java,Json,Rest,Hamcrest,从下面的JSON响应中,我可以使用hamcrest库中的此方法验证JSONpath中是否存在根节点: assertThat(json, hasJsonPath("$.tool")); 这将检查名为“tool”的根节点是否存在 { "tool": { "jsonpath": { "creator": { "name": "Jayway Inc.",

从下面的JSON响应中,我可以使用hamcrest库中的此方法验证JSONpath中是否存在根节点:

assertThat(json, hasJsonPath("$.tool"));
这将检查名为“tool”的根节点是否存在

{
    "tool": 
    {
        "jsonpath": 
        {
            "creator": 
            {
                "name": "Jayway Inc.",
                "location": 
                [
                    "Malmo",
                    "San Francisco",
                    "Helsingborg"
                ]
            }
        }
    },

    "book": 
    [
        {
            "title": "Beginning JSON",
            "price": 49.99
        },

        {
            "title": "JSON at Work",
            "price": 29.99
        }
    ]
}
如果我想使用存储在变量中的数组检查两个根节点(tool和book)的存在性,如何实现这一点?我不关心它们的值或子节点的值。我只想验证这两个根节点是否存在于响应中,并且是有效的路径

在将API响应串接在“json”变量中之后,我尝试了以下方法:

JsonPath jp = new JsonPath(json);

String[] rootNodes = {"tool", "book"};
assertThat(json, hasJsonPath(json.getString(rootNodes)));
但编译器对
getString
方法不满意


有没有解决此问题的方法?

根节点操作符是
$
,因此您可以将
$
读入映射,映射将键入您的根节点名称

例如:

// Approach 1
Map<String, Object> read = JsonPath.read(json, "$");

assertThat(read.size(), is(2));

assertThat(read.keySet(), hasItem("tool"));
assertThat(read.keySet(), hasItem("book"));

// Approach 2: if you want a String[] then ...
String[] rootNodeNames = read.keySet().toArray(new String[read.size()]);
assertThat(rootNodeNames, Matchers.both(arrayWithSize(2)).and(arrayContainingInAnyOrder("book", "tool")));

// Approach 3: if you want to hide it all behind the hasJsonPath() matcher
// note: each of these assertion will cause your JSON string to be parsed 
// so it's more efficient to do that once and assert against the 
// resulting map as I did above
assertThat(json, hasJsonPath("$", Matchers.hasKey("tool")));
assertThat(json, hasJsonPath("$", Matchers.hasKey("book")));
//方法1
Map read=JsonPath.read(json,“$”);
断言(read.size(),为(2));
资产(read.keySet(),hasItem(“工具”);
资产(read.keySet(),hasItem(“book”);
//方法2:如果你想要一个字符串[],那么。。。
String[]rootNodeNames=read.keySet().toArray(新字符串[read.size()]);
断言(rootNodeNames、Matchers.两者(arrayWithSize(2))和(arrayContaininganyOrder(“book”、“tool”)));
//方法3:如果您想将其全部隐藏在hasJsonPath()匹配器后面
//注意:这些断言中的每一个都会导致JSON字符串被解析
//因此,只做一次,然后对
//结果图如我上面所做
资产(json,hasJsonPath(“$”,Matchers.hasKey(“工具”));
资产(json,hasJsonPath(“$”,Matchers.hasKey(“book”));

我将$打印到控制台,可以看到根节点的值也被返回。我希望只提取根节点,而不提取它们的值,使用某种数组方法。顺便问一下,哪个库会将“is”方法添加到项目中?如果这里的目的是验证有两个根节点,并且这些根节点的名称是:“tool”和“book”,那么上面的代码就是这样做的。您无需将根节点名称提取到字符串[]中即可做出该断言。您的另一个问题是:
的完全限定路径是
is
org.hamcrest.Matchers
,也就是说,它是由与
hasItem
相同的类提供的。我已经更新了这个问题,它显示了如何将根节点名称提取到
字符串[]
并展示如何将整个匹配器隐藏在一个
hasJsonPath
调用中。太棒了,@glytching。在我将正确的hamcrest类添加到您的代码片段之后,我开始看到一些有趣的结果。我现在可以看到根节点的提取,而不需要它们的值。如果我想验证根节点是否为null或空,而不实际提取它们的值,那么这可以实现吗?无论执行什么断言,都是从解析JSON开始的,这会导致节点名称和值被反序列化。您不能仅反序列化节点名称,因为
JsonPath
将始终反序列化整个JSON字符串。我认为您应该专注于您的断言,而不必担心JsonPath是否也(从您的角度来看)反序列化了这些值。上面的答案向您展示了三种针对根节点进行断言的方法,并且完全忽略了这些值。