Использование универсального @XmlJavaTypeAdapter для демаршалирования в оболочке Guava
Я пытаюсь разархивировать некоторые XML-объекты в объекты Java, обернутые в необязательный компонент Guava, используя общий XmlJavaTypeAdapter. Тем не менее, я не могу заставить его работать должным образом, используя дженерики.
Я использую eclipselink 2.5.1 / moxy
XML:
<?xml version="1.0" encoding="UTF-8"?>
<page>
<label>Test</label>
<description>Test</description>
</page>
Page.java:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
import com.google.common.base.Optional;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
public class Page {
@XmlPath("label")
private Label label;
@XmlJavaTypeAdapter(OptionalLabelAdapter.class)
private Optional<Label> description = Optional.absent();
}
Label.java:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlValue;
@XmlAccessorType(XmlAccessType.FIELD)
public class Label {
@XmlValue
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
MoxyTest.java:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class MoxyTest {
public static void main(String[] args) throws JAXBException {
String name = "test";
JAXBContext jc = JAXBContext.newInstance(Page.class);
System.out.println(jc.getClass());
Unmarshaller unmarshaller = jc.createUnmarshaller();
Page page = (Page) unmarshaller.unmarshal(new File("xml/" + name + ".xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(page, System.out);
}
}
Это мой адаптер с использованием дженериков:
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.google.common.base.Optional;
public class OptionalAdapter<T> extends XmlAdapter<T, Optional<T>> {
@Override
public Optional<T> unmarshal(T value) throws Exception {
return Optional.of(value);
}
@Override
public T marshal(final Optional<T> value) throws Exception {
if(value.isPresent()){
return value.get();
} else {
return null;
}
}
}
Это не работает, я получаю ElementNSImpl, завернутый в необязательный. Это работает, если я использую:
@XmlJavaTypeAdapter(OptionalAdapter.class)
@XmlElement(name = "description", type = Label.class)
private Optional<Label> description;
в Page.java. Тем не менее, я не уверен, как добиться того же с атрибутами.
Использование этого адаптера работает:
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.google.common.base.Optional;
public class OptionalLabelAdapter extends XmlAdapter<Label, Optional<Label>> {
@Override
public Optional<Label> unmarshal(final Label value) throws Exception {
return Optional.of(value);
}
@Override
public Label marshal(final Optional<Label> value) throws Exception {
if(value.isPresent()){
return value.get();
} else {
return null;
}
}
}
Пожалуйста, объясните, почему мой универсальный адаптер не работает без "@XmlElement (name =" description ", type = Label.class)", и, пожалуйста, объясните, как я достигаю того же для атрибутов вместо элементов.