我无法理解为什么抛出这个JAXB IllegalAnnotationException

这是我的XML文件:

      

我做了2个类来解析它(Fields.java和Field.java):

 @XmlRootElement(name = "fields") public class Fields { @XmlElement(name = "field") List fields = new ArrayList(); //getter, setter } 

 public class Field { @XmlAttribute(name = "mappedField") String mappedField; /getter,setter } 

但我得到了这个例外。

 [INFO] com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions [INFO] at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66) ~[na:1.6.0_07] [INFO] at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:422) ~[na:1.6.0_07] [INFO] at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:270) ~[na:1.6.0_07] 

我无法理解为什么这个例外会上升。 例外情况如下:

 JAXBContext context = JAXBContext.newInstance(Fields.class); 

我使用JDK 1.6_0.0.7。 谢谢。

exception是由于您的JAXB(JSR-222)实现认为有两个事物映射了相同的名称(字段和属性)。 您的用例有几种选择:

选项#1 – 使用@XmlAccessorType(XmlAccessType.FIELD)注释字段

如果要对该字段进行注释,则应指定@XmlAccessorType(XmlAccessType.FIELD)

Fields.java:

 package forum10795793; import java.util.*; import javax.xml.bind.annotation.*; @XmlRootElement(name = "fields") @XmlAccessorType(XmlAccessType.FIELD) public class Fields { @XmlElement(name = "field") List fields = new ArrayList(); public List getFields() { return fields; } public void setFields(List fields) { this.fields = fields; } } 

Field.java:

 package forum10795793; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Field { @XmlAttribute(name = "mappedField") String mappedField; public String getMappedField() { return mappedField; } public void setMappedField(String mappedField) { this.mappedField = mappedField; } } 

选项#2 – 注释属性

默认访问者类型是XmlAccessType.PUBLIC 。 这意味着默认情况下,JAXB实现会将公共字段和访问器映射到XML。 使用默认设置,您应该注释要覆盖默认映射行为的公共访问者。

Fields.java:

 package forum10795793; import java.util.*; import javax.xml.bind.annotation.*; @XmlRootElement(name = "fields") public class Fields { List fields = new ArrayList(); @XmlElement(name = "field") public List getFields() { return fields; } public void setFields(List fields) { this.fields = fields; } } 

Field.java:

 package forum10795793; import javax.xml.bind.annotation.*; public class Field { String mappedField; @XmlAttribute(name = "mappedField") public String getMappedField() { return mappedField; } public void setMappedField(String mappedField) { this.mappedField = mappedField; } } 

了解更多信息

我无法理解为什么抛出这个JAXB IllegalAnnotationException

我也得到### counts of IllegalAnnotationExceptionsexception,它似乎是由于我的Spring连接中的不正确的依赖层次结构。

我通过在JAXB代码中抛出一个断点来解决这个问题。 对我来说,这是在com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check() 。 然后我转储了list变量,它给出了类似的东西:

 [org.mortbay.jetty.Handler is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at org.mortbay.jetty.Handler at public org.mortbay.jetty.Handler[] org.mortbay.jetty.handler.HandlerCollection.getHandlers() at org.mortbay.jetty.handler.HandlerCollection at org.mortbay.jetty.handler.ContextHandlerCollection at com.mprew.ec2.commons.server.LocalContextHandlerCollection at private com.mprew.ec2.commons.server.LocalContextHandlerCollection com.mprew.ec2.commons.services.jaxws_asm.SetLocalContextHandlerCollection.arg0 at com.mprew.ec2.commons.services.jaxws_asm.SetLocalContextHandlerCollection, org.mortbay.jetty.Handler does not have a no-arg default constructor.] .... 

在我does not have a no-arg default constructor会产生误导。 也许我不明白exception是在说什么。 但它确实表明我的LocalContextHandlerCollection存在问题。 我删除了一个依赖循环并清除了错误。

希望这对其他人有所帮助。

这是因为,默认情况下,Jaxb在序列化pojo时,会查找属性的公共成员(getter或setter)上的注释。 但是,您在字段上提供注释。 因此,要么在setter或getter属性上更改和设置注释,要么将XmlAccessortype设置为field。

