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-im-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)บันทึกย่อ
ฮันส์ Wouters

ฟังดูแปลก แต่ฉันก็กำจัดข้อยกเว้นนี้ด้วยการลดคู่คำอธิบายประกอบ \ @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) ให้เหลือเพียง \ @XmlRootElement
Alex InTechno

3
พบปัญหาเดียวกันกับคลาสภายในสำหรับ JAXB Annotation การวาง @XmlAccessorType (XmlAccessType.FIELD) ในคลาสภายในได้ผล!
Shoaib Khan

สุดยอดขอบคุณมาก เมื่อใช้ร่วมกับลอมบอกมีประโยชน์มาก
Michael Hegner

25

คุณไม่ได้ระบุว่าคุณใช้ JAXB-IMPL เวอร์ชันใด แต่เมื่อฉันมีปัญหาเดียวกัน (กับ jaxb-im 2.0.5) และแก้ไขโดยใช้คำอธิบายประกอบที่ระดับ getter แทนที่จะใช้ในระดับสมาชิก


ถูกต้องฉันเพิ่งลบคำอธิบายประกอบออกจากสมาชิกและวางไว้ที่ระดับ setter และใช้งานได้
Varun

22

ฉันเคยเห็นปัญหาที่คล้ายกันเช่นนี้

ฉันคิดว่าเป็นเพราะสถานที่ที่เราใช้คำอธิบายประกอบ " @XMLElement " ในคลาส (bean)

และฉันคิดว่าJAXB (ตัวประมวลผลคำอธิบายประกอบ) ถือว่าเมธอดฟิลด์สมาชิก & getter ขององค์ประกอบฟิลด์เดียวกันเป็นคุณสมบัติที่แตกต่างกันเมื่อเราใช้ คำอธิบายประกอบ@XMLElementที่ระดับฟิลด์และแสดงข้อยกเว้นIllegalAnnotationExceptions

ข้อความยกเว้น:

คลาสมีคุณสมบัติสองอย่างที่มี ชื่อเดียวกัน "timeSeries"

ที่วิธี Getter:

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

ที่สนามสมาชิก:

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

วิธีแก้ไข: แทนที่จะใช้@XmlElementในฟิลด์ให้ใช้ในเมธอดgetter



16

มีวิธีแก้ปัญหาหลายวิธี แต่โดยพื้นฐานแล้วหากคุณใส่คำอธิบายประกอบเกี่ยวกับการประกาศตัวแปรคุณก็จำเป็นต้องใช้@XmlAccessorType(XmlAccessType.FIELD)แต่ถ้าคุณต้องการใส่คำอธิบายประกอบทั้ง get- หรือ set-method คุณก็ไม่ทำ

ดังนั้นคุณสามารถทำได้:

@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
Anish B.

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" จริงๆโปรดกำหนดเป็นระดับฟิลด์และโค้ดควรทำงานได้อย่างสมบูรณ์ อย่ากำหนดคำอธิบายประกอบที่ด้านบนของเมธอด getter

ได้ลองใช้ทั้งสองวิธีข้างต้นที่กล่าวถึงแล้วและแก้ไขปัญหาได้


7

"คลาสมีคุณสมบัติสองข้อยกเว้นชื่อเดียวกัน"สามารถเกิดขึ้นได้เมื่อคุณมีสมาชิกคลาส x ที่มีระดับการเข้าถึงสาธารณะและ getter / setter สำหรับสมาชิกคนเดียวกัน

ตามหลักการทั่วไปของ Java ไม่แนะนำให้ใช้ระดับการเข้าถึงสาธารณะร่วมกับ getters และ setters

ตรวจสอบรายละเอียดเพิ่มเติม: ทรัพย์สินสาธารณะ VS ทรัพย์สินส่วนตัวกับ getter?

วิธีแก้ไข:

  1. เปลี่ยนระดับการเข้าถึงของสมาชิกของคุณเป็นส่วนตัวและให้ getter / setter ของคุณ
  2. ลบ getter และ setter ของสมาชิก

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

ฉันก็ประสบปัญหาเดียวกันเช่นกัน ฉันก็สังเกตเช่นกันว่าเมื่อคำอธิบายประกอบถูกทำเครื่องหมายไว้เหนือแอตทริบิวต์ฉันจะเห็นสิ่งนี้ นี่หมายความว่าควรวางไว้ตรงหน้า getters เสมอ?
Pavan Dittakavi

@Pavan ใช่ฉันคิดอย่างนั้น มิฉะนั้นจะทำให้ฉันมีปัญหาเหมือนกันกับคุณ
Lilia

2

ฉันเพิ่งพบปัญหานี้และแก้ไขได้

ต้นตอของปัญหาคือคุณมีทั้ง XmlAccessType.FIELD และคู่ของ getters และ setters วิธีแก้ปัญหาคือการลบ setters และเพิ่มตัวสร้างเริ่มต้นและตัวสร้างที่รับฟิลด์ทั้งหมด


ฉันมีข้อผิดพลาดเดียวกันและคำอธิบายประกอบที่คุณกล่าวถึงแก้ไขได้แล้วขอบคุณ!
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 เพิกเฉยต่อวิธีการนี้แทนที่จะทำให้มันรู้ว่ามันเป็นสิ่งเดียวกัน
Hans Wouters

แฮ็กหรือไม่นี่เป็นทางออกที่ดีที่สุดในการหลีกเลี่ยงสิ่งที่ไม่สามารถอธิบายได้ว่าเป็นข้อบกพร่องใด ๆ ฉันใช้ @XmlAccessorType (XmlAccessType.FIELD) ซึ่งส่วนใหญ่ถูกละเลยและการเพิ่ม @XmlTransient ให้กับแต่ละคุณสมบัติเป็นวิธีเดียวที่จะ แก้ไขปัญหานี้ ขอบคุณ!
Ralph Ritoch

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ที่ตั้งชื่อตามแบบแผนและมีเมธอด setter ที่เกี่ยวข้อง

สังเกตว่าถ้าฟิลด์เป็น (หรือวิธีการส่งคืน) nullจะไม่ถูกเขียนลงในเอาต์พุต

ตอนนี้ถ้า@XmlElementถูกใช้สิ่งที่ไม่ใช่สาธารณะ (อาจเป็นฟิลด์หรือเมธอด getter) ก็สามารถนำมาใช้งานได้เช่นกัน

แต่สองวิธีคือเขตข้อมูลและวิธีการรับจะต้องไม่ขัดแย้งกัน มิฉะนั้นคุณจะได้รับการยกเว้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.