如何反序列化具有动态名称的对象

How to deserialize objects with dynamic name

我想将下面的 JSON 响应反序列化为 Java 对象。

但是字段名称 时间序列 是动态的,例如它可以是 Time Series (5min)Time Series (1min)Time Series (15min)

是否有任何注释或配置可以帮助将 JSON 反序列化为 POJO,而不考虑字段名称?

JSON 响应:

{
  "Meta Data": {
    "1. Information": "Intraday (5min) open, high, low, close prices and volume",
    "2. Symbol": "IBM",
    "3. Last Refreshed": "2020-10-09 19:55:00",
    "4. Interval": "5min",
    "5. Output Size": "Compact",
    "6. Time Zone": "US/Eastern"
  },
  "Time Series (5min)": {
    "2020-10-09 19:55:00": {
      "1. open": "127.7500",
      "2. high": "127.7500",
      "3. low": "127.7000",
      "4. close": "127.7000",
      "5. volume": "405"
    },
    "2020-10-09 19:45:00": {
      "1. open": "127.7600",
      "2. high": "127.7600",
      "3. low": "127.7600",
      "4. close": "127.7600",
      "5. volume": "200"
    }
  }
}

JSON 的 POJO 响应:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class IntraDayResponse {

    @JsonProperty("Meta Data")
    private Metadata metadata;

    private Map<String, IntraDayData> timeSeries;

}

由于元数据已经包含了有关间隔的信息,您可以使用 JsonAlias - 像这样。

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class IntraDayResponse {

    @JsonProperty("Meta Data")
    private Metadata metadata;
    @JsonAlias({ "Time Series (5min)", "Time Series (1min)", "Time Series (15min)" })
    private Map<String, IntraDayData> timeSeries;

}

我认为@JsonAnySetter适合这个。基本上,带注释的字段(支持 2.8 版的字段,如文档中所述)然后用作默认值来反序列化未知属性。请试试这个。

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class IntraDayResponse {

    @JsonProperty("Meta Data")
    private Metadata metadata;

    @JsonAnySetter
    private Map<String, IntraDayData> timeSeries;

}

通过使用 String 键和 Object 值作为参数创建 setter 方法并使用 @JsonAnySetter.

对其进行注释,问题得以解决
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class IntraDayResponse {

    @JsonProperty("Meta Data")
    private Metadata metadata;

    private Map<String, IntraDayData> timeSeries = new HashMap<>();

    @JsonAnySetter
    public void setTimeSeries(String key, Object value) {
        this.timeSeries = (Map<String, IntraDayData>) value;
    }
}

字符串键的值如下:"Time Series (5min)", "Time Series (1min)", "Time Series (15min)" 对象值将具有内容。