JAXB и полиморфизм - PullRequest
       16

JAXB и полиморфизм

3 голосов
/ 21 февраля 2012

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

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

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

    @XmlAttribute
    abstract Object getValue ();
}

И вот класс, который расширяет абстрактный класс id:

@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 в Java просто генерирует исключение, если вы пытаетесь маршалировать что-то типа AbstractID.

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

1 Ответ

3 голосов
/ 21 февраля 2012

Может быть ошибка с реализацией 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);
    }

}

Для получения дополнительной информации:

<Ч />

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

Для получения дополнительной информации

...