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


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.