Jaxb, Class имеет два свойства с одинаковым именем


121

с jaxb я пытаюсь прочитать файл xml, интересны только несколько элементов в файле xml, поэтому я хотел бы пропустить многие элементы

xml контент

xml я пытаюсь прочитать

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
    <flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
    <flx:Identification v="test1a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="123a"/>
    <flx:ResourceObject codingScheme="N" v="testa"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
    <flx:Identification v="test2a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="a123b"/>
    <flx:ResourceObject codingScheme="N" v="test2"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
        <flx:Pt>
            <flx:P v="2"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>

мой класс

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {

  @XmlElement(name="TimeSeries")
  protected List<TimeSeries> timeSeries;

  public List<TimeSeries> getTimeSeries() {
  if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
  }
  return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
  this.timeSeries = timeSeries;
  }

}

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

@XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;

@XmlElement(name = "Period")
protected Period period;

public RessourceObject getResourceObject() {
    return this.resourceObject;
}

public void setResourceObject(RessourceObject resourceObject) {
    this.resourceObject = resourceObject;
}

public Period getPeriod() {
    return this.period;
}

public void setPeriod(Period period) {
    this.period = period;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ResourceObject")

public class RessourceObject {
@XmlAttribute(name = "codingScheme")
protected String codingScheme;

@XmlAttribute(name = "v")
protected String v;

public String getCodingScheme() {
    return this.codingScheme;
}

public void setCodingScheme(String codingScheme) {
    this.codingScheme = codingScheme;
}

public String getV() {
    return this.v;
}

public void setV(String v) {
    this.v = v;
}
}

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Period")
public class Period {

@XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;

@XmlElement(name = "Pt")
protected List<Pt> pt;

public TimeInterval getTimeInterval() {
    return this.timeInterval;
}

public void setTimeInterval(TimeInterval timeInterval) {
    this.timeInterval = timeInterval;
}

public List<Pt> getPt() {
    if (this.pt == null) {
    this.pt = new ArrayList<Pt>();
    }
    return this.pt;
}

public void setPt(List<Pt> pt) {
    this.pt=pt;
}

}

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

@XmlAttribute(name = "v")
private String timeIntervalPeriod;

public String getTimeIntervalPeriod() {
    return this.timeIntervalPeriod;
}

public void setTimeIntervalPeriod(String timeIntervalPeriod) {
    this.timeIntervalPeriod = timeIntervalPeriod;
}

}

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

@XmlElement(name = "P")
protected P p;

@XmlElement(name = "A")
protected A a;

public P getP() {
    return this.p;
}

public void setP(P p) {
    this.p = p;
}

public A getA() {
    return this.a;
}

public void setA(A a) {
    this.a = a;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "P")
public class P {
@XmlAttribute(name = "v")
protected String position;


public String getPosition(){
    return this.position;
}

public void setPosition(String position){
    this.position=position;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "A")
public class A {
@XmlAttribute(name = "v")
protected String calculatedAmount;

public String getCalculatedAmount() {
    return this.calculatedAmount;
}

public void setCalculatedAmount(String calculatedAmount) {
    this.calculatedAmount = calculatedAmount;
}
}

когда я пытаюсь прочитать файл xlm, я получаю

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
    this problem is related to the following location:
        at public java.util.List testjaxp.ModeleREP.getTimeSeries()
        at testjaxp.ModeleREP
    this problem is related to the following location:
        at protected java.util.List testjaxp.ModeleREP.timeSeries
        at testjaxp.ModeleREP

я не понимаю эту ошибку

изменить: я использую jaxb-impl-2.1.12

хорошо, теперь у меня нет ошибок, но когда я проверяю свой объект, timeSeries имеет значение null ...

так, может быть, у jaxb проблемы с flx?

Ответы:


204

Я также столкнулся с такой проблемой, и я установил это.

@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)

Это будет работать на 100%


8
Я была такая же проблема. И даже это работает, когда мы добавляем только @XmlAccessorType (XmlAccessType.FIELD)
Рам Датт Шукла

2
Я решил проблему путем удаления в @XmlAccessorType(XmlAccessType.FIELD)аннотации
Hans Уотерс

Звучит странно, но я также избавился от этого исключения, сократив пару аннотаций \ @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) до только \ @XmlRootElement
Alex InTechno

3
Возникла та же проблема с внутренними классами для аннотации JAXB. Размещение @XmlAccessorType (XmlAccessType.FIELD) во внутренних классах сработало!
Shoaib Khan

Замечательно, спасибо большое. В сочетании с Ломбоком очень помогает
Майкл Хегнер

25

