Jaxb, Class memiliki dua properti dengan nama yang sama


120

dengan jaxb, saya mencoba membaca file xml hanya beberapa elemen dalam file xml yang menarik, jadi saya ingin melewatkan banyak elemen

konten xml

xml saya mencoba membaca

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

kelasku

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

ketika saya mencoba membaca file xlm saya mengerti

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

saya tidak mengerti kesalahan ini

edit: saya menggunakan jaxb-impl-2.1.12

ok sekarang saya tidak mengalami kesalahan, tetapi ketika saya memeriksa objek saya, timeSeries adalah null ...

jadi mungkin jaxb sepertinya bermasalah dengan flx?

Jawaban:


204

Saya juga menghadapi masalah seperti ini dan saya mengatur ini.

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

Ini akan berhasil 100%


8
Saya memiliki masalah yang sama. Dan bahkan itu berfungsi ketika kita hanya menambahkan @XmlAccessorType (XmlAccessType.FIELD)
Ram Dutt Shukla

2
Aku memecahkan masalah ini dengan menghapus para @XmlAccessorType(XmlAccessType.FIELD)penjelasan
Hans Wouters

Kedengarannya aneh, tetapi saya juga menyingkirkan pengecualian ini dengan mengurangi pasangan anotasi \ @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) menjadi hanya \ @XmlRootElement
Alex InTechno

3
Mengalami masalah yang sama dengan kelas dalam untuk Anotasi JAXB. Menempatkan @XmlAccessorType (XmlAccessType.FIELD) pada kelas dalam berhasil!
Shoaib Khan

Luar biasa, terima kasih banyak. Dalam kombinasi dengan Lombok sangat membantu
Michael Hegner

25

Anda tidak menentukan versi JAXB-IMPL yang Anda gunakan, tetapi pernah saya mengalami masalah yang sama (dengan jaxb-impl 2.0.5) dan menyelesaikannya menggunakan anotasi di tingkat pengambil alih-alih menggunakannya di tingkat anggota.


Itu benar, saya baru saja menghapus anotasi dari anggota dan meletakkannya di tingkat penyetel dan berhasil.
Varun

22

Saya juga melihat beberapa masalah serupa seperti ini.

Saya pikir, itu karena tempat kami menggunakan anotasi " @XMLElement " di kelas (bean).

Dan menurut saya, JAXB (pemroses anotasi) menganggap metode bidang & pengambil anggota dari elemen bidang yang sama sebagai properti yang berbeda, ketika kita menggunakan anotasi @XMLElement di tingkat bidang dan melontarkan pengecualian IllegalAnnotationExceptions .

Pesan Pengecualian:

Kelas memiliki dua sifat yang sama nama "Timeseries"

Di Metode Getter:

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

Di Member Field:

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

Solusi: Alih-alih menggunakan @XmlElement di lapangan , gunakan itu dalam metode pengambil .


16

baru saja menambahkan ini ke kelasku

@XmlAccessorType(XmlAccessType.FIELD)

bekerja seperti cham


Berfungsi dengan anotasi @Data lombok juga.
digz6666

16

Ada beberapa solusi tetapi pada dasarnya jika Anda membuat anotasi pada deklarasi variabel maka Anda perlu @XmlAccessorType(XmlAccessType.FIELD), tetapi jika Anda lebih suka memberi anotasi baik get- atau set-method maka Anda tidak melakukannya.

Jadi Anda bisa melakukan:

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

Atau:

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

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

Hebat. Terima kasih :) +1
Anish B.

11

JAXB Anda melihat getTimeSeries()metode dan anggotanya timeSeries. Anda tidak mengatakan implementasi JAXB mana yang Anda gunakan, atau konfigurasinya, tetapi pengecualiannya cukup jelas.

di java.util.List publik testjaxp.ModeleREP.getTimeSeries ()

dan

di java.util.List dilindungi testjaxp.ModeleREP.timeSeries

