考慮到您提供的JSON並閱讀了Jayway JsonPath的文檔。我發現了兩個解決方案可以幫助解決您的問題。
- 解決方案1,您可以直接訪問ERRORMSG領域,但不是applicbable當有一個以上的公司,你必須手動循環
- 方案2允許自定義謂詞是特定於您的情況下建設並且有點通用。
解決方案1 您已經似乎是正確的,如下圖所示的過濾器:
Filter responseFilter = Filter.filter(Criteria.where("errorMsg").is("INACTIVE"));
尋找到您的JSON,有效載荷可以被認爲是出發點和結構似乎被固定的第二個值陣列是失敗的公司,這就是你感興趣的,因此,我會寫如下的json路徑:
Map<String, Object> inactiveFailedCompany =
parse(json).read("$.payload[1].['Failed company(ies)'][1]", responseFilter);
如果你注意到上面,我已經指定payload[1]
,我假設你的JSON是如何構造的。我還指定了['Failed company(ies)'][1]
,即訪問擁有INACTIVE
的公司。你可以明顯地通過['Failed company(ies)'][1]
指數使用與循環這個解決方案中循環,並打印ID如下:
System.out.println("Company Object > " + inactiveFailedCompany.toString());
//output: Output > {id=COM002FILE, index=NA, errorMsg=[["INACTIVE"],["INVALID_LOCATION","INACTIVE"]]}
System.out.println("Company ID > " + inactiveFailedCompany.get("id"));
//output: COM002FILE
綜觀上述方案,我覺得不好,因爲它不夠好,所以我讀更多該文件,並遇到了Roll your own predicate因此解決方案2。
解決方案2
如文檔中解釋,我量身定做的謂詞的apply
方法,以滿足您的要求和解決方案如下:
Predicate inactiveCompaniesPredicate = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
if(ctx.item(Map.class).containsKey("errorMsg") &&
((JSONArray)((JSONArray) ctx.item(Map.class).get("errorMsg")).get(0)).get(0).equals("INACTIVE")) {
return true;
} else {
return false;
}
}
};
現在使用上述謂詞如下:
List<Map<String, Object>> failedCompanies =
parse(json).read("$.payload[1].['Failed company(ies)'][?]", List.class, inactiveCompaniesPredicate);
然後遍歷公司列表並打印f的ID ailed公司如下:
for(Map<String, Object> object: failedCompanies) {
System.out.println(object.get("id"));
//output: COM002FILE
}
我想反思嚇人如果斷言如下內部條件:
左如果條件的部分 - XX
這部分過濾所有那些包含errorMsg字段。如果條件的
if(ctx.item(Map.class).containsKey("errorMsg") && yy)
右邊部分 - YY
這部分可以確保errorMsg
是INACTIVE
if(xx & ((JSONArray)((JSONArray) ctx.item(Map.class).get("errorMsg")).get(0)).get(0).equals("INACTIVE"))
這裏是我用來測試示例代碼(我進口Jsonpath 2.1和它的依賴作爲外部罐子到我的日食)
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import net.minidev.json.JSONArray;
import com.jayway.jsonpath.Predicate;
import static com.jayway.jsonpath.JsonPath.parse;
public class JaywayJSON {
public static void main(String[] args) throws IOException {
String json = readFile("C:\\test_stackoverflow\\jayway.json",
Charset.defaultCharset());
/*
* //Solution 1
*
* Filter responseFilter =
* Filter.filter(Criteria.where("errorMsg").is("INACTIVE"));
*
* Map<String, Object> inactiveFailedCompany =
* parse(json).read("$.payload[1].['Failed company(ies)'][1]",
* responseFilter);
*
* System.out.println("Company Object > " +
* inactiveFailedCompany.toString()); //output: Output > {id=COM002FILE,
* index=NA, errorMsg=[["INACTIVE"],["INVALID_LOCATION","INACTIVE"]]}
*
* System.out.println("Company ID > " +
* inactiveFailedCompany.get("id")); //output: COM002FILE
*/
// solution 2
Predicate inactiveCompaniesPredicate = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
if (ctx.item(Map.class).containsKey("errorMsg")
&& ((JSONArray) ((JSONArray) ctx.item(Map.class).get(
"errorMsg")).get(0)).get(0).equals("INACTIVE")) {
return true;
} else {
return false;
}
}
};
List<Map<String, Object>> failedCompanies = parse(json).read(
"$.payload[1].['Failed company(ies)'][?]", List.class,
inactiveCompaniesPredicate);
for (Map<String, Object> object : failedCompanies) {
System.out.println(object.get("id"));
}
}
public static String readFile(String path, Charset encoding)
throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
errorMsg是一個數組數組,因此您應該驗證它是否包含包含文本的項目以及包含文本的項目「INACTIVE」 – andrucz
errorMsg爲INACTIVE時,JSON的預期結果是什麼?它應該返回哪個json部分? – Raf
@Raf它應該只返回Ids。 –