Java 使用SpringBootRestTemplate解析嵌套元素会导致JSON解析错误
我想使用一个REST接口,该接口提供以下输出(确切地说,我想检索TAF元素的列表): 看起来解析器看到了Java 使用SpringBootRestTemplate解析嵌套元素会导致JSON解析错误,java,xml,spring,rest,Java,Xml,Spring,Rest,我想使用一个REST接口,该接口提供以下输出(确切地说,我想检索TAF元素的列表): 看起来解析器看到了forecast的第一个子元素,它是中的fcst\u time\u,它获取了它的内容并试图将日期反序列化为forecast对象。我不知道为什么。也许我错过了一些简单的事情?提前感谢您的帮助 更新 我更接近这个问题。嵌套的TAF元素在response元素中被正确解析,因为它们被包装在数据元素中。不幸的是,TAF中没有用于forecast标记列表的包装元素。我为Forecast类创建了一个带字符串
forecast
的第一个子元素,它是中的fcst\u time\u,它获取了它的内容并试图将日期反序列化为forecast
对象。我不知道为什么。也许我错过了一些简单的事情?提前感谢您的帮助
更新
我更接近这个问题。嵌套的TAF
元素在response
元素中被正确解析,因为它们被包装在数据
元素中。不幸的是,TAF
中没有用于forecast
标记列表的包装元素。我为Forecast
类创建了一个带字符串参数的构造函数,现在它将嵌入元素(fcst\u time\u from、fcst\u time\u to等等)解析为预测对象。有没有办法声明这个内部列表没有包装元素
更新2
经过一些测试,我发现这个问题与解析未包装的元素列表密切相关。我不知道为什么,但是如果我像这样声明我的结果
类,而不是上面显示的声明:
@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;
}
}
@XmlRootElement(name=“response”)
公众课堂反应{
@xmlementwrapper(name=“data”)
@xmlement(name=“TAF”)
私人名单技术援助基金;
公共列表getTafs(){
返回TAF;
}
公共无效集合TAF(列表TAF){
this.tafs=tafs;
}
}
它不起作用。未解析任何TAF元素。似乎解析器正在强制包装所有列表。不幸的是,我在REST输出中得到了展开的forecast
列表。我该怎么处理?我看到了@Element(inline=true)
注释的参数,但是@xmlement
没有这样的东西。我可以在RestTemplate中强制展开列表吗?OMG
经过两天的努力,我需要一条线来解决这个问题。所以从解析器的角度来看,似乎所有这些@xmlement
注释都是无用的。它们仅在我希望将对象作为REST服务输出回时使用。为了告诉解析器任何事情,我需要使用@jacksonxmlementwrapper
注释。确切的解决方案是:
@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=“TAF”)
公共级Taf{
@XmlElement(name=“raw_text”)私有字符串raw_text;
@xmlement(name=“station\u id”)私有字符串station\u id;//ICAO
@XmlElement(name=“发布时间”)私有日期发布时间;
@XmlElement(name=“公告时间”)私人日期公告时间;
@XmlElement(name=“valid\u time\u from”)私有日期有效时间\u from;
@XmlElement(name=“valid\u time\u to”)私有日期有效时间\u to;
@XmlElement(name=“备注”)私有字符串备注;
@XmlElement(name=“latitude”)专用双纬度;
@xmlement(name=“longitude”)私有双经度;
@XmlElement(name=“elevation\u m”)专用双立面;
@JacksonXmlElementWrapper(useWrapping=false)
@XmlElement(name=“forecast”)私有列表预测;
//接球手和接球手
}
及
@XmlRootElement(name=“forecast”)
公共类预测{
@XmlElement(name=“fcst_time_from”)私有日期fcst_time_from;
@XmlElement(name=“fcst\u time\u to”)私有日期fcst\u time\u to;
@XmlElement(name=“wind_dir_degrees”)私有整数wind_dir_degrees;
@XmlElement(name=“wind_speed_kt”)私有整数wind_speed_kt;
@XmlElement(name=“可见性法规”)私有双可见性法规;
@xmlement(name=“ex_string”)私有字符串wx_string;
@JacksonXmlElementWrapper(useWrapping=false)
@XmlElement(name=“天空条件”)私有列表天空条件;
//接球手和接球手
}
就这样。请先解决主要问题,然后我们才能看到。。。主要问题是:RestTemplate无法将“2017-10-17T12:00:00Z”解析/反序列化为“java.utill.Date”!有关解决方案,请参阅:(ObjectMapper.setDateFormat()
!)@xerx593不,不是这样。它将“2017-10-17T12:00:00Z”解析为“java.utill.Date”,没有问题。当我注释掉预测列表时,Taf对象被正确解析(它们包含日期字段)。此错误表示它试图将此日期字符串反序列化为Forecast对象。
public List<Taf> getTafsForICAO(String icao) {
RestTemplate restTemplate = new RestTemplate();
Response resp = restTemplate.getForObject(tafUrl+icao, Response.class);
return resp.getData();
}
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])
@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;
}
}
@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
}