Anda perlu mengonfigurasi barang-barang JAXB Anda untuk menggunakan anotasi (sesuai kebutuhan Anda @XmlElement(name="TimeSeries")) dan mengabaikan metode publik.


saya sudah melakukan: @XmlElement (name = "TimeSeries") protected List <TimeSeries> timeSeries;
redfox26

4
juga saya mengubah (XmlAccessType.FIELD) menjadi (XmlAccessType.NONE), saya dapat menyimpan XmlElement di tingkat anggota
redfox26

Saya juga perlu menambahkan @XmlTransient ke variabel
HomeIsWhereThePcIs

8

Anda perlu kelas configure ModeleREPjuga dengan @XmlAccessorType(XmlAccessType.FIELD)seperti yang Anda lakukan dengan kelas TimeSeries.

Lihat juga OOXS


8

Jika kita menggunakan anotasi di bawah ini dan menghapus anotasi "@XmlElement", kode harus bekerja dengan baik dan XML yang dihasilkan akan memiliki nama elemen yang mirip dengan anggota kelas.

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

Jika penggunaan "@XmlElement" benar-benar diperlukan, harap tentukan sebagai tingkat bidang dan kode harus berfungsi dengan sempurna. Jangan mendefinisikan anotasi di atas metode pengambil.

Telah mencoba kedua pendekatan yang disebutkan di atas dan harus memperbaiki masalah.


7

"Kelas memiliki dua properti dengan pengecualian nama yang sama" dapat terjadi jika Anda memiliki anggota kelas x dengan tingkat akses publik dan pengambil / penyetel untuk anggota yang sama.

Sebagai aturan praktis java, tidak disarankan untuk menggunakan tingkat akses publik bersama dengan getter dan setter.

Periksa ini untuk lebih jelasnya: Properti publik VS Properti pribadi dengan pengambil?

Untuk memperbaikinya:

  1. Ubah tingkat akses anggota Anda menjadi pribadi dan pertahankan pengambil / penyetel Anda
  2. Hapus pengambil dan penyetel anggota

6

Ini adalah dua properti yang dilihat JAXB.

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

dan

protected java.util.List testjaxp.ModeleREP.timeSeries

Hal ini dapat dihindari dengan menggunakan anotasi JAXB pada metode get seperti yang disebutkan di bawah ini.

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

5

cukup deklarasikan variabel anggota menjadi private di kelas yang ingin Anda ubah ke XML. Selamat membuat kode


Ini harus menjadi solusi yang diterima. Jika Anda mendeklarasikan variabel anggota Anda sebagai publik, JABX akan menguraikannya sebagai tambahan untuk metode beranotasi pengambil / penyetel dan mengeluarkan pengecualian. Ini adalah contoh yang bagus di mana perancang pustaka jabx bekerja ekstra pada refleksi mencoba menciptakan fleksibilitas dan akhirnya memfasilitasi konfigurasi yang tidak valid. Saya memperbaiki masalah saya sendiri dengan mengubah satu baris kode pada saat itu, menelusuri kembali ke variabel anggota.
Vortex

4

Masalah yang sama yang saya hadapi, saya menambahkan

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

dan sekarang berfungsi.


3

Ini akan berfungsi ketika Anda meletakkan anotasi Anda sebelum getter, dan menghapusnya dari atribut yang dilindungi:

protected String codingScheme;

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

Saya juga mengalami masalah yang sama. Saya juga telah mengamati bahwa ketika anotasi ditandai di atas atribut, saya melihat ini. Apakah ini berarti bahwa selalu harus ditempatkan sebelum getter ?.
Pavan Dittakavi

@Pavan Ya saya kira begitu. Jika tidak, itu menyebabkan saya masalah yang sama dari Anda
Lilia

2

Saya baru saja mengalami masalah ini dan menyelesaikannya.

