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.