我正在尝试使用通用 XmlJavaTypeAdapter 将一些 xml 解组为包装在 Guava 的 Optional 中的 java 对象。但是,我无法使用泛型使其正常工作。
我正在使用 eclipselink 2.5.1 / moxy
XML:
<?xml version="1.0" encoding="UTF-8"?>
<page>
<label>Test</label>
<description>Test</description>
</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();
}
标签.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;
}
}
}
这不起作用,我得到一个包含在 Optional 中的 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)" 的情况下无法工作,并请解释我如何为属性而不是元素实现相同的功能。