全局配置ObjectMapper(通过@Bean或smth)以从“数据”节点进行解析

时间:2018-08-15 20:31:38

标签: java json jackson mapper

关于SO和其他资源的杰克逊问题已经成千上万,我已经花了几个小时进行搜索,但仍然无法弄清。

我正在尝试使用REST Web服务,它以通常的单个对象json格式返回信息,例如:

{
  "data" : { SomeData },
  "meta: : {MetaInfo}
}

或带有数组:

{
  "data" : [ {SomeData}, {SomeData} ],
  "meta: : {MetaInfo}
}

SomeData是一些POJO类,我需要对其进行解析。服务中有数十种不同的POJO类。我暂时不关心MetaInfo,但是我想解决我的问题的方法也将有助于解决它。

我想为每个SomeData类型使用一个POJO类来处理单个对象和数组的响应。问题出在我应该从哪个data节点开始解析。

问题:是否可以全局配置我的ObjectMapper以仅解析来自data节点的信息?

所以,我想要这样的东西:

SomeData data = new ObjectMapper().fromNode("data").readValue(inputString, SomeData.class);

或带有数组:

List<SomeData> listData = new ObjectMapper().fromNode("data").readValue(inputString, new TypeReference<List<SomeData>>() {});

当然有一种解决方法-使用包含wrapper节点和data的{​​{1}}对象,例如:

List<SomeData>

但这是我的开销。因此,从包装器类中取出这些列表,我基本上应该有两倍于所需类的类+开销。

在此先感谢您的帮助!

EDIT1:

我想全局配置@JsonIgnoreProperties(ignoreUnknown = true) public class SomeDataWrapper { @JsonProperty("data") private List<SomeData> data; public List<SomeData> getData() { return data; } } 来寻找ObjectMapper节点。我正在使用Spring data,它在调用时处理下面的反序列化。 RestTemplate方法。因此,我想将其委托给Spring,不想使用JsonNode /遍历响应数据来手动解析每个端点响应。

EDIT2: 我知道我可以用jackson的restTemplate.exchange(..)定义一个@Bean并注册自定义解串器,但是同样,我需要为每个POJO定义一个新的解串器类。这将是一个巨大的痛苦和样板

2 个答案:

答案 0 :(得分:1)

使用TreeNode将JSON反序列化为ObjectMapper.readTree(String),然后选择要映射的路径,例如:

JsonNode node = new ObjectMapper().readTree(inputString)
                                  .path("data");

然后使用JsonNodeSomeData映射到ObjectMapper.treeToValue(TreeNode, Class)数组:

 SomeData[] data = jsonObjectMapper.treeToValue(node, SomeData[].class);

答案 1 :(得分:0)

如果您要使用相同的确切属性名称actionObjectOrderAddAfter来包含多个不同的 TYPES 数据(对象|数组),我不知道有什么可能。

我建议在API提供者方面这是一个非常糟糕的设计选择,如果您有能力更改它,将其更改为ALWAYS则会返回一个列表,其大小可能为Hook::exec('actionObject'.get_class($this).'AddAfter', array('object' => $this)); 理想。

除此之外,我不知道有什么办法告诉data 1的类型是或者 ObjectMapper 还是 data