Jaxb, Class aynı isimli iki özelliğe sahiptir


121

jaxb ile bir xml dosyasını okumaya çalışıyorum, sadece xml dosyasındaki birkaç öğe ilginç, bu yüzden birçok öğeyi atlamak istiyorum

xml içeriği

xml okumaya çalışıyorum

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

sınıfım

@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 dosyasını okumaya çalıştığımda alıyorum

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

bu hatayı anlamıyorum

düzenleme: jaxb-impl-2.1.12 kullanıyorum

tamam şimdi herhangi bir hatam yok ama nesnemi kontrol ettiğimde timeSeries boş ...

belki jaxb flx ile sorun yaşıyor gibi görünüyor?

Yanıtlar:


204

Ben de böyle bir problemle karşılaştım ve bunu ayarladım.

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

Bu% 100 çalışacak


8
Ben de aynı sorunu yaşadım. Sadece @XmlAccessorType (XmlAccessType.FIELD) eklediğimizde bile işe yarıyor
Ram Dutt Shukla

2
Ben sorunu çözüldü kaldırarak@XmlAccessorType(XmlAccessType.FIELD) ek açıklama
Hans Wouters

Kulağa tuhaf geliyor, ancak bu istisnadan da bir çift ek açıklama \ @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) 'i yalnızca \ @XmlRootElement
Alex InTechno

3
JAXB Annotation için Inner sınıflarında aynı sorunla karşılaşıldı. @XmlAccessorType (XmlAccessType.FIELD) 'i iç sınıflara yerleştirmek işe yaradı!
-Shoaib Khan

Harika, çok teşekkür ederim. Lombok ile kombinasyon halinde çok yardımcı oldu
Michael Hegner

25

Hangi JAXB-IMPL sürümünü kullandığınızı belirtmediniz, ancak bir kez aynı sorunu yaşadım (jaxb-impl 2.0.5 ile) ve üye düzeyinde kullanmak yerine alıcı düzeyinde ek açıklamayı kullanarak çözdüm.


Bu doğru, ek açıklamayı üyeden kaldırdım ve ayarlayıcı seviyesine koydum ve işe yaradı.
Varun

22

Bunun gibi bazı benzer sorunlar da gördüm.

Bence, (bean) sınıfındaki " @XMLElement " açıklamasını kullandığımız yer yüzünden .

Ve sanırım, JAXB (ek açıklama işlemci) Kullandığımız zaman, farklı özellikleri ile aynı alan öğesi üyesi saha ve alıcı yöntemini dikkate @XMLElement de ek açıklama saha seviyesi ve atar IllegalAnnotationExceptions istisna.

İstisna Mesajı:

Sınıf sahiptir iki özelliği bir aynı adı "TimeSeries"

Getter Yönteminde:

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

Üye Alanında:

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

Çözüm: Bunun yerine kullanmanın @XmlElement içinde alanında , kullanmak alıcı yöntemiyle.


16

az önce bunu sınıfıma ekledim

@XmlAccessorType(XmlAccessType.FIELD)

bir cham gibi çalıştı


Lombok'un @Data ek açıklaması ile birlikte çalışır.
digz6666

16

Birden fazla çözüm vardır, ancak temelde değişken bildirimine açıklama eklerseniz ihtiyacınız olur @XmlAccessorType(XmlAccessType.FIELD), ancak bir get veya set yöntemine açıklama eklemeyi tercih ederseniz, o zaman yapmazsınız.

Böylece şunları yapabilirsiniz:

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

Veya:

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

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

Olağanüstü. Teşekkürler :) +1
Anish B.

11

JAXB'niz hem getTimeSeries()yönteme hem de üyeye bakıyor timeSeries. Hangi JAXB uygulamasını veya yapılandırmasını kullandığınızı söylemiyorsunuz, ancak istisna oldukça açık.

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

ve

korumalı java.util.List testjaxp.ModeleREP.timeSeries adresinde

