【问题标题】:How to deserialize objects with dynamic name如何反序列化具有动态名称的对象
【发布时间】:2020-10-11 21:16:32
【问题描述】:

我想将下面的 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;

}

【问题讨论】:

    标签: java json jackson deserialization


    【解决方案1】:

    由于元数据已经包含有关间隔的信息,您可以使用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;
    
    }
    

    【讨论】:

    • 为了解释的目的,我给出了 3 个值。实际上,timeseries 不限于这 3 个值,它可以是任何 "Time Series (XYZmin)" 我猜在 JsonAlias 中不能给出所有可能的名称。您能否详细说明我们如何使用元数据?
    • 元数据有区间字段,可以告诉你持续时间。另外,你是对的。您可以将值限制为 3 个值。在这种情况下,您可以使用自定义反序列化程序来容纳通配符字段名称。希望这会有所帮助:)
    【解决方案2】:

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

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class IntraDayResponse {
    
        @JsonProperty("Meta Data")
        private Metadata metadata;
    
        @JsonAnySetter
        private Map<String, IntraDayData> timeSeries;
    
    }
    

    【讨论】:

    • 在字段上注释 @JsonAnySetter 并不能解决问题,仍然得到相同的响应。但是,谢谢你的建议,我想出了答案。
    【解决方案3】:

    通过使用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)" 对象值会有内容。

    【讨论】:

      猜你喜欢
      • 2014-08-26
      • 2018-03-24
      • 2014-09-06
      相关资源
      最近更新 更多