Java 在jsonpath中进行筛选时如何获取第一个元素?
因此,我正在研究以下json:Java 在jsonpath中进行筛选时如何获取第一个元素?,java,jsonpath,Java,Jsonpath,因此,我正在研究以下json: { "id": "", "owner": "some dude", "metaData": { "request": { "ref": null, "contacts":[ { "email": null, "name": null, "contactType": "R"
{
"id": "",
"owner": "some dude",
"metaData": {
"request": {
"ref": null,
"contacts":[
{
"email": null,
"name": null,
"contactType": "R"
},
{
"email": null,
"name": "Dante",
"contactType": "S"
}
]
}
}
}
我想检索联系人的姓名
,其类型为S
,并且只检索第一个返回的联系人
将jsonpath与此路径一起使用<代码>“$…contacts[?(@.contactType=='S')].name”始终返回字符串数组,因为筛选操作始终将结果作为数组返回
因此,我尝试了“$”联系人[?(@.contactType='S')].name[0]”和“”$…联系人[?(@.contactType='S')][0]。name“
,但运气不好。这些路径返回空结果
所以我的问题是,在jsonpath中使用过滤器时,有没有办法只获取第一个元素。我目前正在使用jayway jsonpath v2.2.0。如果您使用spring test中带有MockMvc类的jsonpath,那么您可以编写以下虚拟匹配器:
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.core.IsEqual;
import net.minidev.json.JSONArray;
public class FirstMatcher<T> extends BaseMatcher<T> {
private final Matcher<?> matcher;
public static <T> FirstMatcher<T> matcher(Matcher<T> matcher) {
return new FirstMatcher<T>(matcher);
}
public static FirstMatcher<Object> value(Object value) {
return new FirstMatcher<Object>(value);
}
public FirstMatcher(Matcher<T> matcher) {
this.matcher = matcher;
}
public FirstMatcher(Object value) {
this.matcher = new IsEqual<Object>(value);
}
@Override
public void describeTo(Description description) {
description.appendText("first matcher");
}
@Override
public boolean matches(Object item) {
if (!(item instanceof JSONArray)) {
return false;
}
JSONArray array = (JSONArray)item;
if (array.isEmpty()) {
return false;
}
Object obj = array.get(0);
return matcher.matches(obj);
}
}
另外,由于net.minidev.json.JSONArray是java.util.List的子类,因此可以强制转换为List甚至Iterable,而不是net.minidev.json.JSONArray.:) 我找到的最快解决方案只是将其与列表进行比较,因此在您的场景中如下所示:
.andExpect(jsonPath("$..contacts[?(@.contactType == 'S')].name", equalTo(Arrays.asList("Dante"))))
(当然,假设您正在尝试比较测试中的某些结果)从2.2.0开始,您不能这样做。见公开问题:
.andExpect(jsonPath("$..contacts[?(@.contactType == 'S')].name", equalTo(Arrays.asList("Dante"))))