Вы не указали, какую версию JAXB-IMPL вы используете, но однажды у меня возникла такая же проблема (с jaxb-impl 2.0.5), и я решил ее, используя аннотацию на уровне получателя вместо того, чтобы использовать ее на уровне члена.


Это правильно, я просто удалил аннотацию из члена и поместил ее на уровень установщика, и это сработало.
Варун

22

Я также видел несколько похожих проблем.

Я думаю, это из-за того места, где мы используем аннотацию « @XMLElement » в классе (bean).

И я думаю, что JAXB (обработчик аннотаций) рассматривает поле члена и метод получения одного и того же элемента поля как разные свойства, когда мы используем аннотацию @XMLElement на уровне поля и выдает исключение IllegalAnnotationExceptions .

Сообщение об исключении:

Класс имеет два свойства с одинаковым именем "timeSeries"

В методе получения:

    at public java.util.List testjaxp.ModeleREP.getTimeSeries()

В поле участника:

    at protected java.util.List testjaxp.ModeleREP.timeSeries

Решение: Вместо того чтобы использовать @XmlElement в поле , использовать его в геттерном методе.


16

только что добавил это в свой класс

@XmlAccessorType(XmlAccessType.FIELD)

работал как чам


Также работает вместе с аннотацией @Data lombok.
digz6666

16

Есть несколько решений, но в основном, если вы комментируете объявление переменной, вам нужно @XmlAccessorType(XmlAccessType.FIELD) , но если вы предпочитаете аннотировать метод get или set, тогда вы этого не сделаете.

Итак, вы можете:

@XmlRootElement(name="MY_CLASS_A")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
    @XmlElement(name = "STATUS")   
    private int status;
   //.. and so on
}

Или:

@XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
    private int status;

    @XmlElement(name = "STATUS")         
    public int getStatus()
    {
    }
}

Чудесно. Спасибо :) +1
Аниш Б.

11

Ваш JAXB смотрит и на getTimeSeries()метод, и на член timeSeries. Вы не говорите, какую реализацию JAXB вы используете или ее конфигурацию, но исключение довольно очевидно.

в общедоступном java.util.List testjaxp.ModeleREP.getTimeSeries ()

и

в защищенном java.util.List testjaxp.ModeleREP.timeSeries

Вам необходимо настроить ваш материал JAXB для использования аннотаций (в соответствии с вашими @XmlElement(name="TimeSeries")) и игнорирования общедоступных методов.


я уже делаю: @XmlElement (name = "TimeSeries") protected List <TimeSeries> timeSeries;
redfox26

4
также я меняю (XmlAccessType.FIELD) на (XmlAccessType.NONE), я могу сохранить XmlElement на уровне участника
redfox26

Еще мне нужно было добавить @XmlTransient в переменную
HomeIsWhereThePcIs

8

Вам нужно настроить class ModeleREPтак же, @XmlAccessorType(XmlAccessType.FIELD)как вы это делали с class TimeSeries.

Посмотри на OOXS


8

Если мы воспользуемся приведенными ниже аннотациями и удалим аннотацию «@XmlElement», код должен работать правильно, и результирующий XML будет иметь имена элементов, аналогичные членам класса.

@XmlRootElement(name="<RootElementName>")
@XmlAccessorType(XmlAccessType.FIELD)

В случае, если действительно требуется использование «@XmlElement», определите его как уровень поля, и код должен работать идеально. Не определяйте аннотацию в верхней части метода получения.

Пробовал оба вышеупомянутых подхода и решил проблему.


7

«Класс имеет два свойства с одинаковым именем, исключение» может произойти, когда у вас есть член класса x с публичным уровнем доступа и геттер / сеттер для того же члена.

Как правило, не рекомендуется использовать общедоступный уровень доступа вместе с геттерами и сеттерами.

Проверьте это для более подробной информации: Public property VS Private property with getter?

Чтобы исправить это:

  1. Измените уровень доступа вашего участника на частный и оставьте свой геттер / сеттер
  2. Удалите геттер и сеттер члена

6

Это два свойства, на которые смотрит JAXB.

public java.util.List testjaxp.ModeleREP.getTimeSeries()  

и

protected java.util.List testjaxp.ModeleREP.timeSeries

Этого можно избежать, используя аннотацию JAXB в методе get, как указано ниже.

@XmlElement(name="TimeSeries"))  
public java.util.List testjaxp.ModeleREP.getTimeSeries()

5

просто объявите переменные-члены частными в классе, который вы хотите преобразовать в XML. Удачного кодирования


