41

这是我的 XML 文件:

<fields>
    <field mappedField="Num">
    </field>
    
    <field mappedField="Type">      
    </field>    
</fields>

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

@XmlRootElement(name = "fields")
public class Fields {

    @XmlElement(name = "field")
    List<Field> fields = new ArrayList<Field>();
        //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.<init>(JAXBContextImpl.java:270) ~[na:1.6.0_07]

我不明白为什么会出现这个异常。例外在这里:

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

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

4

12 回答 12

63

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

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

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

字段.java:

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;
    }

}

字段.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。使用默认设置,您应该注释要覆盖默认映射行为的公共访问器。

字段.java:

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;
    }

}

字段.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;
    }

}

了解更多信息

于 2012-05-29T09:32:08.110 回答
28

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

我也遇到了### counts of 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.]
....

does not have a no-arg default constructor我看来,这具有误导性。也许我不明白异常在说什么。但它确实表明我的LocalContextHandlerCollection. 我删除了一个依赖循环并清除了错误。

希望这对其他人有帮助。

于 2014-01-08T23:55:40.747 回答
11

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

  1. 向您的 Fields 类添加一个空的公共构造函数,JAXB 使用反射来加载您的类,这就是引发异常的原因。
  2. 为您的列表添加单独的 getter 和 setter。
于 2012-05-29T08:52:08.873 回答
11

这是因为默认情况下,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
}

选项 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
}

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

于 2012-05-29T09:53:48.680 回答
2

我曾经在考虑将@XmlTransient不需要序列化的字段放在一个用@XmlAccessorType(XmlAccessType.NONE).

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

于 2014-08-12T17:26:07.100 回答
1

对我来说,这个错误实际上是由一个错误地声明为公共而不是私有的字段引起的。

于 2019-02-11T13:27:15.220 回答
0

我遇到了同样的问题,我将一个 spring bean 作为 ResponseBody 对象传递回来。当我交还一个由 new 创建的对象时,一切都很好。

于 2015-03-30T23:10:31.310 回答
0

我有同样的问题

我的问题

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 文档中提供唯一命名的元素和属性。

于 2017-06-02T06:50:38.647 回答
0

以下所有选项都对我有用。

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

 @XmlRootElement(name = "fields")
 @XmlAccessorType(XmlAccessType.FIELD)
    public class Fields {

        @XmlElement(name = "field")
        List<Field> fields = new ArrayList<Field>();
            //getter, setter
    }

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

@XmlRootElement(name = "fields")
    public class Fields {

        @XmlElement(name = "field")
        List<Field> fields = new ArrayList<Field>();
            //getter
    }

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

@XmlRootElement(name = "fields")
    public class Fields {

        List<Field> fields = new ArrayList<Field>();

        @XmlElement(name = "field")
        //getter

        //setter
    }

希望这对你有帮助!

于 2017-12-20T08:06:14.907 回答
0

就我而言,我能够通过临时捕获异常、根据需要下降到原因(基于 IllegalAnnotationException 的深度)并在其上调用 getErrors() 来找到问题。

    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());
    }
于 2019-10-03T13:16:38.270 回答
0

发生这种情况是因为您有 2 个具有相同名称的类。例如,我有 2 个名为 settings 的 SOAP Web 服务,而 settings2 都具有相同的 GetEmployee 类,这是模棱两可的错误证明。

于 2020-06-20T05:19:09.857 回答
0

JAXB (java.xml.bind)

这个答案:

JDK 14

Spring Boot WebFlux 2.3.3.RELEASE

龙目岛 1.18.12

为我工作 >>>>> JDK 14

<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>

所以依赖项(jaxb-api,jaxb-impl,jaxb-runtime

我尝试测试每个版本。

正文要求:

<?xml version="1.0" encoding="UTF-8"?>
<service generator="zend" version="1.0">
    <send>
        <message>OK</message>
        <status>success</status>
    </send>
</service> 

DTO:

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"
        }
    ]
}

享受编程的乐趣^__^

于 2020-08-14T16:34:48.037 回答