我一直在使用JsonPath
。但是,在昨天的一个问题中,我发现默认的JsonSmartJsonProvider
在解析时没有报告无效文档的错误,我修改了设置以使用Jackson,如下所示:
public JsonPathExtractor(String document) throws DocumentFormatException
{
try
{
Configuration.setDefaults(new Configuration.Defaults()
{
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();
@Override
public JsonProvider jsonProvider()
{
return jsonProvider;
}
@Override
public MappingProvider mappingProvider()
{
return mappingProvider;
}
@Override
public Set<Option> options()
{
return EnumSet.noneOf(Option.class);
}
});
// Get an object representation of the JSON to allow values to be extracted
this.document = Configuration.defaultConfiguration().jsonProvider().parse(document);
}
catch(Exception e)
{
throw new DocumentFormatException("Invalid JSON document", e);
}
}
但是,我发现行为有所不同,因为如果我得到的路径中包含几个字段,则在使用JsonSmartJsonProvider
时它们不会被引用。
JSON示例
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"height_cm": 167.6,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}
拨打电话:
Object obj = JsonPath.read(document, "$.phoneNumbers");
使用JacksonMappingProvider
时我得到
[{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
使用JsonSmartJsonProvider
时,我得到:
[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
如果我希望Jackson表现相同,是否还有其他可以配置的内容?
答案 0 :(得分:0)
Jackson处理值的方式与打印它们的方式之间是有区别的。
使用JsonSmartJsonProvider
时,此行...
JsonPath.read(parse, "$.phoneNumbers");
...返回一个JSONArray
和一个toString()
方法-当您“打印” JSONArray
实例时足够聪明,以至于知道它正在处理JSON,因此可以打印该状态为JSON字符串。例如:
[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
但是当您使用JacksonJsonProvider
时,此行...
JsonPath.read(parse, "$.phoneNumbers");
...返回List
中的LinkedHashMap
,并在您“打印”该实例不支持JSON时调用toString()
实现,因此它会打印以下内容:
[{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
如果要在使用JacksonJsonProvider
时打印JSON,则必须使用支持JSON的内容进行打印。这是一个示例:
String payload = "{\n" +
" \"firstName\": \"John\",\n" +
" \"lastName\": \"Smith\",\n" +
" \"isAlive\": true,\n" +
" \"age\": 25,\n" +
" \"height_cm\": 167.6,\n" +
" \"address\": {\n" +
" \"streetAddress\": \"21 2nd Street\",\n" +
" \"city\": \"New York\",\n" +
" \"state\": \"NY\",\n" +
" \"postalCode\": \"10021-3100\"\n" +
" },\n" +
" \"phoneNumbers\": [\n" +
" {\n" +
" \"type\": \"home\",\n" +
" \"number\": \"212 555-1234\"\n" +
" },\n" +
" {\n" +
" \"type\": \"office\",\n" +
" \"number\": \"646 555-4567\"\n" +
" }\n" +
" ],\n" +
" \"children\": [],\n" +
" \"spouse\": null\n" +
"}";
// this is a simpler way of declaring and using the JacksonJsonProvider
ObjectMapper objectMapper = new ObjectMapper();
Configuration conf = Configuration.builder()
.jsonProvider(new JacksonJsonProvider(objectMapper))
.build();
Object obj = JsonPath.using(conf).parse(payload).read("$.phoneNumbers");
// prints out:
// [{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
System.out.println(obj);
// prints out:
// [{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
System.out.println(objectMapper.writer().writeValueAsString(obj));