Это должно быть приемлемое решение. Если вы объявите свою переменную-член общедоступной, JABX проанализирует ее в дополнение к аннотированным методам получения / установки и выдаст исключение. Это отличный пример, когда разработчики библиотек jabx приложили дополнительные усилия для размышлений, пытаясь создать гибкость, и в конечном итоге облегчили создание недопустимых конфигураций. Я исправил проблему самостоятельно, изменяя по одной строке кода за раз, возвращаясь к переменной-члену.
Vortex

4

Та же проблема, с которой я столкнулся, я добавил

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

и теперь он работает.


3

Это сработает, если вы поместите аннотацию перед геттерами и удалите ее из защищенных атрибутов:

protected String codingScheme;

@XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
    return this.codingScheme;
}

Я тоже сталкиваюсь с той же проблемой. Я тоже заметил, что когда аннотация помечается над атрибутами, я вижу это. Значит ли это, что его всегда нужно ставить перед геттерами?
Паван Диттакави

@Pavan Да, я так думаю. В остальном это вызывает у меня те же проблемы, что и вы,
Лилия

2

Я только что столкнулся с этой проблемой и решил ее.

Источник проблемы в том, что у вас есть как XmlAccessType.FIELD, так и пары геттеров и сеттеров. Решение состоит в том, чтобы удалить сеттеры и добавить конструктор по умолчанию и конструктор, который принимает все поля.


У меня была такая же ошибка, и упомянутая вами аннотация решила ее, спасибо!
gyorgyabraham 03

1

У меня был класс обслуживания с подписью ниже "

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

При запуске я получил ту же ошибку для FetchIQAStatusResponseVOполей. Я просто добавил строку поверх FetchIQAStatusResponseVO:

@XmlAccessorType(XmlAccessType.FIELD) //This line added
public class FetchIQAStatusResponseVO {

и это решило проблему.



0

Аннотирование с помощью @XmlTransientрешает эту проблему

@XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
   this.timeSeries = timeSeries;
}

Посмотрите http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html для получения дополнительной информации.


1
Я думаю, что это скорее взлом, чем решение. Это указывает jaxb игнорировать метод вместо того, чтобы сообщать ему, что это одно и то же.
Ханс Воутерс,

Взламывать или нет, это лучшее решение, чтобы обойти то, что нельзя описать как что-либо, кроме ошибки, я использовал @XmlAccessorType (XmlAccessType.FIELD), который в основном игнорировался, и добавление @XmlTransient к каждому свойству было единственным способом устраните эту проблему. Спасибо!
Ральф Риточ 02

0

Быстрый и простой способ решить эту проблему - удалить @XmlElement(name="TimeSeries")из верхней части оператора объявления переменной protected List<TimeSeries> timeSeries;верхнюю часть его получателя public List<TimeSeries> getTimeSeries().

Таким образом, ваш ModeleREPкласс будет выглядеть так:

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {


  protected List<TimeSeries> timeSeries;

  @XmlElement(name="TimeSeries")
  public List<TimeSeries> getTimeSeries() {
    if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
    }
    return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
    this.timeSeries = timeSeries;
  }
}

Надеюсь, поможет!


Вы упомянули «простой способ». Любопытно, есть ли другой выход из этого - нет других аннотаций, которые можно было бы использовать?
Паван Диттакави

0

Я провел метод проб и ошибок и пришел к выводу, что вам нужно использовать либо оба, @XMLElementлибо @XmlAccessorType(XmlAccessType.FIELD).

Когда какой использовать?

случай 1 : Если ваши имена полей и имя элемента, которое вы хотите использовать в XML-файле, отличаются, вам необходимо использовать @XMLElement(name="elementName"). Поскольку это свяжет поля с этим именем элемента и отобразится в файле XML.

случай 2 : если имена полей и имя соответствующего элемента в xml одинаковы, вы можете просто использовать@XmlAccessorType(XmlAccessType.FIELD)


0

Было дано много решений, и @Sriram и @ptomli также вкратце коснулись внутреннего устройства. Я просто хочу добавить несколько ссылок на исходный код, чтобы помочь понять, что происходит под капотом.

По умолчанию (т.е. никакие дополнительные аннотации не используются, кроме @XmlRootElementкорневого класса), JABX пытается упорядочить объекты, представленные двумя способами:

  1. общественные поля
  2. методы получения , названные в соответствии с соглашением и имеющие соответствующий метод установки.

Обратите внимание, что если поле есть (или метод возвращается) null, оно не будет записано в вывод.

Теперь, если @XmlElementиспользуется, закрытые объекты (например, поля или методы получения) также могут быть упорядочены.

Но два способа, то есть поля и методы-получатели, не должны конфликтовать друг с другом. В противном случае вы получите исключение .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.