gpt4 book ai didi

java - 使用 Spring Boot RestTemplate 解析嵌套元素会出现 JSON 解析错误

转载 作者:行者123 更新时间:2023-12-02 12:07:25 25 4
gpt4 key购买 nike

我想使用一个提供以下输出的 REST 接口(interface)(准确地说,我想检索 TAF 元素列表):

<?xml version="1.0" encoding="UTF-8"?>
<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML-Schema-instance" version="1.2" xsi:noNamespaceSchemaLocation="http://aviationweather.gov/adds/schema/taf1_2.xsd">
<request_index>32084191</request_index>
<data_source name="tafs" />
<request type="retrieve" />
<errors />
<warnings />
<time_taken_ms>13</time_taken_ms>
<data num_results="4">
<TAF>
<raw_text>TAF EPGD 171130Z 1712/1812 25008KT CAVOK PROB40 1718/1806 1500 BR BKN005</raw_text>
<station_id>EPGD</station_id>
<issue_time>2017-10-17T11:30:00Z</issue_time>
<bulletin_time>2017-10-17T11:00:00Z</bulletin_time>
<valid_time_from>2017-10-17T12:00:00Z</valid_time_from>
<valid_time_to>2017-10-18T12:00:00Z</valid_time_to>
<latitude>54.37</latitude>
<longitude>18.47</longitude>
<elevation_m>138.0</elevation_m>
<forecast>
<fcst_time_from>2017-10-17T12:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-18T12:00:00Z</fcst_time_to>
<wind_dir_degrees>250</wind_dir_degrees>
<wind_speed_kt>8</wind_speed_kt>
<visibility_statute_mi>6.21</visibility_statute_mi>
<wx_string>NSW</wx_string>
<sky_condition sky_cover="NSC" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T18:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-18T06:00:00Z</fcst_time_to>
<change_indicator>PROB</change_indicator>
<probability>40</probability>
<visibility_statute_mi>0.93</visibility_statute_mi>
<wx_string>BR</wx_string>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="500" />
</forecast>
</TAF>
<TAF>
<raw_text>TAF EPGD 170530Z 1706/1806 22010KT 0300 FG BKN002 BECMG 1707/1709 CAVOK</raw_text>
<station_id>EPGD</station_id>
<issue_time>2017-10-17T05:30:00Z</issue_time>
<bulletin_time>2017-10-17T05:00:00Z</bulletin_time>
<valid_time_from>2017-10-17T06:00:00Z</valid_time_from>
<valid_time_to>2017-10-18T06:00:00Z</valid_time_to>
<latitude>54.37</latitude>
<longitude>18.47</longitude>
<elevation_m>138.0</elevation_m>
<forecast>
<fcst_time_from>2017-10-17T06:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T07:00:00Z</fcst_time_to>
<wind_dir_degrees>220</wind_dir_degrees>
<wind_speed_kt>10</wind_speed_kt>
<visibility_statute_mi>0.19</visibility_statute_mi>
<wx_string>FG</wx_string>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="200" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T07:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-18T06:00:00Z</fcst_time_to>
<change_indicator>BECMG</change_indicator>
<time_becoming>2017-10-17T09:00:00Z</time_becoming>
<wind_dir_degrees>220</wind_dir_degrees>
<wind_speed_kt>10</wind_speed_kt>
<visibility_statute_mi>6.21</visibility_statute_mi>
<wx_string>NSW</wx_string>
<sky_condition sky_cover="NSC" />
</forecast>
</TAF>
<TAF>
<raw_text>TAF EPGD 162330Z 1700/1724 24006KT 7000 SCT012 TEMPO 1700/1708 BKN005 PROB40 1702/1707 1000 BR OVC002</raw_text>
<station_id>EPGD</station_id>
<issue_time>2017-10-16T23:30:00Z</issue_time>
<bulletin_time>2017-10-16T23:00:00Z</bulletin_time>
<valid_time_from>2017-10-17T00:00:00Z</valid_time_from>
<valid_time_to>2017-10-18T00:00:00Z</valid_time_to>
<latitude>54.37</latitude>
<longitude>18.47</longitude>
<elevation_m>138.0</elevation_m>
<forecast>
<fcst_time_from>2017-10-17T00:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T08:00:00Z</fcst_time_to>
<change_indicator>TEMPO</change_indicator>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="500" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T00:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-18T00:00:00Z</fcst_time_to>
<wind_dir_degrees>240</wind_dir_degrees>
<wind_speed_kt>6</wind_speed_kt>
<visibility_statute_mi>4.35</visibility_statute_mi>
<sky_condition sky_cover="SCT" cloud_base_ft_agl="1200" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T02:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T07:00:00Z</fcst_time_to>
<change_indicator>PROB</change_indicator>
<probability>40</probability>
<visibility_statute_mi>0.62</visibility_statute_mi>
<wx_string>BR</wx_string>
<sky_condition sky_cover="OVC" cloud_base_ft_agl="200" />
</forecast>
</TAF>
<TAF>
<raw_text>TAF EPGD 161730Z 1618/1718 24006KT CAVOK BECMG 1618/1620 BKN013 TEMPO 1621/1708 BKN005 PROB40 1700/1707 2000 BR OVC002 BECMG 1709/1711 SCT030</raw_text>
<station_id>EPGD</station_id>
<issue_time>2017-10-16T17:30:00Z</issue_time>
<bulletin_time>2017-10-16T17:00:00Z</bulletin_time>
<valid_time_from>2017-10-16T18:00:00Z</valid_time_from>
<valid_time_to>2017-10-17T18:00:00Z</valid_time_to>
<latitude>54.37</latitude>
<longitude>18.47</longitude>
<elevation_m>138.0</elevation_m>
<forecast>
<fcst_time_from>2017-10-16T18:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T18:00:00Z</fcst_time_to>
<wind_dir_degrees>240</wind_dir_degrees>
<wind_speed_kt>6</wind_speed_kt>
<visibility_statute_mi>6.21</visibility_statute_mi>
<wx_string>NSW</wx_string>
<sky_condition sky_cover="NSC" />
</forecast>
<forecast>
<fcst_time_from>2017-10-16T18:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T09:00:00Z</fcst_time_to>
<change_indicator>BECMG</change_indicator>
<time_becoming>2017-10-16T20:00:00Z</time_becoming>
<wind_dir_degrees>240</wind_dir_degrees>
<wind_speed_kt>6</wind_speed_kt>
<visibility_statute_mi>6.21</visibility_statute_mi>
<wx_string>NSW</wx_string>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="1300" />
</forecast>
<forecast>
<fcst_time_from>2017-10-16T21:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T08:00:00Z</fcst_time_to>
<change_indicator>TEMPO</change_indicator>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="500" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T00:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T07:00:00Z</fcst_time_to>
<change_indicator>PROB</change_indicator>
<probability>40</probability>
<visibility_statute_mi>1.24</visibility_statute_mi>
<wx_string>BR</wx_string>
<sky_condition sky_cover="OVC" cloud_base_ft_agl="200" />
</forecast>
<forecast>
<fcst_time_from>2017-10-17T09:00:00Z</fcst_time_from>
<fcst_time_to>2017-10-17T18:00:00Z</fcst_time_to>
<change_indicator>BECMG</change_indicator>
<time_becoming>2017-10-17T11:00:00Z</time_becoming>
<wind_dir_degrees>240</wind_dir_degrees>
<wind_speed_kt>6</wind_speed_kt>
<visibility_statute_mi>6.21</visibility_statute_mi>
<wx_string>NSW</wx_string>
<sky_condition sky_cover="SCT" cloud_base_ft_agl="3000" />
</forecast>
</TAF>
</data>
</response>

