2012-02-21 3 views
3

У меня возникли проблемы с получением следующей структуры классов, упорядоченной реализацией Java JAXB. У меня есть абстрактный класс идентификатора, который имеет значение.JAXB и полиморфизм

Для меня важно, чтобы значение было представлено как атрибут.

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

    @XmlAttribute 
    abstract Object getValue(); 
} 

А, вот это класс, который расширяет абстрактный класс ID: реализация JAXB

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

В настоящее время в Java просто бросает исключение, если вы пытаетесь Маршалл что-то типа AbstractID.

Это нарушение чего-то в стандарте JAXB или реализация Java JAXB нарушена?

ответ

3

Может возникнуть ошибка с реализацией JAXB, включенной в JDK. Использование JDK 1.6.0_29 я получаю исключение, что вы, вероятно, видя:

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) 

Запуск же демонстрационный код с EclipseLink JAXB (MOXy) я получаю следующий вывод (я в 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:


UPDATE

Если вам нужно использовать JAXB RI включены в Java 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

Спасибо. Любая идея, как я могу аннотировать AbstractID, чтобы заставить его работать с реализацией Java JAXB? Я использую JAXB через CXF для создания WSDL. Мне нужен код, сгенерированный из WSDL, для генерации AbstractID с помощью метода getValue(). – rouble

+0

@prmatta - Я добавил обновление, которое может работать с RI JAXB. –

+0

Я думаю, что проблема в том, что в сгенерированном WSDL и в коде, сгенерированном из WSDL, AbstractID теперь будет пустым классом, а AbstractIDInt имеет поле «значение». Таким образом, кто-то, кто хочет получить значение, сначала должен будет передать в AbstractIDInt. Это не идеально, так как невозможно узнать, какой производный тип нужно отличить. Мне нужно, чтобы поле «значение» нужно унаследовать от AbstractID. Любые другие идеи? – rouble

Смежные вопросы