JAXB öğelerini ek açıklamaları (size göre @XmlElement(name="TimeSeries")) kullanacak ve genel yöntemleri yok sayacak şekilde yapılandırmanız gerekir .


zaten yapıyorum: @XmlElement (name = "TimeSeries") korumalı Liste <TimeSeries> timeSeries;
redfox26

4
ayrıca (XmlAccessType.FIELD) 'i (XmlAccessType.NONE) olarak değiştiriyorum, XmlElement'i üye seviyesinde tutabiliyorum
redfox26

Değişkene @XmlTransient'i de eklemem gerekiyordu
HomeIsWhereThePcIs

8

Sen yapılandırmak sınıfına ihtiyaç ModeleREPyanı ile @XmlAccessorType(XmlAccessType.FIELD)sınıfta yaptığı gibi TimeSeries.

OOXS'a tüm göz atın


8

Aşağıdaki ek açıklamaları kullanırsak ve "@XmlElement" açıklamasını kaldırırsak, kod düzgün çalışmalı ve ortaya çıkan XML, sınıf üyesine benzer öğe adlarına sahip olacaktır.

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

"@XmlElement" kullanımı gerçekten gerekliyse, lütfen bunu alan seviyesi olarak tanımlayın ve kod mükemmel çalışmalıdır. Alıcı yönteminin üst kısmındaki açıklamayı tanımlamayın.

Yukarıda belirtilen her iki yaklaşımı da denemiş ve sorunu çözmüştü.


7

"Sınıfın aynı ada sahip iki özelliği vardır" istisnası , genel erişim düzeyine sahip bir sınıf üyesi x ve aynı üye için alıcı / ayarlayıcıya sahip olduğunuzda ortaya çıkabilir.

Java kuralı olarak, alıcılar ve ayarlayıcılarla birlikte bir genel erişim düzeyinin kullanılması önerilmez .

Daha fazla ayrıntı için şunu kontrol edin: Kamu mülküne karşı alıcılı özel mülk?

Bunu düzeltmek için:

  1. Üyenizin erişim düzeyini özel olarak değiştirin ve alıcı / ayarlayıcınızı saklayın
  2. Üye alıcı ve ayarlayıcıyı kaldırın

6

Bunlar JAXB'nin baktığı iki özellik.

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

ve

protected java.util.List testjaxp.ModeleREP.timeSeries

Bu, aşağıda belirtildiği gibi, alma yönteminde JAXB ek açıklaması kullanılarak önlenebilir.

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

5

XML'ye dönüştürmek istediğiniz sınıfta üye değişkenleri özel olarak bildirmeniz yeterlidir. Mutlu kodlama


Kabul edilen çözüm bu olmalıdır. Üye değişkeninizi public olarak bildirirseniz, JABX, alıcı / ayarlayıcı açıklamalı yöntemlere ek olarak onu ayrıştırır ve istisnayı kullanır. Bu, jabx kütüphane tasarımcılarının esneklik yaratmaya çalışırken yansıma konusunda fazladan bir mil gittiği ve geçersiz yapılandırmaları kolaylaştırdığı harika bir örnek. Üye değişkeni takip ederek, bir seferde bir kod satırını değiştirerek sorunu kendi başıma çözdüm.
Girdap

4

Karşılaştığım problemin aynısını ekledim

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

ve şimdi çalışıyor.


3

Ek açıklamanızı alıcıların önüne koyduğunuzda ve korumalı özelliklerden kaldırdığınızda çalışacaktır:

protected String codingScheme;

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

Ben de aynı problemle karşılaşıyorum. Ben de ek açıklama niteliklerin üzerine işaretlendiğinde bunu gördüğümü gözlemledim. Bu, her zaman alıcılardan önce yerleştirilmesi gerektiği anlamına mı geliyor?
Pavan Dittakavi

@Pavan Evet öyle düşünüyorum. Aksi takdirde, bana seninle aynı sorunlara neden oluyor
Lilia

2

Bu problemle yeni karşılaştım ve çözdüm.