选项1::

 @XmlRootElement(name = "fields") @XmlAccessorType(XmlAccessType.FIELD) public class Fields { @XmlElement(name = "field") List fields = new ArrayList(); //getter, setter } @XmlAccessorType(XmlAccessType.FIELD) public class Field { @XmlAttribute(name = "mappedField") String mappedField; //getter,setter } 

选项2 ::

 @XmlRootElement(name = "fields") public class Fields { List fields = new ArrayList(); @XmlElement(name = "field") public List getFields() { } //setter } @XmlAccessorType(XmlAccessType.FIELD) public class Field { String mappedField; @XmlAttribute(name = "mappedField") public String getMappedField() { } //setter } 

有关更多详细信息和深度,请查看以下JDK文档http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html

以下之一可能导致exception:

  1. 将一个空的公共构造函数添加到Fields类中,JAXB使用reflection来加载类,这就是抛出exception的原因。
  2. 为列表添加单独的getter和setter。

我曾经认为在一个用@XmlAccessorType(XmlAccessType.NONE)注释的类@XmlTransient放在一个我不需要序列化的字段上之后就收到了这条消息。

在这种情况下,删除XmlTransient解决了这个问题。 我不是JAXB专家,但我怀疑因为AccessType.NONE表示不应该进行自动序列化(即必须对字段进行特别注释以将其序列化),这使得XmlTransient非法,因为它的唯一目的是从auto中排除字段-serialization。

我有同样的问题,我正在将一个Spring bean作为ResponseBody对象传回。 当我递回一个由new创建的对象时,一切都很好。

我遇到了同样的问题

我的问题

 Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions Two classes have the same XML type name "{urn:cpq_tns_Kat_getgroupsearch}Kat_getgroupsearch". Use @XmlType.name and @XmlType.namespace to assign different names to them. this problem is related to the following location: at katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearch at public javax.xml.bind.JAXBElement katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory.createKatGetgroupsearch(katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearch) at katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory this problem is related to the following location: at cpq_tns_kat_getgroupsearch.KatGetgroupsearch Two classes have the same XML type name "{urn:cpq_tns_Kat_getgroupsearch}Kat_getgroupsearchResponse0". Use @XmlType.name and @XmlType.namespace to assign different names to them. this problem is related to the following location: at katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0 at public javax.xml.bind.JAXBElement katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory.createKatGetgroupsearchResponse0(katrequest.cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0) at katrequest.cpq_tns_kat_getgroupsearch.ObjectFactory this problem is related to the following location: at cpq_tns_kat_getgroupsearch.KatGetgroupsearchResponse0 

为了解决它而改变了以下

我将相应的名称更改为名称空间

 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(**name** = "Kat_getgroupsearch", propOrder = { @XmlAccessorType(XmlAccessType.FIELD) @XmlType(namespace = "Kat_getgroupsearch", propOrder = { @XmlAccessorType(XmlAccessType.FIELD) @XmlType(**name** = "Kat_getgroupsearchResponse0", propOrder = { @XmlAccessorType(XmlAccessType.FIELD) @XmlType(namespace = "Kat_getgroupsearchResponse0", propOrder = { 

为什么?

由于在错误日志中编写了两个类具有相同的名称,因此我们应该使用命名空间,因为XML命名空间用于在XML文档中提供唯一命名的元素和属性。

以下所有选项对我有用。

选项1:使用getter / setter方法在类和字段级别对FIELD进行注释

  @XmlRootElement(name = "fields") @XmlAccessorType(XmlAccessType.FIELD) public class Fields { @XmlElement(name = "field") List fields = new ArrayList(); //getter, setter } 

选项2:在类级别没有注释FIELD(@XmlAccessorType(XmlAccessType.FIELD)并且只使用getter方法。添加Setter方法会抛出错误,因为在这种情况下我们不包括Annotation。记住,当你不需要setter显式设置XML文件中的值。

 @XmlRootElement(name = "fields") public class Fields { @XmlElement(name = "field") List fields = new ArrayList(); //getter } 

选项3:仅使用getter方法进行注释。 请记住,我们也可以在这里使用setter方法,因为在这种情况下我们没有进行任何FIELD级别的注释。

 @XmlRootElement(name = "fields") public class Fields { List fields = new ArrayList(); @XmlElement(name = "field") //getter //setter } 

希望这对你有所帮助!