Jaxb, Class에는 같은 이름의 두 가지 속성이 있습니다.


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가 null입니다 ...

그래서 jaxb가 flx에 문제가있는 것 같나요?

답변:


204

나는 또한 이와 같은 문제에 직면했고 이것을 설정했습니다.

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

이것은 100 % 작동합니다


8
나는 같은 문제가 있었다. 우리는 @XmlAccessorType (XmlAccessType.FIELD)를 추가 할 때조차 그것을 작동합니다
램 더트 Shukla

2
나는하여 문제를 해결 제거@XmlAccessorType(XmlAccessType.FIELD) 주석
한스 Wouters

이상하게 들리지만 주석 쌍 \ @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD)을 \ @XmlRootElement
Alex InTechno로만 줄여이

3
JAXB Annotation의 내부 클래스와 동일한 문제가 발생했습니다. 내부 클래스에 @XmlAccessorType (XmlAccessType.FIELD)을 배치하면 효과가 있습니다!
Shoaib Khan

정말 감사합니다. 매우 도움이 롬복와 함께
마이클 Hegner

25

사용중인 JAXB-IMPL 버전을 지정하지 않았지만 동일한 문제 (jaxb-impl 2.0.5 사용)가 발생하고 멤버 수준에서 사용하는 대신 getter 수준에서 주석을 사용하여 해결했습니다.


맞습니다. 멤버에서 주석을 제거하고 setter 수준에 놓았으며 작동했습니다.
Varun

22

나는 또한 이와 같은 유사한 문제를 보았습니다.

(bean) 클래스에서 " @XMLElement " 주석 을 사용하는 때문이라고 생각합니다 .

그리고 JAXB (주석 처리기) 는 필드 수준 에서 @XMLElement 주석을 사용 하고 IllegalAnnotationExceptions 예외를 throw 할 때 동일한 필드 요소의 멤버 필드 및 getter 메서드를 다른 속성으로 간주한다고 생각합니다 .

예외 메시지 :

클래스에는 "timeSeries" 라는 동일한 이름두 속성 이 있습니다.

Getter 메서드에서 :

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

회원 필드에서 :

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

솔루션 : 필드 에서 @XmlElement 를 사용하는 대신 getter 메서드 에서 사용하십시오 .


16

내 수업에 이것을 추가했습니다.

@XmlAccessorType(XmlAccessType.FIELD)

참처럼 일했다


lombok의 @Data 주석과 함께 작동합니다.
digz6666

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 구현을 사용하고 있는지 또는 그 구성을 말하지 않지만 예외는 상당히 분명합니다.

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

보호 된 java.util.List testjaxp.ModeleREP.timeSeries에서

주석을 사용 @XmlElement(name="TimeSeries")하고 공용 메서드를 무시 하도록 JAXB 항목을 구성해야 합니다.


나는 이미 : @XmlElement (name = "TimeSeries") protected List <TimeSeries> timeSeries;
redfox26

4
또한 (XmlAccessType.FIELD)를 (XmlAccessType.NONE)으로 변경하면 XmlElement를 멤버 수준으로 유지할 수 있습니다
redfox26

나는 또한 변수에 @XmlTransient를 추가해야했습니다
HomeIsWhereThePcIs

8

class ModeleREP@XmlAccessorType(XmlAccessType.FIELD)마찬가지로 class를 구성해야합니다 TimeSeries.

OOXS 살펴보기


8

아래 주석을 사용하고 "@XmlElement"주석을 제거하면 코드가 제대로 작동하고 결과 XML은 클래스 멤버와 유사한 요소 이름을 갖게됩니다.

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

"@XmlElement"사용이 정말 필요한 경우 필드 레벨로 정의하면 코드가 완벽하게 작동합니다. getter 메서드 상단에 주석을 정의하지 마십시오.

위에서 언급 한 두 가지 방법을 모두 시도하고 문제를 해결했습니다.


7

