Я не могу понять, почему это исключение JAXB IllegalAnnotationException
Это мой 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. Спасибо.
Ответы
Ответ 1
Исключение связано с вашей реализацией 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<Field> fields = new ArrayList<Field>();
public List<Field> getFields() {
return fields;
}
public void setFields(List<Field> 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<Field> fields = new ArrayList<Field>();
@XmlElement(name = "field")
public List<Field> getFields() {
return fields;
}
public void setFields(List<Field> 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;
}
}
Дополнительная информация
Ответ 2
Для потомков ни один из этих ответов не помог мне с моей проблемой. Я получал исключение ### 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
. Я удалил цикл зависимостей, и ошибка была удалена.
Надеюсь, это будет полезно для других.
Ответ 3
Это связано с тем, что по умолчанию Jaxb при сериализации pojo ищет аннотации к публичным членам (getters или seters) свойств. Но вы предоставляете аннотации по полям. поэтому либо измените, либо установите аннотации на сеттеры или геттеры свойств, либо задайте поле 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
Ответ 4
Одно из следующего может вызвать исключение:
- Добавить пустой публичный конструктор в ваш класс Fields, JAXB использует
отражение для загрузки ваших классов, поэтому исключение выбрано.
- Добавьте отдельный тэгстер и сеттер для вашего списка.
Ответ 5
Я получил это сообщение после того, как подумал, что положить @XmlTransient
в поле, которое мне не нужно сериализовать, в классе, который был аннотирован с помощью @XmlAccessorType(XmlAccessType.NONE)
.
В этом случае удаление XmlTransient
разрешило проблему. Я не эксперт JAXB, но я подозреваю, что поскольку AccessType.NONE указывает, что автоматическая сериализация не должна выполняться (например, поля должны быть специально аннотированы для их сериализации), что делает XmlTransient
незаконным, поскольку единственная его цель - исключить поле от автоматической сериализации.
Ответ 6
У меня была эта же проблема, я передавал spring bean обратно как объект ResponseBody. Когда я вернул объект, созданный новым, все было хорошо.
Ответ 7
У меня была такая же проблема
Мой вопрос
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.
Ответ 8
Все приведенные ниже параметры работали для меня.
Вариант 1: аннотация для FIELD на уровне класса и поля с использованием методов getter/setter
@XmlRootElement(name = "fields")
@XmlAccessorType(XmlAccessType.FIELD)
public class Fields {
@XmlElement(name = "field")
List<Field> fields = new ArrayList<Field>();
//getter, setter
}
Вариант 2: No Annotation для FIELD на уровне класса (@XmlAccessorType (XmlAccessType.FIELD) и только с помощью метода getter. Добавление метода Setter будет вызывать ошибку, поскольку в этом случае мы не включаем аннотацию. требуется, если вы явно задаете значения в своем XML файле.
@XmlRootElement(name = "fields")
public class Fields {
@XmlElement(name = "field")
List<Field> fields = new ArrayList<Field>();
//getter
}
Вариант 3: аннотация по методу геттера. Помните, что мы также можем использовать метод setter, поскольку в этом случае мы не делаем аннотации уровня FIELD.
@XmlRootElement(name = "fields")
public class Fields {
List<Field> fields = new ArrayList<Field>();
@XmlElement(name = "field")
//getter
//setter
}
Надеюсь, это поможет вам!