JUnit 测试中的 IllegalAnnotationExceptions

IllegalAnnotationExceptions in JUnit test

我想创建 JUnit 测试来测试 JAXB 代码:

@XmlRootElement(name = "reconcile")
public class Reconcile {

    @XmlElement(name = "start_date")
    @XmlJavaTypeAdapter(LocalDateTimeXmlAdapter.class)
    public LocalDateTime start_date;
    @XmlElement(name = "end_date")
    @XmlJavaTypeAdapter(LocalDateTimeXmlAdapter.class)
    public LocalDateTime end_date;
    @XmlElement(name = "page")
    public String page;

    //// getters and setters
}

我为上面的代码尝试了这个 JUnit 测试:

import java.time.LocalDateTime;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.datalis.plugin.reconcile.Reconcile;
import org.junit.jupiter.api.Test;

public class ReconciliationTest {

    @Test
    public void uniqueTransactionIdLenght() throws JAXBException {

        Reconcile reconcile = new Reconcile();
        reconcile.start_date = LocalDateTime.of(2018, 4, 8, 11, 2, 44);
        reconcile.end_date = LocalDateTime.of(2018, 11, 8, 11, 2, 44);
        reconcile.page = "1";

        JAXBContext jaxbContext = JAXBContext.newInstance(Reconcile.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(reconcile, System.out);
    }
}

但是当我 运行 我得到代码时:

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
    at org.datalis.plugin.jaxb.ReconciliationTest.uniqueTransactionIdLenght(ReconciliationTest.java:22)

在这一行

JAXBContext jaxbContext = JAXBContext.newInstance(Reconcile.class);

有什么办法可以解决这个问题吗?

查看您在评论中提到的错误信息:

Class has two properties of the same name "end_date" this problem is related to the following location: at public java.time.LocalDateTime

问题大概是这样的:

您要么没有 @XmlAccessorType 注释(以便使用默认访问类型),要么您有,但访问类型错误。

尝试将此注释添加到您的 class:

@XmlAccessorType(XmlAccessType.FIELD)

解释:

JAXB 可以用不同的方式处理您的 classes。它可以查看 getter/setter 对,也可以直接查看字段。这是访问类型。

默认访问类型是XmlAccessType.PUBLIC_MEMBER,这有点奇怪:它会查看public getter/setter 对以及public 字段。

如果您在字段上放置诸如 @XmlElement 之类的注释,但您也有这些字段的 getter/setter 方法,那么 JAXB 将找到 getter/setter 并且它也会找到该字段因为它被明确地注释了,然后它会认为有两个同名的属性:一个由 getter/setter 定义,一个由字段定义。

解决方案是通过使用 XmlAccessType.FIELD 或将 @XmlElement 注释放在 getter 或 [=51= 上来告诉 JAXB 它应该只查看字段] 方法而不是在场上。

这有点古怪,但这就是 JAXB 的工作方式...

请注意,您不仅可以将 @XmlAccessorType(XmlAccessType.FIELD) 放在 class 上,还可以通过将其放在 package-info.java 文件中来将其放在整个包上 - 这样您就不会必须把它放在你的每一个域模型上 classes.