Sorunun kaynağı, hem XmlAccessType.FIELD hem de alıcı ve ayarlayıcı çiftlerine sahip olmanızdır. Çözüm, ayarlayıcıları kaldırmak ve varsayılan bir kurucu ve tüm alanları alan bir kurucu eklemektir.


Ben de aynı hatayı aldım ve bahsettiğiniz ek açıklama sorunu çözdü, teşekkürler!
gyorgyabraham

1

Aşağıdaki gibi imzalı bir hizmet sınıfım vardı "

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

Çalışırken FetchIQAStatusResponseVOalanlar için aynı hatayı aldım . Az önce şunun üstüne bir satır ekledim FetchIQAStatusResponseVO:

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

ve bu sorunu çözdü.


1

ModeleREP#getTimeSeries()@Transientek açıklamalı olmak zorunda . Bu yardımcı olur.


0

İle açıklama @XmlTransienteklemek bu sorunu çözer

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

Daha fazla ayrıntı için http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html adresine bakın


1
Bunun bir çözümden çok bir hack olduğunu düşünüyorum. Bu, jaxb'ye, aynı şey olduğunun farkına varmak yerine, yöntemi görmezden gelmesini söyler.
Hans Wouters

Bu, bir hatadan daha kısa bir şey olarak tanımlanamayan bir şeyin üstesinden gelmek için en iyi çözümdür, çoğunlukla göz ardı edilen @XmlAccessorType (XmlAccessType.FIELD) kullandım ve her özelliğe @XmlTransient eklemenin tek yolu buydu. bu sorunu onarın. Teşekkürler!
Ralph Ritoch

0

Bu sorunu çözmenin hızlı ve basit bir yolu @XmlElement(name="TimeSeries"), değişken bildirim ifadesinin protected List<TimeSeries> timeSeries;en üstünden alıcısının en üstüne kaldırmaktır public List<TimeSeries> getTimeSeries().

Böylece ModeleREPsınıfınız şöyle görünecek:

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

Umarım yardımcı olur!


"Basit bir yol" dan bahsediyorsunuz. Merak ediyorum, bundan başka bir çıkış yolu var mı - kaldırılabilecek başka açıklama yok mu?
Pavan Dittakavi

0

Deneme yanılma yaptım ve sonuca vardım, sadece ikisinden birini @XMLElementveya ikisini birden kullanmanız gerekiyor @XmlAccessorType(XmlAccessType.FIELD).

Hangisi ne zaman kullanılır?

durum 1 : xml dosyasında kullanmak istediğiniz alan adlarınız ve eleman adınız farklıysa, kullanmanız gerekir @XMLElement(name="elementName"). Bu, alanları bu öğe adına bağlayacak ve XML dosyasında gösterecektir.

durum 2 : xml'deki alan adları ve ilgili öğe adlarının her ikisi de aynıysa,@XmlAccessorType(XmlAccessType.FIELD)


0

Birçok çözüm verilmiş ve iç kısımlara @Sriram ve @ptomli tarafından da kısaca değinilmiştir. Kaputun altında neler olduğunu anlamanıza yardımcı olması için kaynak koduna birkaç referans eklemek istiyorum.

Varsayılan olarak (yani @XmlRootElement, kök sınıf dışında hiçbir ek açıklama kullanılmaz ), JABX ortaya çıkan şeyleri iki yolla sıralamayı dener:

  1. halka açık alanlar
  2. Kuralı takiben adlandırılan ve karşılık gelen bir ayarlayıcı yöntemine sahip alıcı yöntemleri .

Bir alan ise (veya yöntem geri dönerse) null, çıktıya yazılmayacağına dikkat edin.

Şimdi @XmlElementkullanılırsa, halka açık olmayan şeyler (alanlar veya alıcı yöntemler olabilir) de sıralanabilir.

Ancak iki yol, yani alanlar ve alıcı yöntemler birbiriyle çelişmemelidir. Aksi takdirde istisna elde edersiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.