Java 我能';我不理解为什么会抛出这个JAXB IllegalAnnotationException

Java 我能';我不理解为什么会抛出这个JAXB IllegalAnnotationException,java,exception,jaxb,Java,Exception,Jaxb,这是我的XML文件: <fields> <field mappedField="Num"> </field> <field mappedField="Type"> </field> </fields> 但我有个例外 [INFO] com.sun.xml.internal.bind.v2.runtime.IllegalAnn

这是我的XML文件:

<fields>
    <field mappedField="Num">
    </field>
    
    <field mappedField="Type">      
    </field>    
</fields>
但我有个例外

[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.<init>(JAXBContextImpl.java:270) ~[na:1.6.0_07]

我使用JDK1.6_0.0.7。谢谢。

以下情况之一可能导致异常:

  • 在JAXB使用的Fields类中添加一个空的公共构造函数 反射来加载类,这就是引发异常的原因
  • 为列表添加单独的getter和setter

  • 这个异常是由于您的JAXB(JSR-222)实现认为有两个映射为相同名称的东西(一个字段和一个属性)。对于您的用例,有两个选项:

    选项#1-使用
    @xmlacessortype(xmlacesstype.Field)

    package forum10795793;
    
    import java.util.*;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement(name = "fields")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Fields {
    
        @XmlElement(name = "field")
        List<Field> fields = new ArrayList<Field>();
    
        public List<Field> getFields() {
            return fields;
        }
    
        public void setFields(List<Field> fields) {
            this.fields = fields;
        }
    
    }
    
    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;
        }
    
    }
    
    package forum10795793;
    
    import java.util.*;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement(name = "fields")
    public class Fields {
    
        List<Field> fields = new ArrayList<Field>();
    
        @XmlElement(name = "field")
        public List<Field> getFields() {
            return fields;
        }
    
        public void setFields(List<Field> fields) {
            this.fields = fields;
        }
    
    }
    
    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;
        }
    
    }
    
    如果要注释该字段,则应指定
    @xmlacessortype(xmlacesstype.field)

    Fields.java:

    选项#2-注释属性

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

    Fields.java:

    了解更多信息


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

        备选案文1:

        @XmlRootElement(name = "fields")
        @XmlAccessorType(XmlAccessType.FIELD)
        public class Fields {
        
                @XmlElement(name = "field")
                List<Field> fields = new ArrayList<Field>();
                //getter, setter
        }
        
        @XmlAccessorType(XmlAccessType.FIELD)
        public class Field {
        
               @XmlAttribute(name = "mappedField")
               String mappedField;
               //getter,setter
        }
        
        @XmlRootElement(name=“fields”)
        @XmlAccessorType(XmlAccessType.FIELD)
        公共类字段{
        @xmlement(name=“field”)
        列表字段=新的ArrayList();
        //盖特,塞特
        }
        @XmlAccessorType(XmlAccessType.FIELD)
        公共类字段{
        @XmlAttribute(name=“mappedField”)
        字符串映射字段;
        //盖特,塞特
        }
        
        备选案文2:

        @XmlRootElement(name = "fields")
        public class Fields {
        
                List<Field> fields = new ArrayList<Field>();
        
                @XmlElement(name = "field")
                public List<Field> getFields() {
        
                }
        
                //setter
        }
        
        @XmlAccessorType(XmlAccessType.FIELD)
        public class Field {
        
               String mappedField;
        
               @XmlAttribute(name = "mappedField")
               public String getMappedField() {
        
               }
        
                //setter
        }
        
        @XmlRootElement(name=“fields”)
        公共类字段{
        列表字段=新的ArrayList();
        @xmlement(name=“field”)
        公共列表getFields(){
        }
        //塞特
        }
        @XmlAccessorType(XmlAccessType.FIELD)
        公共类字段{
        字符串映射字段;
        @XmlAttribute(name=“mappedField”)
        公共字符串getMappedField(){
        }
        //塞特
        }
        
        有关更多详细信息和深度,请查看以下JDK文档

        我不明白为什么会抛出这个JAXB IllegalAnnotationException

        我还得到了IllegalAnnotationExceptions的
        ###计数
        异常,这似乎是由于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.]
        ....
        
        没有无参数默认构造函数
        在我看来似乎有误导性。也许我不明白例外是怎么说的。但它确实表明我的
        LocalContextHandlerCollection
        存在问题。我删除了一个依赖循环,错误被清除


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

        我曾经收到这条消息,当时我认为将
        @xmltransive
        放在一个我不需要序列化的字段上,这个类用
        @xmlacessortype(xmlacesstype.NONE)
        注释


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

        我也有同样的问题,我将一个Springbean作为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
        
        为解决此问题而进行的更改如下所示

        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方法在类和字段级别对字段进行注释

         @XmlRootElement(name = "fields")
         @XmlAccessorType(XmlAccessType.FIELD)
            public class Fields {
        
                @XmlElement(name = "field")
                List<Field> fields = new ArrayList<Field>();
                    //getter, setter
            }
        
        @XmlRootElement(name=“fields”)
        @XmlAccessorType(XmlAccessType.FIELD)
        公共类字段{
        @xmlement(name=“field”)
        列表字段=新的ArrayList();
        //盖特,塞特
        }
        
        选项2:在类级别(@XmlAccessorType(XmlAccessType.FIELD))没有字段注释,并且只有getter方法。添加Setter方法将引发错误,因为在本例中不包括注释。请记住,在XML文件中显式设置值时不需要Setter

        @XmlRootElement(name = "fields")
            public class Fields {
        
                @XmlElement(name = "field")
                List<Field> fields = new ArrayList<Field>();
                    //getter
            }
        
        @XmlRootElement(name=“fields”)
        公共类字段{
        @xmlement(name=“field”)
        列表字段=新的ArrayList();
        //吸气剂
        }
        
        选项3:仅在getter方法上进行注释。请记住,我们也可以在这里使用setter方法,因为在本例中我们不做任何字段级注释

        @XmlRootElement(name = "fields")
            public class Fields {
        
                List<Field> fields = new ArrayList<Field>();
        
                @XmlElement(name = "field")
                //getter
        
                //setter
            }
        
        @XmlRootElement(name=“fields”)
        公共类字段{
        列表字段=新的ArrayList();
        @xmlement(name=“field”)
        //吸气剂
        //塞特
        }
        

        希望这对您有所帮助!

        对于我来说,这个错误实际上是由一个字段被错误地声明为public而不是private引起的。

        在我的例子中,我可以通过临时捕获异常来发现问题,并根据需要(根据异常的深度)深入分析原因
        @XmlRootElement(name = "fields")
            public class Fields {
        
                @XmlElement(name = "field")
                List<Field> fields = new ArrayList<Field>();
                    //getter
            }
        
        @XmlRootElement(name = "fields")
            public class Fields {
        
                List<Field> fields = new ArrayList<Field>();
        
                @XmlElement(name = "field")
                //getter
        
                //setter
            }
        
            try {
                // in my case, this was what gave me an exception
                endpoint.publish("/MyWebServicePort");
            // I got a WebServiceException caused by another exception, which was caused by the IllegalAnnotationsException
            } catch (WebServiceException e) {
                // Incidentally, I need to call getCause().getCause() on it, and cast to IllegalAnnotationsException before calling getErrors()
                System.err.println(((com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException)e.getCause().getCause()).getErrors());
            }
        
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>3.0.0-M4</version>
        </dependency>
        
        <?xml version="1.0" encoding="UTF-8"?>
        <service generator="zend" version="1.0">
            <send>
                <message>OK</message>
                <status>success</status>
            </send>
        </service> 
        
        import lombok.Getter;
        import lombok.Setter;
        
        import javax.xml.bind.annotation.XmlAccessType;
        import javax.xml.bind.annotation.XmlAccessorType;
        import javax.xml.bind.annotation.XmlRootElement;
        import java.util.ArrayList;
        import java.util.List;
        
        public class SmsSend {
            
            @Getter
            @Setter
            @XmlRootElement(name = "service")
            public static class ReplyMethodSend {
                private List<ReplyValue> send = new ArrayList<>();
            }
        
            @Getter
            @Setter
            @XmlAccessorType(XmlAccessType.FIELD)
            public static class ReplyValue {
                private String message;
                private String status;
            }
        }
        
        {
            "send": [
                {
                "message": "OK",
                "status": "success"
                }
            ]
        }