使用JAXB 2.2.5将XML转Java对象时遇IllegalAnnotationsException问题
你遇到的这个异常是因为JAXB同时识别了字段dateDebut和对应的getter方法作为两个同名属性,产生了冲突。具体来说,你设置了@XmlAccessorType(XmlAccessType.FIELD),这个注解告诉JAXB直接通过字段来映射XML元素,但你又在getter方法上添加了@XmlElement注解——这就导致JAXB同时处理字段和方法,认为存在两个名为dateDebut的属性,从而抛出错误。
下面给你具体的解决步骤和修正后的代码:
1. 统一属性映射方式
既然你选择了XmlAccessType.FIELD(字段级映射),就应该把@XmlElement注解移到字段上,而不是getter方法上。这样JAXB只会处理字段,不会重复识别方法。
2. 正确处理XML命名空间
你的XML里用了tag前缀的命名空间,不能直接在@XmlElement的name属性里写tag:home_003,要通过namespace属性指定对应的命名空间URI(也就是XML里xmlns:tag="xxxxxxxx/tag"的那个值)。
3. 匹配XML根节点
你的XML根节点是<tag:TAG>,而不是<tag:home>,所以需要创建一个对应TAG的根类,再包含Customer(对应home节点)的属性。
修正后的代码示例
第一步:创建对应XML根节点的TAG类
import javax.xml.bind.annotation.*; @XmlRootElement(name = "TAG", namespace = "xxxxxxxx/tag") @XmlAccessorType(XmlAccessType.FIELD) public class TAG { @XmlElement(name = "home", namespace = "xxxxxxxx/tag") private Customer home; // 标准getter和setter,无需额外注解 public Customer getHome() { return home; } public void setHome(Customer home) { this.home = home; } }
第二步:修正Customer类
import javax.xml.bind.annotation.*; import java.util.Date; @XmlAccessorType(XmlAccessType.FIELD) public class Customer { @XmlElement(name = "home_003", namespace = "xxxxxxxx/tag") protected Date dateDebut; // 标准getter和setter,无需额外注解 public Date getDateDebut() { return dateDebut; } public void setDateDebut(Date dateDebut) { this.dateDebut = dateDebut; } }
优化:包级命名空间配置(可选)
如果不想在每个类和字段上重复写namespace,可以在你的实体类所在包下创建package-info.java文件,统一配置命名空间:
@XmlSchema( namespace = "xxxxxxxx/tag", elementFormDefault = XmlNsForm.QUALIFIED, xmlns = @XmlNs(prefix = "tag", namespaceURI = "xxxxxxxx/tag") ) package fr.models; // 替换成你的实体类所在包名 import javax.xml.bind.annotation.*;
这样之后,类和字段上的namespace属性就可以省略,JAXB会自动使用包级配置的命名空间。
最后提醒:解析XML的时候,要以TAG类作为根对象来解析,而不是Customer类,这样才能匹配你的XML结构。
内容的提问来源于stack exchange,提问作者Feres.o

