创建JAXBContext时抛出IllegalAnnotationsException的原因?附IsoMessage类代码
这个异常通常是因为JAXB在解析你的类时遇到了重复属性映射或者无法识别的映射规则问题,结合你给出的IsoMessage类代码,最可能的原因和解决方法如下:
最可能的原因:属性重复映射
JAXB默认的访问类型是PUBLIC_MEMBER,它会同时处理公共字段和公共的getter/setter方法。虽然你的binBitmap字段是私有的,但如果你的properties参数中指定了访问类型为FIELD(比如设置了javax.xml.bind.annotation.XmlAccessorType为FIELD),JAXB会强制解析所有字段(包括私有),同时又会把isBinaryBitmap()/setBinaryBitmap()对应的binaryBitmap属性当作另一个可映射属性,这样就会出现重复属性映射,触发IllegalAnnotationsException。
另外,即使没有修改访问类型,某些JAXB版本对boolean类型的getter命名(isXxx)和字段名的匹配逻辑可能出现偏差,导致误判为重复属性。
解决方案
1. 指定明确的访问类型
在你的IsoMessage类上添加@XmlAccessorType注解,明确告诉JAXB只处理getter/setter或者只处理字段,避免重复映射:
方式一:基于属性(getter/setter)映射
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; @XmlAccessorType(XmlAccessType.PROPERTY) public class IsoMessage { private boolean binBitmap; public IsoMessage() {} public void setBinaryBitmap(boolean paramBoolean) { this.binBitmap = paramBoolean; } public boolean isBinaryBitmap() { return this.binBitmap; } }
方式二:基于字段映射
如果想让JAXB直接处理字段,需要给字段添加@XmlElement注解(可选,用来指定XML元素名),同时指定访问类型为FIELD:
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlElement; @XmlAccessorType(XmlAccessType.FIELD) public class IsoMessage { @XmlElement(name = "binaryBitmap") // 可选,指定XML中元素的名称 private boolean binBitmap; public IsoMessage() {} public void setBinaryBitmap(boolean paramBoolean) { this.binBitmap = paramBoolean; } public boolean isBinaryBitmap() { return this.binBitmap; } }
2. 添加@XmlRootElement注解(可选但推荐)
虽然创建JAXBContext不需要这个注解,但添加@XmlRootElement可以明确标记这个类是XML的根元素,避免后续marshal/unmarshal时的其他问题,同时也能让JAXB更清晰地识别类的映射规则:
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; @XmlRootElement @XmlAccessorType(XmlAccessType.PROPERTY) public class IsoMessage { // 类内容不变 }
3. 检查properties参数
如果你的properties参数中设置了JAXB相关的配置,比如javax.xml.bind.context.factory或者访问类型,确保这些配置没有和类的注解冲突,比如不要同时设置访问类型为FIELD又保留getter/setter的属性映射。
内容的提问来源于stack exchange,提问作者Nidhi Dhoka

