EclipseLink MOXy: поля суперкласса не устанавливаются при демаршалинге

Я ожидал бы, что поля суперкласса будут неупорядочены в приведенном ниже сценарии, но это не так. Что сделать, чтобы он работал?

Вход:

<?xml version="1.0" encoding="UTF-8"?>
<a>my text</a>

Привязка:

<?xml version="1.0"?>
<xml-bindings
 xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
 package-name="test">

<java-types>        
  <java-type name="SubClass">
    <xml-root-element name="a"/>
    <java-attributes>
        <xml-element java-attribute="text" xml-path="text()" />
    </java-attributes>
  </java-type>
</java-types>

</xml-bindings>

Классы:

public class SuperClass {

 private String text;

 public String getText() {
    return text;
 }

 public void setText(String text) {
    this.text = text;
 }
}

public class SubClass extends SuperClass { }

Демо:

Map<String, Object> jaxbContextProperties = new HashMap<String, Object>(1);
jaxbContextProperties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "bindings.xml");
JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {SuperClass.class}, jaxbContextProperties);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
SuperClass superClass = (SuperClass)unmarshaller.unmarshal(new File("input.xml"));
System.out.println(superClass.getText());   

Выход:

[EL Warning]: 2013-07-31 15:09:16.602--Ignoring attribute [text] on class [SubClass] as no Property was generated for it.
null

person hansi    schedule 31.07.2013    source источник


Ответы (2)


Отображение должно быть выполнено в классе, к которому он принадлежит.

ВАРИАНТ 1. Карта SuperClass собственности на SubClass

Если вы хотите отобразить свойства суперкласса как часть дочернего элемента, вам нужно отметить переход родительского класса в элементе java-type.

bindings.xml

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum17981925">
    <java-types>
        <java-type name="SuperClass" xml-transient="true"/>
        <java-type name="SubClass">
            <xml-root-element/>
            <java-attributes>
                <xml-element java-attribute="text" xml-path="text()" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

ВАРИАНТ № 2. Карта SuperClass собственности на SuperClass

В качестве альтернативы вы можете сопоставить свойство text с SuperClass, и это сопоставление будет унаследовано SubClass.

bindings.xml

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum17981925">
    <java-types>
        <java-type name="SuperClass">
            <java-attributes>
                <xml-element java-attribute="text" xml-path="text()" />
            </java-attributes>
        </java-type>
        <java-type name="SubClass">
            <xml-root-element/>
        </java-type>
    </java-types>
</xml-bindings>

Демонстрационный код

Можно запустить следующий демонстрационный код, чтобы убедиться, что оба варианта работают:

входной файл.xml

<subClass>Hello World</subClass>

Демо

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> jaxbContextProperties = new HashMap<String, Object>(1);
        jaxbContextProperties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "bindings.xml");
        JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {SuperClass.class}, jaxbContextProperties);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        SuperClass superClass = (SuperClass)unmarshaller.unmarshal(new File("input.xml"));
        System.out.println(superClass.getText());
    }

}

Вывод

Hello World
person bdoughan    schedule 31.07.2013
comment
Это работает, спасибо! На самом деле, у меня также есть второй файл привязок, в котором уже указан тип java (для более общего случая). Поэтому мне пришлось бы переопределить эту спецификацию типа java, которую я пробовал здесь, но не смог заставить ее работать: stackoverflow.com/questions/17982654/ - person hansi; 01.08.2013

Также поле SuperClass's может быть null, потому что у вашего SuperClass нет Setter для его поля, потому что Unmarshaller использует конструктор по умолчанию без аргументов и сеттеры для инициализации своих полей. Или SuperClass не имеет аннотаций @XmlRootElement и @XmlElement.

person Ihor Klimov    schedule 08.09.2015