控制JsonPath的read()方法返回的数据类型

Ada*_*dam 3 java jsonpath

我希望JsonPath始终将其解析为字符串的数据返回。但是,JsonPath read()方法的返回类型取决于要解析的数据类型,因为JsonPath总是猜测数据类型是什么,并返回该类型的结果。

问题是我无法知道将要返回哪种数据,因为我只能访问需要输入到read()函数中的一组路径。这意味着我必须将返回的JsonPath数据存储在Objects数组中,并使用包含instanceof关键字的if / else-if语句的丑陋集合来确定数据是什么(然后将其转换为适当的类型)。

有谁知道强制JsonPath返回字符串的方法?还是可以想到更好的解决方法?

这是我现在正在执行的操作(使用Java):

ArrayList<Object> realData = JsonPath.read(dataDumpFile, current.getPath());
Run Code Online (Sandbox Code Playgroud)

我想做的是:

ArrayList<String> realData = JsonPath.read(dataDumpFile, current.getPath());
Run Code Online (Sandbox Code Playgroud)

文档中,我发现了这一点:

在Java中使用JsonPath时,重要的是要知道您期望的结果类型。JsonPath将自动尝试将结果转换为调用者期望的类型。

//Will throw an java.lang.ClassCastException    
List<String> list = JsonPath.parse(json).read("$.store.book[0].author")

//Works fine
String author = JsonPath.parse(json).read("$.store.book[0].author")
Run Code Online (Sandbox Code Playgroud)

“调用者期望的类型”是什么意思?

app*_*lue 7

在JsonPath的典型用例中,该库假设我们知道从路径中可以获得什么

  • 路径是确定的吗?路径是:

    • 确定是否只有一个结果,例如$..book[0]第一本书。
    • 如果可能有多个结果,则不确定,例如$..book[?(@.isbn)]对于具有某些属性的所有书籍;返回类型可以是列表。
  • 结果应为哪种特定类型?例如,您可以期望返回类型为DateList<Date>代替ObjectList<Object>

在您的情况下,上述所有操作都不重要,因为您事先不知道类型,您只需要将结果作为JSON字符串即可。

JsonPath中的默认解析器过于智能,无法将所有内容都转换为漂亮的LinkedHashMap对象。但是,如果您使用JacksonJsonNodeJsonProvider则将得到的结果作为JsonNode对象,并且toString()与JSON字符串结果之间只有一个调用。

更好的是,您可以使用JsonPath 选项 ALWAYS_RETURN_LIST,这意味着您不必担心路径是确定的还是不确定的(无论结果是单个对象还是列表)。

// Example from https://github.com/jayway/JsonPath#path-examples
final String json = "{\"store\": {\"book\": [{\"category\": \"reference\",\"author\": \"Nigel Rees\",\"title\": \"Sayings of the Century\",\"price\": 8.95},{\"category\": \"fiction\",\"author\": \"Evelyn Waugh\",\"title\": \"Sword of Honour\",\"price\": 12.99},{\"category\": \"fiction\",\"author\": \"Herman Melville\",\"title\": \"Moby Dick\",\"isbn\": \"0-553-21311-3\",\"price\": 8.99},{\"category\": \"fiction\",\"author\": \"J. R. R. Tolkien\",\"title\": \"The Lord of the Rings\",\"isbn\": \"0-395-19395-8\",\"price\": 22.99}],\"bicycle\": {\"color\": \"red\",\"price\": 19.95}},\"expensive\": 10}";

Configuration conf = Configuration.builder().jsonProvider(new JacksonJsonNodeJsonProvider())
        .options(Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS).build();

ArrayNode node = JsonPath.using(conf).parse(json).read("$.store.book[*]"); // indefinite
for (Object o : node) {
    System.out.println(o.toString());
}
// {"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95}
// {"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}
// {"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}
// {"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}

node = JsonPath.using(conf).parse(json).read("$.store.book[0].author"); // definite
for (Object o : node) {
    System.out.println(o.toString());
}
// "Nigel Rees"
Run Code Online (Sandbox Code Playgroud)