Java 针对泛型和特定类型或该类型列表的灵活JAXB XML解析

Java 针对泛型和特定类型或该类型列表的灵活JAXB XML解析,java,xml,generics,jaxb,generic-programming,Java,Xml,Generics,Jaxb,Generic Programming,我正在使用同事的API。API返回带有对象列表的响应,或者只返回一个单一对象。对象可以是多种类型。返回类型为XML格式。我感兴趣的是通过JAXB解析这个XML来获得我的类,理想情况下是以一种灵活和通用的方式 以下两个XML响应是我所说的示例 示例1:具有包含Job对象的列表Jobs的响应 <Response> <Status>OK</Status> <Jobs> <Job> <I

我正在使用同事的API。API返回带有对象列表的
响应
,或者只返回一个单一对象。对象可以是多种类型。返回类型为XML格式。我感兴趣的是通过JAXB解析这个XML来获得我的类,理想情况下是以一种灵活和通用的方式

以下两个XML响应是我所说的示例

示例1:具有包含
Job
对象的列表
Jobs
的响应

<Response>
   <Status>OK</Status>
   <Jobs>
        <Job>
            <ID>J1</ID>
            <Name>job name</Name> 
        </Job>
        <Job>
            <ID>J2</ID>
            <Name>job name</Name> 
        </Job>
    </Jobs>
</Response>
目前,我正在构建如下内容:

@XmlRootElement(name="Response")
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {
    @XmlElement(name = "Status")
    protected Status status;
    @XmlAnyElement(lax=true)
    protected Object items;
}
解组通过

   Response = (Response) unmarshaller.unmarshal(myXmlResponse);
但在解组样本1时,我在我的项目中接收到
null
。此外,这种方法给了我一种不好的感觉,因为我正在使用
对象
作为一种包罗万象的方法,即既要使用
列表
也要使用
作业
类型。我做错了什么?有更好的解决办法吗?也许我的response类可以有两个泛型,一个用于
项的列表,另一个用于单个
项的列表

将单数
转换为包含一个元素的
作业列表的方法也很有趣,但我不确定在不修改XML响应的情况下该方法是否为通用方法。

您可以这样做:

@XmlRootElement(name = "Response")
public class Response {

    @XmlElement(name ="Status")
    private Status status;

    @XmlElements({
            @XmlElement(name = "Job", type = Job.class),
            @XmlElement(name = "Jobs", type = Jobs.class),
    })
    private List<?> jobs;
}
和工作:

public class Jobs {

    @XmlElement(name = "Job")
    private List<Job> jobs;
}
公共类作业{
@xmlement(name=“作业”)
私人名单工作;
}
有关评论的最新答复:

这是我能想到的处理这些描述的有效载荷的最干净的方法。挑战在于
只出现过几次

有一种方法可以在没有嵌入列表的情况下完成,但它更混乱。我会把它复制到下面,这样你就可以决定你是否喜欢它,或者最好换一种更干净的解决方案

@XmlRootElement(name = "Response")
public class Response {

    @XmlElement(name ="Status")
    private Status status;

    @XmlElement(name = "Job")
    private List<Job> jobs;

    @XmlElementWrapper(name = "Jobs")
    @XmlElement(name = "Job")
    private List<Job> jobsWrapped;

}
@XmlRootElement(name=“Response”)
公众课堂反应{
@xmlement(name=“Status”)
私人身份;
@xmlement(name=“作业”)
私人名单工作;
@XmlElementWrapper(name=“作业”)
@xmlement(name=“作业”)
私人名单上的工作受到打击;
}
您可以这样做:

@XmlRootElement(name = "Response")
public class Response {

    @XmlElement(name ="Status")
    private Status status;

    @XmlElements({
            @XmlElement(name = "Job", type = Job.class),
            @XmlElement(name = "Jobs", type = Jobs.class),
    })
    private List<?> jobs;
}
和工作:

public class Jobs {

    @XmlElement(name = "Job")
    private List<Job> jobs;
}
公共类作业{
@xmlement(name=“作业”)
私人名单工作;
}
有关评论的最新答复:

这是我能想到的处理这些描述的有效载荷的最干净的方法。挑战在于
只出现过几次

有一种方法可以在没有嵌入列表的情况下完成,但它更混乱。我会把它复制到下面,这样你就可以决定你是否喜欢它,或者最好换一种更干净的解决方案

@XmlRootElement(name = "Response")
public class Response {

    @XmlElement(name ="Status")
    private Status status;

    @XmlElement(name = "Job")
    private List<Job> jobs;

    @XmlElementWrapper(name = "Jobs")
    @XmlElement(name = "Job")
    private List<Job> jobsWrapped;

}
@XmlRootElement(name=“Response”)
公众课堂反应{
@xmlement(name=“Status”)
私人身份;
@xmlement(name=“作业”)
私人名单工作;
@XmlElementWrapper(name=“作业”)
@xmlement(name=“作业”)
私人名单上的工作受到打击;
}

这给出了
列表的列表(即
列表的
列表)或
作业的
列表,对吗?是否有不同的方法来实现这一点,例如在两种情况下直接获取
列表
,或者,取而代之的是
作业
列表
(避免嵌套列表)?@Zeruno这是我能想到的最干净的方法。问题在于
作业
只在部分时间存在。还有另一种方法可以做到这一点,没有嵌套列表,但它更混乱。将更新答案以包含itI我想让我的响应类包含两个属性,一个是作业列表,另一个是单个作业,然后相应地访问其中一个,怎么样?@Zeruno yes确实是我的解决方案-刚刚发布:)。然后,您可以提供一种基于字段检索作业的方法。这两个版本都有效,你必须决定你更喜欢什么。是的,我明白了。非常感谢您的编辑!您关于使用单一方法的提示也非常有用。对于我的用例,我可能会改变的是将单个元素作为单个对象,而不是一个元素的列表。这会给出一个
list
列表(即
list
list
,或者
job
list
,对吗?是否有不同的方法来实现这一点,例如在两种情况下直接获取
列表
,或者,取而代之的是
作业
列表
(避免嵌套列表)?@Zeruno这是我能想到的最干净的方法。问题在于
作业
只在部分时间存在。还有另一种方法可以做到这一点,没有嵌套列表,但它更混乱。将更新答案以包含itI我想让我的响应类包含两个属性,一个是作业列表,另一个是单个作业,然后相应地访问其中一个,怎么样?@Zeruno yes确实是我的解决方案-刚刚发布:)。然后,您可以提供一种基于字段检索作业的方法。这两个版本都有效,你必须决定你更喜欢什么。是的,我明白了。非常感谢您的编辑!您关于使用单一方法的提示也非常有用。也许对于我的用例,我会改变的是将单个元素作为单个对象,而不是一个元素列表。