Джакс, Клас має дві однойменні властивості


120

з 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 є нульовим ...

тож, можливо, у Jaxb, здається, є проблеми з flx?

Відповіді:


204

Я також зіткнувся з такою проблемою, і я поставив це.

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

Це буде працювати 100%


8
У мене було те саме питання. І навіть це працює, коли ми додаємо лише @XmlAccessorType (XmlAccessType.FIELD)
— Ram Dutt Shukla

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

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

3
Потрапив у той самий випуск із Внутрішніми класами для JAXB Annotation. Розміщення @XmlAccessorType (XmlAccessType.FIELD) на внутрішніх класах працювало!
— Шойб Хан

Дивовижне, дуже дякую У поєднанні з Ломбоком дуже корисно
— Майкл

25

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


Це правильно, я щойно видалив анотацію з учасника і поставив її на рівні сетера, і вона спрацювала.
— Варун

22

Я також бачив деякі подібні проблеми, як це.

Я думаю, це через місця , де ми використовуємо « @XMLElement » анотацію в (бобу) класу.

І я думаю, що JAXB (процесор анотацій) розглядає метод поля & getter того ж елемента поля як різні властивості, коли ми використовуємо анотацію @XMLElement на рівні поля та викидає виняток IllegalAnnotationExceptions .

Повідомлення про виняток:

Клас має два властивості з однойменною назвою "timeSeries"

Метод Геттера:

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

У полі учасників:

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

Рішення: Замість використання @XmlElement в полі використовуйте його в методі getter .


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") захищений список <TimeSeries> timeSeries;
— redfox26

4
також я змінюю (XmlAccessType.FIELD) на (XmlAccessType.NONE), я можу тримати XmlElement на рівні учасника
— redfox26

Мені також потрібно було додати @XmlTransient до змінної
— HomeIsWhereThePcIs

8

Ви також повинні налаштувати клас, ModeleREPяк і @XmlAccessorType(XmlAccessType.FIELD)з класомTimeSeries .

Погляньте на OOXS


8

Якщо ми використовуємо наведені нижче анотації та видалимо анотацію "@XmlElement", код повинен працювати належним чином, і в результаті XML матиме назви елементів, схожих на члена класу.

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

Якщо використання "@XmlElement" дійсно потрібно, будь ласка, визначте його як рівень поля і код повинен працювати ідеально. Не визначайте примітку вгорі методу отримання.

Спробував обидва вищезазначені підходи та вирішив проблему.


7

"Клас має два властивості виключення з однойменною назвою" може статися, коли у вас є член класу x із загальнодоступним рівнем доступу та getter / setter для одного члена.

Як правило, не рекомендується використовувати загальнодоступні рівень доступу разом з геттерами та сетерами.

Перевірте це для отримання більш детальної інформації: Публічна власність VS Приватна власність з геттером?

Щоб виправити це:

  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 проаналізує її на додаток до анотованих методів getter / setter та виплюне виняток. Це чудовий приклад, коли дизайнери бібліотек jabx пройшли додаткову милю в роздумах, намагаючись створити гнучкість, і в кінцевому підсумку полегшили недійсні конфігурації. Я вирішив проблему самостійно, змінивши одночасно один рядок коду, відслідковуючи змінну члена.
— Vortex

4

Та сама проблема, з якою я стикався, додав я

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

і зараз це працює.


3

Він буде працювати, коли ви помістите свою анотацію перед "getters" та видалите її із захищених атрибутів:

protected String codingScheme;

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

Я теж стикаюся з тією ж проблемою. Я теж помітив, що коли анотація позначена над атрибутами, я це бачу. Чи означає це, що завжди його слід ставити перед геттерами ?.
— Pavan Dittakavi

@Pavan Так, я так думаю. Інакше це викликає у мене ті ж проблеми, що і ви
— Лілія

2

Я просто зіткнувся з цією проблемою і вирішив її.

Джерелом проблеми є те, що у вас є і XmlAccessType.FIELD, і пари геттерів і сеттерів. Рішення полягає в тому, щоб видалити сетери та додати конструктор за замовчуванням та конструктор, який приймає всі поля.


У мене була така ж помилка, і примітка, яку ви згадали, вирішила її, дякую!
— gyorgyabraham

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 до кожного ресурсу було єдиним способом виправити цю проблему. Дякую!
— Ральф Рітох

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

Сподіваюся, це допомагає!


Ви згадуєте "Простий спосіб". Цікаво, чи є якийсь інший вихід із цього - будь-яка інша примітка, яку можна використати?
— Pavan Dittakavi

0

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

Коли використовувати який?

випадок 1 : Якщо ваші поля та ім’я елементів, які ви хочете використовувати у файлі xml, відрізняються, то вам доведеться використовувати @XMLElement(name="elementName"). Оскільки це пов'язує поля з назвою цього елемента та відображатиметься у XML-файлі.

випадок 2 : Якщо імена полів і відповідне ім’я елемента в xml обидва однакові, ви можете просто використовувати@XmlAccessorType(XmlAccessType.FIELD)


0

Було дано багато рішень, і внутрішні питання коротко торкнулися @Sriram та @ptomli. Я просто хочу додати кілька посилань на вихідний код, щоб допомогти зрозуміти, що відбувається під кришкою.

За замовчуванням (тобто ніяких додаткових приміток, які використовуються зовсім, крім @XmlRootElementкореневого класу), JABX намагається здійснити маршал речей, викритих двома способами:

  1. публічні поля
  2. getter методи , які названі відповідно до конвенції та мають відповідний метод сеттера.

Зауважте, що якщо поле (або метод повертається) null, воно не буде записане у висновок.

Тепер, якщо @XmlElementвикористовується, непублічні речі (це можуть бути поля або способи отримання) також можуть бути скасовані.

Але два способи, тобто поля та методи отримання, не повинні суперечити один одному. Інакше ви отримуєте виняток .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.