2012-02-21 3 views
3

Java의 JAXB 구현에서 다음 클래스 구조를 마샬링하는 데 문제가 있습니다. 값이있는 추상 식별자 클래스가 있습니다.JAXB 및 다형성

값은 attribiute로 표시해야합니다. 이 유형의 AbstractID의 마샬 뭔가하려고하면

@XmlRootElement(name = "AbstractIDInt") 
@XmlAccessorType(XmlAccessType.NONE) 
public class AbstractIDInt extends AbstractID { 
    Integer value; 

    Integer getValue() { 
     return value; 
    } 

    public void setvalue (Integer value) { 
     this.value = value; 
    } 
} 

현재 자바의 JAXB 구현은 단지 예외가 발생합니다 :

@XmlSeeAlso({ 
    AbstractIDInt.class 
}) 
@XmlRootElement(name = "AbstractID") 
@XmlAccessorType(XmlAccessType.PROPERTY) 
public abstract class AbstractID { 

    @XmlAttribute 
    abstract Object getValue(); 
} 

그리고, 여기에 추상적 인 ID 클래스를 확장하는 클래스입니다.

이것은 JAXB 표준에서 위반하고 있습니까? 아니면 JAXB의 Java 구현이 손상 되었습니까?

답변

3

JDK에 포함 된 JAXB의 구현에 버그가있을 수 있습니다. JDK 1.6.0_29 사용 나는 당신이 아마보고있는 예외를 얻을 : EclipseLink JAXB (MOXy)와 같은 데모 코드를 실행

Exception in thread "main" java.lang.NullPointerException 
    at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:154) 
    at com.sun.xml.internal.bind.v2.runtime.property.AttributeProperty.<init>(AttributeProperty.java:56) 
    at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:93) 
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100) 
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143) 
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202) 
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:376) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522) 
    at forum9382200.Demo.main(Demo.java:9) 

를 내가받을 다음과 같은 출력 (I가 MOXY 리드를 해요) :

<?xml version="1.0" encoding="UTF-8"?> 
<AbstractIDInt value="1"/> 

package forum9382200; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(AbstractID.class); 

     AbstractIDInt abstractIDInt = new AbstractIDInt(); 
     abstractIDInt.setvalue(1); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.marshal(abstractIDInt, System.out); 
    } 

} 

더 Infomration의 경우 :

다음은 내가 사용하는 데모 코드 17,451,515,

UPDATE

당신이 다음 시도 할 수있는 JAXB RI는 자바 SE에 포함 사용해야하는 경우 :

을 AbstractID

마크 @XmlTransient로 부모 클래스 :

package forum9382200; 

import javax.xml.bind.annotation.*; 

@XmlSeeAlso({ 
    AbstractIDInt.class 
}) 
@XmlTransient 
public abstract class AbstractID { 

    abstract Object getValue(); 
} 

AbstractIDInt

주석 서브 클래스에 value 특성 : 추가 정보

package forum9382200; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "AbstractIDInt") 
@XmlAccessorType(XmlAccessType.NONE) 
public class AbstractIDInt extends AbstractID { 
    Integer value; 

    @XmlAttribute 
    Integer getValue() { 
     return value; 
    } 

    public void setvalue (Integer value) { 
     this.value = value; 
    } 
} 

+0

감사합니다. JavaID의 JAXB 구현을 위해 AbstractID에 주석을 달 수있는 방법은 무엇입니까? CXF를 통해 JAXB를 사용하여 WSDL을 생성합니다. getValue() 메소드로 AbstractID를 생성하기 위해 WSDL에서 생성 된 코드가 필요하다. – rouble

+0

@prmatta - JAXB RI에서 작동하는 업데이트를 추가했습니다. –

+0

이 문제는 생성 된 WSDL과 WSDL에서 생성 된 코드에서 AbstractID는 이제 빈 클래스가 될 것이고 AbstractIDInt는 "value"필드를 갖는다 고 생각합니다. 따라서 값을 얻으려는 사람은 먼저 AbstractIDInt로 형변환해야합니다. 이것은 파생 될 파생 된 유형을 알 수 없으므로 이상적이지 않습니다. 필드 "값"을 AbstractID에서 상속해야하는 방법이 필요합니다. 다른 아이디어? – rouble