JAXB @XmlElements,类型不同但名称相同?

我有一个Animal类和一个名为AnimalExtension的Animal扩展。

public class Animal

public class AnimalExtension extends Animal

这两个类之间的唯一区别是AnimalExtension还有另一个实例变量叫做animalId。Animal没有此实例变量。

我也有自己的数据类型,想要对XML进行封送处理。此数据类型称为AnimalList。在AnimalList内,有一个Animals列表作为实例变量。

@XmlType(name = "AnimalList")

public class AnimalList{

private List<Animal> animalList;

....

animalList可以包含Animal和AnimalExtension。但是,在XML上,我不希望将该元素命名为AnimalExtension。我希望他们所有人都具有Animal的元素名称。我只希望在JAXB知道Animal实际上是AnimalExtension的实例时显示多余的属性。所以,如果我有一个列表看起来像

List<Animal> animalList = new LinkedList<Animal>();

AnimalExtension animalExtension = new AnimalExtension();

animalExtension.setAnimalId(1);

amimalExtension.setName("Don");

Animal animal = new Animal();

animal.setName("Mike");

animalList.add(animalExtension);

animalList.add(animal);

我希望XML看起来像

<AnimalList>

<Animal name="Don" id="1" />

<Animal name="Mike" />

</AnimalList>

这就是我试图做的

    @XmlElements(

{

@XmlElement(name = "Animal", type = Animal.class),

@XmlElement(name = "Animal", type = AnimalExtension.class)

}

)

public List<Animal> getEntries() {

return animalList;

}

代码可以编译,但是当我尝试运行服务器时。它给了我这个奇怪的错误,它与正在发生的事情无关(BeanCreationException)。我尝试使XmlElement的名称对于每种类型都不同,并且可以使用,但是这里的挑战是使名称相同。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'encryptionPayloadContentProvider'

回答:

要映射此用例,可以利用以下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;

}

}

如果它的值为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 AnimalExtension

class 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

以上是 JAXB @XmlElements,类型不同但名称相同? 的全部内容, 来源链接: utcz.com/qa/429651.html

回到顶部