Sumber masalahnya adalah Anda memiliki XmlAccessType.FIELD dan pasangan getter dan setter. Solusinya adalah menghapus penyetel dan menambahkan konstruktor default dan konstruktor yang mengambil semua bidang.


Saya mengalami kesalahan yang sama dan anotasi yang Anda sebutkan mengatasinya, terima kasih!
gyorgyabraham

1

Saya memiliki kelas layanan dengan tanda tangan seperti di bawah ini "

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

Saat dijalankan saya mendapat kesalahan yang sama untuk FetchIQAStatusResponseVObidang. Saya baru saja menambahkan baris di atas FetchIQAStatusResponseVO:

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

dan ini menyelesaikan masalah.


1

ModeleREP#getTimeSeries()harus dengan @Transientpenjelasan. Itu akan membantu.


0

Menganotasi dengan @XmlTransientmenyelesaikan masalah itu

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

Lihat http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html untuk lebih jelasnya


1
Saya pikir ini lebih merupakan peretasan daripada solusi. Ini memberitahu jaxb untuk mengabaikan metode tersebut, alih-alih membuatnya sadar bahwa itu adalah hal yang sama.
Hans Wouters

Retas atau tidak ini IS solusi terbaik untuk menyiasati sesuatu yang tidak dapat digambarkan sebagai sesuatu yang pendek dari bug, saya menggunakan @XmlAccessorType (XmlAccessType.FIELD) yang sebagian besar diabaikan dan menambahkan @XmlTransient ke setiap properti adalah satu-satunya cara untuk perbaiki masalah ini. Terima kasih!
Ralph Ritoch

0

Cara cepat dan sederhana untuk memperbaiki masalah ini adalah dengan menghapus @XmlElement(name="TimeSeries")pernyataan deklarasi variabel protected List<TimeSeries> timeSeries;dari atas ke atas getter public List<TimeSeries> getTimeSeries(),.

Dengan demikian ModeleREPkelas Anda akan terlihat seperti:

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

Semoga membantu!


Anda menyebut 'Cara sederhana'. Penasaran, apakah ada jalan keluar lain - atau anotasi lain yang dapat dimanfaatkan ?.
Pavan Dittakavi

0

Saya melakukan trial and error dan mendapat kesimpulan bahwa, Anda hanya perlu menggunakan salah satu dari keduanya @XMLElementatau @XmlAccessorType(XmlAccessType.FIELD).

Kapan menggunakan yang mana?

kasus 1 : Jika nama bidang dan nama elemen yang ingin Anda gunakan dalam file xml berbeda maka Anda harus menggunakan @XMLElement(name="elementName"). Karena ini akan mengikat bidang dengan nama elemen itu dan ditampilkan dalam file XML.

case 2 : Jika nama field dan masing-masing nama elemen dalam xml sama, maka Anda dapat menggunakan@XmlAccessorType(XmlAccessType.FIELD)


0

Banyak solusi telah diberikan, dan bagian dalamnya secara singkat disentuh oleh @Sriram dan @ptomli juga. Saya hanya ingin menambahkan beberapa referensi ke kode sumber untuk membantu memahami apa yang terjadi di balik terpal.

Secara default (yaitu tidak ada penjelasan tambahan yang digunakan sama sekali kecuali @XmlRootElementpada kelas root), JABX mencoba untuk mengatur hal-hal yang diekspos melalui dua cara:

  1. bidang publik
  2. metode pengambil yang diberi nama mengikuti konvensi dan memiliki metode penyetel yang sesuai.

Perhatikan bahwa jika bidang adalah (atau metode kembali) null kolom , itu tidak akan ditulis ke dalam output.

Sekarang jika @XmlElement digunakan, hal-hal non-publik (bisa berupa bidang atau metode pengambil) dapat diatur juga.

Tetapi dua cara, yaitu field dan metode pengambil, tidak boleh saling bertentangan. Jika tidak, Anda mendapatkan pengecualian .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.