JUnit测试中的IllegalAnnotationExceptions

时间:2018-10-05 06:26:38

标签: java junit jaxb

我想创建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);

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

1 个答案:

答案 0 :(得分:2)

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

  

类具有两个具有相同名称“ end_date”的属性,此问题与以下位置有关:公共java.time.LocalDateTime

问题可能是这样的:

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

尝试将此注释放在您的班级上:

@XmlAccessorType(XmlAccessType.FIELD)

说明:

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

默认访问类型为XmlAccessType.PUBLIC_MEMBER,这有点奇怪:它将查看公共获取器/设置器对以及公共字段。

如果在字段上放置诸如@XmlElement之类的注释,但对于这些字段也具有getter / setter方法,则JAXB将找到getter / setter,并且还将找到该字段,因为它已被显式注释,并且那么它将认为有两个具有相同名称的属性:一个由getter / setter定义,而另一个由字段定义。

解决方案是通过使用XmlAccessType.FIELD或通过将@XmlElement批注放置在getter或setter方法上而不是在字段上来告诉JAXB,它只应查看字段。

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

请注意,您不仅可以将@XmlAccessorType(XmlAccessType.FIELD)放在一个类上,还可以将其放在整个包中,只需将其放在package-info.java文件中-这样就不必将它放在每个您的域模型类之一。