给出以下xml:
<?xml version="1.0" encoding="utf-8"?>
<live_schedules>
<title>This Schedule</title>
<date>20190328</date>
<link>/v2/schedule</link>
<id>schedule</id>
<updated>2019-03-28T21:51:41+0</updated>
<schedule>
<sport id="1" name="Football" link="/v2/sport/1">
<league id="100" name="Alliance of American Football" link="/v2/league/100" />
<league id="101" name="Alliance of American Football" link="/v2/league/101" />
</sport>
</schedule>
</live_schedules>
并且还提供以下类:
LiveScheduleDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Data
@AllArgsConstructor
@XmlRootElement(name = "live_schedule")
@XmlAccessorType(XmlAccessType.FIELD)
public class LiveScheduleWrapper {
@XmlElement(name = "title")
private String title;
@XmlElement(name = "date")
private String date;
@XmlElement(name = "link")
private String link;
@XmlElement(name = "id")
private String id;
@XmlElement(name = "updated")
private String updatedDate;
@XmlElement(name = "schedule")
private ScheduleDto schedule;
}
ScheduleDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "schedule")
class ScheduleDto {
@XmlElement(name = "sport")
List<SportDto> sports;
}
SportDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.xml.bind.annotation.*;
import java.util.List;
@Data
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "sport")
public class SportDto {
@XmlAttribute(name = "id")
Integer id;
@XmlAttribute(name = "name")
String name;
@XmlAttribute(name = "link")
String link;
@XmlElementWrapper(name = "league")
List<LeagueDto> league;
}
LeagueDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import javax.xml.bind.annotation.*;
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "league")
public class LeagueDto {
@XmlAttribute(name = "id")
String id;
@XmlAttribute(name = "name")
String name;
@XmlAttribute(name = "link")
String link;
}
执行映射的适配器:
package com.stackoverflow.adaptors;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.stackoverflow.dto.LiveScheduleWrapper;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import java.io.IOException;
public class ScheduleAdaptor {
private final HttpClient httpClient;
private final HttpGet httpGet;
public ScheduleAdaptor(HttpClient httpClient, HttpGet httpGet) {
this.httpClient = httpClient;
this.httpGet = httpGet;
}
public HttpApiResponse<LiveScheduleWrapper> retrieveSchedule() {
try {
HttpResponse response = httpClient.execute(httpGet);
XmlMapper mapper = new XmlMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
LiveScheduleWrapper schedule =
mapper.readValue(response.getEntity().getContent(), LiveScheduleWrapper.class);
return new HttpApiResponse(response.getStatusLine().getStatusCode(), schedule);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
我在通过解析器运行此程序时看到它将SportDto绑定到LeagueDto,因为我已经将<sport>
元素定义为List
。这不是我所期望的。相反,我希望它将把Sport XmlElement绑定到SportDto对象,然后将League绑定到我在示例中定义的嵌套League对象。
将<sport>
xml元素列表正确绑定到SportDto并将<league>
xml元素列表正确绑定到LeagueDto的最简单方法是什么?
我应该明确说明我使用的是Jackson
的{{1}}而不是XmlMapper
答案 0 :(得分:0)
我设法解决了。我的问题是因为我使用的Jackson
XmlMapper
功能不如JAXBContext
库...
我将retrieveSchedule
函数替换为以下内容:
public HttpApiResponse<LiveScheduleWrapper> retrieveSchedule() {
try {
HttpResponse response = httpClient.execute(httpGet);
JAXBContext jc = JAXBContext.newInstance(LiveScheduleWrapper.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
LiveScheduleWrapper schedule = (LiveScheduleWrapper) unmarshaller.unmarshal(response.getEntity().getContent());
return new HttpApiResponse(response.getStatusLine().getStatusCode(), schedule);
} catch (JAXBException | IOException e) {
e.printStackTrace();
}
return null;
}
这解决了我的问题,因为JAXBContext
可以正确识别XmlMapper
上的JAXB批注。