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

huangapple go评论87阅读模式
英文:

How to deserialize objects with dynamic name

问题

以下是您要翻译的内容:

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

但是字段Time Series的名称是动态的,例如可以是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;

}
英文:

I'm want to deserialize the below JSON response into a Java object.

But the name of field Time Series is dynamic for e.g. it can be Time Series (5min), Time Series (1min), Time Series (15min) etc.

Is there any annotation or configuration that can help in deserializing the JSON into POJO irrespective of field name?

JSON Response:

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

POJO for JSON response:

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

    @JsonProperty(&quot;Meta Data&quot;)
    private Metadata metadata;

    private Map&lt;String, IntraDayData&gt; timeSeries;

}

答案1

得分: 0

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

}
英文:

Since metadata already contains the information about the interval, you could utilise JsonAlias - something like this.

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

    @JsonProperty(&quot;Meta Data&quot;)
    private Metadata metadata;
    @JsonAlias({ &quot;Time Series (5min)&quot;, &quot;Time Series (1min)&quot;, &quot;Time Series (15min)&quot; })
    private Map&lt;String, IntraDayData&gt; timeSeries;

}

答案2

得分: 0

我认为@JsonAnySetter适用于这种情况。基本上,被注解的字段(从版本2.8开始支持,如文档中所述)然后用作默认值来反序列化未知属性。请尝试这样做。

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

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

    @JsonAnySetter
    private Map<String, IntraDayData> timeSeries;

}
英文:

I believe @JsonAnySetter is suitable for this. Basically, the annotated field (support on field from version 2.8, as mentioned in doc) is then used as a default to deserialize unknown properties. Please try this.

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

    @JsonProperty(&quot;Meta Data&quot;)
    private Metadata metadata;

    @JsonAnySetter
    private Map&lt;String, IntraDayData&gt; timeSeries;

}

答案3

得分: 0

问题通过创建一个带有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)"的值。
对象值将包含内容。

英文:

The issue got resolved by creating a setter method with String key and Object value as argument and annotating it with @JsonAnySetter.

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

    @JsonProperty(&quot;Meta Data&quot;)
    private Metadata metadata;

    private Map&lt;String, IntraDayData&gt; timeSeries = new HashMap&lt;&gt;();

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

String key would have values like: &quot;Time Series (5min)&quot;, &quot;Time Series (1min)&quot;, &quot;Time Series (15min)&quot;
Object value will have the content.

huangapple
  • 本文由 发表于 2020年10月12日 05:16:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64309074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定