0

给定以下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 并将 xml 元素列表正确绑定到 LeagueDto 的最简单方法是什么<league>

我应该说清楚我没有使用JacksonsXmlMapperJAXBContext

4

1 回答 1

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.

于 2019-04-10T13:13:08.640 回答