我的 POJO 类如下所示:

@XmlRootElement(name = "response")
public class Response {
@XmlElement private List<Taf> data; // I don't need any other contents of this element

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

public void setData(List<Taf> data) {
this.data = data;
}
}

@XmlRootElement(name = "TAF")
public class Taf {
@XmlElement(name = "raw_text") private String raw_text;
@XmlElement(name = "station_id") private String station_id; // ICAO
@XmlElement(name = "issue_time") private Date issue_time;
@XmlElement(name = "bulletin_time") private Date bulletin_time;
@XmlElement(name = "valid_time_from") private Date valid_time_from;
@XmlElement(name = "valid_time_to") private Date valid_time_to;
@XmlElement(name = "remarks") private String remarks;
@XmlElement(name = "latitude") private Double latitude;
@XmlElement(name = "longitude") private Double longitude;
@XmlElement(name = "elevation_m") private Double elevation_m;
@XmlElement(name = "forecast", type = Forecast.class) private List<Forecast> forecast;
// getters and setters
}

@XmlRootElement(name = "forecast")
public class Forecast {
@XmlElement(name = "fcst_time_from") private Date fcst_time_from;
@XmlElement(name = "fcst_time_to") private Date fcst_time_to;
@XmlElement(name = "wind_dir_degrees") private Integer wind_dir_degrees;
@XmlElement(name = "wind_speed_kt") private Integer wind_speed_kt;
@XmlElement(name = "visibility_statute_mi") private Double visibility_statute_mi;
@XmlElement(name = "wx_string") private String wx_string;
@XmlElement(name = "sky_condition", type = SkyCondition.class) private List<SkyCondition> sky_condition;
// getters and setters
}

