Używanie ogólnego @XmlJavaTypeAdapter do nieumyślnego zapakowania w Opcjonalne Guava
Próbuję unmarshal niektóre xml do obiektów java zawinięte w Opcjonalne Guava za pomocą ogólnego XmlJavaTypeAdapter. Jednak nie mogę sprawić, by działał poprawnie przy użyciu generycznych.
Używam eclipselink 2.5.1 / moxy
XML:
<?xml version="1.0" encoding="UTF-8"?>
<page>
<label>Test</label>
<description>Test</description>
</page>
Strona.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);
}
}
To jest mój adapter używający generycznych:
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;
}
}
}
To nie działa, dostaję ElementNSImpl zawinięty w Opcjonalny. Działa, gdy używam:
@XmlJavaTypeAdapter(OptionalAdapter.class)
@XmlElement(name = "description", type = Label.class)
private Optional<Label> description;
w Page.java. Nie wiem jednak, jak osiągnąć to samo z atrybutami.
Korzystanie z tego adaptera działa:
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;
}
}
}
Proszę wyjaśnić, dlaczego mój ogólny adapter nie działa bez „@XmlElement (name =„ description ”, wpisz = Label.class)” i proszę wyjaśnić, jak osiągnąć to samo dla atrybutów zamiast elementów.