要映射此用例,可以利用以下XmlAdapters:
动物适配器
由于AnimalExtension是Animal的超集,因此我们将使用它来生成/使用XML。然后,我们将利用animalId属性的值来确定是否将Animal或AnimalExtension的实例返回给AnimalList。
import javax.xml.bind.annotation.adapters.XmlAdapter;public class AnimalAdapter extends XmlAdapter<AnimalExtension, Animal> { @Override public Animal unmarshal(AnimalExtension animalExtension) throws Exception { if(0 != animalExtension.getAnimalId()) { return animalExtension; } Animal animal = new Animal(); animal.setName(animalExtension.getName()); return animal; } @Override public AnimalExtension marshal(Animal animal) throws Exception { if(animal.getClass() == AnimalExtension.class) { return (AnimalExtension) animal; } AnimalExtension animalExtension = new AnimalExtension(); animalExtension.setName(animal.getName()); return animalExtension; }}IdAdapter
如果它的值为0,我们将需要第二个XmlAdapter来抑制animalId:
import javax.xml.bind.annotation.adapters.XmlAdapter;public class IdAdapter extends XmlAdapter<String, Integer> { @Override public Integer unmarshal(String string) throws Exception { return Integer.valueOf(string); } @Override public String marshal(Integer integer) throws Exception { if(integer == 0) { return null; } return String.valueOf(integer); }}模型类的注释如下:
动物名单
import java.util.ArrayList;import java.util.List;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;@XmlRootElement(name="AnimalList")public class AnimalList { private List<Animal> animalList = new ArrayList<Animal>(); @XmlElement(name="Animal") @XmlJavaTypeAdapter(AnimalAdapter.class) public List<Animal> getEntries() { return animalList; }}动物
import javax.xml.bind.annotation.XmlAttribute;public class Animal { private String name; @XmlAttribute public String getName() { return name; } public void setName(String name) { this.name = name; }}动物延伸
import javax.xml.bind.annotation.XmlAttribute;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;public class AnimalExtension extends Animal { private int animalId; @XmlAttribute(name="id") @XmlJavaTypeAdapter(IdAdapter.class) public int getAnimalId() { return animalId; } public void setAnimalId(int animalId) { this.animalId = animalId; }}示范代码
以下演示代码可用于演示此解决方案:
import java.io.File;import javax.xml.bind.JAXBContext;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(AnimalList.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("input.xml"); AnimalList animalList = (AnimalList) unmarshaller.unmarshal(xml); for(Animal animal : animalList.getEntries()) { System.out.println(animal.getClass()); } Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(animalList, System.out); }}将产生以下输出:
class AnimalExtensionclass Animal<?xml version="1.0" encoding="UTF-8"?><AnimalList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Animal name="Don" id="1"/> <Animal name="Mike"/></AnimalList>
相关信息
您可能会发现以下信息有用:
- http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
- http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
- http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-substitution.html