"클래스에는 동일한 이름의 두 속성이 있습니다. 예외" 는 공용 액세스 수준을 가진 클래스 멤버 x와 동일한 멤버에 대한 getter / setter가있을 때 발생할 수 있습니다.

Java 경험의 규칙에 따라 공용 을 사용하지 않는 것이 좋습니다. getter 및 setter와 함께 액세스 수준 .

자세한 내용은 다음을 확인하십시오. Getter를 사용하는 Public 속성 VS Private 속성?

이를 수정하려면 :

  1. 회원의 액세스 수준을 비공개로 변경 하고 getter / setter를 유지하세요.
  2. 구성원의 getter 및 setter 제거

6

다음은 JAXB가보고있는 두 가지 속성입니다.

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

protected java.util.List testjaxp.ModeleREP.timeSeries

이것은 아래 언급 된 것처럼 get 메소드에서 JAXB 주석을 사용하여 피할 수 있습니다.

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

5

XML로 변환하려는 클래스에서 멤버 변수를 private으로 선언하기 만하면됩니다. 즐거운 코딩


이것이 허용되는 솔루션이어야합니다. 멤버 변수를 public으로 선언하면 JABX는 getter / setter 주석이 달린 메서드와 함께이를 구문 분석하고 예외를 뱉어냅니다. jabx 라이브러리 디자이너가 유연성을 생성하기 위해 리플렉션에 추가 노력을 기울 였고 결국 잘못된 구성을 촉진 한 훌륭한 예입니다. 한 번에 한 줄의 코드를 변경하고 멤버 변수를 추적하여 문제를 직접 해결했습니다.
Vortex

4

내가 직면했던 동일한 문제, 나는 추가했다

@XmlRootElement(name="yourRootElementName")

@XmlAccessorType(XmlAccessType.FIELD)

이제 작동합니다.


3

getter 앞에 주석을 넣고 보호 된 속성에서 제거하면 작동합니다.

protected String codingScheme;

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

나도 같은 문제에 직면하고 있습니다. 저도 어노테이션이 속성 위에 표시 될 때 이것을 보는 것을 관찰했습니다. 이것은 항상 게터 앞에 배치되어야 함을 의미합니까?
Pavan Dittakavi

@Pavan 네 그렇게 생각합니다. 그렇지 않으면 나에게 당신과 같은 문제가 발생합니다
Lilia

2

방금이 문제에 부딪혀 해결했습니다.

문제의 원인은 XmlAccessType.FIELD와 getter 및 setter 쌍이 모두 있다는 것입니다. 해결책은 setter를 제거하고 기본 생성자와 모든 필드를 사용하는 생성자를 추가하는 것입니다.


나는 같은 오류가 있었고 당신이 언급 한 주석이 그것을 해결했습니다. 감사합니다!
gyorgyabraham 2013

1

다음과 같은 서명이있는 서비스 클래스가 있습니다. "

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

실행시 FetchIQAStatusResponseVO필드에 대해 동일한 오류가 발생했습니다 . 방금 다음 줄을 추가했습니다 FetchIQAStatusResponseVO.

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

그리고 이것은 문제를 해결했습니다.


1

ModeleREP#getTimeSeries()@Transient주석 과 함께 있어야합니다 . 도움이 될 것입니다.


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 2015 년

해킹 여부는 버그가 아닌 것으로 설명 할 수없는 문제를 해결하는 가장 좋은 솔루션입니다. 대부분 무시되는 @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. 규칙에 따라 이름이 지정 되고 해당하는 setter 메소드가있는 getter 메소드 .

필드가 (또는 메서드가 반환 null되는 경우) 출력에 기록되지 않습니다.

이제 @XmlElement가 사용되면 비공개 항목 (필드 또는 getter 메서드 일 수 있음)도 마샬링 할 수 있습니다.

그러나 두 가지 방법, 즉 필드와 getter-method는 서로 충돌하지 않아야합니다. 그렇지 않으면 예외가 발생 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.