关于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节点和dataList<SomeData>对象,例如:

@JsonIgnoreProperties(ignoreUnknown = true)
public class SomeDataWrapper  {

    @JsonProperty("data")
    private List<SomeData> data;

    public List<SomeData> getData() {
        return data;
    }
}


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

在此先感谢您的帮助!

编辑1:

我想全局配置ObjectMapper以查找data节点。我正在使用Spring RestTemplate,它在调用例如时处理下面的反序列化restTemplate.exchange(..)方法。因此,我想将其委托给Spring,不想使用JsonNode /遍历响应数据来手动解析每个端点响应。

编辑2:
我知道我可以使用jackson的@Bean定义Module并注册自定义反序列化器,但是同样,我需要为每个POJO定义一个新的反序列化器类。这将是一个巨大的痛苦和样板

最佳答案

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

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


然后将JsonNode映射到具有SomeDataObjectMapper.treeToValue(TreeNode, Class)数组:

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

关于java - 全局配置ObjectMapper(通过@Bean或smth)以从“数据”节点进行解析,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51865995/

10-12 03:39