@XmlRootElement(name = "sky_condition")
public class SkyCondition {
@XmlAttribute(name = "sky_cover") private String sky_cover;
@XmlAttribute(name = "cloud_base_ft_agl") private Integer cloud_base_ft_agl;
// getters and setters
}

现在我的服务有一个简单的方法:

public List<Taf> getTafsForICAO(String icao) {
RestTemplate restTemplate = new RestTemplate();

Response resp = restTemplate.getForObject(tafUrl+icao, Response.class);
return resp.getData();
}

如果我忽略嵌套的 forecast 元素,则所有内容都会正确解析。但我需要这些嵌套元素,如果我按原样运行所有内容,则会出现以下异常:

Failed to read HTTP message:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error:
Can not construct instance of airports.models.taf.Forecast:
no String-argument constructor/factory method to deserialize from String value ('2017-10-17T12:00:00Z'); nested exception is
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of airports.models.taf.Forecast: no String-argument constructor/factory method to deserialize from String value ('2017-10-17T12:00:00Z')
at [Source: java.io.PushbackInputStream@4c723aba; line: 21, column: 45] (through reference chain: airports.models.taf.Response["data"]->java.util.ArrayList[0]->airports.models.taf.Taf["forecast"]->java.util.ArrayList[0])

看起来解析器看到了 forecast 的第一个子元素,即 fcst_time_from 获取了其内容并尝试将日期反序列化为 Forecast目的。我不知道为什么。也许我错过了一些简单的事情?预先感谢您的帮助。

更新

我离问题更近了一点。嵌套的 TAF 元素在 response 元素内正确解析,因为它们包装在 data 元素中。不幸的是,TAF 内没有用于forecast 标记列表的包装元素。我为 Forecast 类创建了一个带有 String 参数的构造函数,现在它将嵌入元素(fcst_time_from、fcst_time_to 等)解析为 Forecast 对象。有没有办法声明这个内部列表没有包装元素?

更新2

经过一些测试,我发现问题与解析未包装的元素列表严格相关。我不知道为什么,但如果我像这样声明我的 Result 类,而不是上面显示的声明:

@XmlRootElement(name = "response")
public class Response {
@XmlElementWrapper(name = "data")
@XmlElement(name = "TAF")
private List<Taf> tafs;

public List<Taf> getTafs() {
return tafs;
}

public void setTafs(List<Taf> tafs) {
this.tafs = tafs;
}
}

它不起作用。不解析任何 TAF 元素。解析器似乎强制所有列表都被包装。不幸的是,我在 REST 输出中得到了未包装的预测列表。我该如何处理这个问题?我看到了 @Element(inline = true) 注释的参数,但是 @XmlElement 没有这样的东西。我可以以某种方式强制在 RestTemplate 本身中展开列表吗?

最佳答案

天啊

经过两天的努力才发现我需要一条线来解决这个问题。所以...从解析器的角度来看,所有这些 @XmlElement 注释似乎都是无用的。仅当我想将对象作为 REST 服务输出时才使用它们。为了告诉解析器任何信息,我需要使用 @JacksonXmlElementWrapper 注释。具体解决办法是:

@XmlRootElement(name = "TAF")
public class Taf {
@XmlElement(name = "raw_text") private String raw_text;
@XmlElement(name = "station_id") private String station_id; // ICAO
@XmlElement(name = "issue_time") private Date issue_time;
@XmlElement(name = "bulletin_time") private Date bulletin_time;
@XmlElement(name = "valid_time_from") private Date valid_time_from;
@XmlElement(name = "valid_time_to") private Date valid_time_to;
@XmlElement(name = "remarks") private String remarks;
@XmlElement(name = "latitude") private Double latitude;
@XmlElement(name = "longitude") private Double longitude;
@XmlElement(name = "elevation_m") private Double elevation_m;
@JacksonXmlElementWrapper(useWrapping = false)
@XmlElement(name = "forecast") private List<Forecast> forecast;
// getters and setters
}

@XmlRootElement(name = "forecast")
public class Forecast {
@XmlElement(name = "fcst_time_from") private Date fcst_time_from;
@XmlElement(name = "fcst_time_to") private Date fcst_time_to;
@XmlElement(name = "wind_dir_degrees") private Integer wind_dir_degrees;
@XmlElement(name = "wind_speed_kt") private Integer wind_speed_kt;
@XmlElement(name = "visibility_statute_mi") private Double visibility_statute_mi;
@XmlElement(name = "ex_string") private String wx_string;
@JacksonXmlElementWrapper(useWrapping = false)
@XmlElement(name = "sky_condition") private List<SkyCondition> sky_condition;
// getters and setters
}

就是这样。

关于java - 使用 Spring Boot RestTemplate 解析嵌套元素会出现 JSON 解析错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46794118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com