1

这篇文章打算成为一个问题,但在其撰写过程中,我想出了一个解决方案,我想分享它。

我有一个 jax-ws Web 服务,其中一个操作只接受一个参数,可以说它称为 AnimalParameter。问题是客户可以用他喜欢的任何动物(一次一个)调用我的服务。动物是预定义的。我的目的是检索这个“AnicmalParameter”的内容并调用另一个 Web 服务服务,该服务实际上对每只动物都有一个操作。

我将 XmlElements 与继承结合使用作为动态绑定选择,以便用相同的 bean 捕获每只动物:

@XmlRootElement
public class AnimalParameter implements Serializable {

    @XmlElements({
            @XmlElement(name = "dog", type=Dog.class ),
            @XmlElement(name = "cat", type=Cat.class )
    })
    protected Animal animal;    
 }

在我的情况下,客户一次将调用一只动物。所以xml会像:

<animalParameter>
  <dog>
    ...
  </dog>
</animalParameter>

或者 :

<animalParameter>
  <cat>
    ...
  </cat>
</animalParameter>

通过执行以下操作将整个动物容器编组为字符串相当容易:

final Writer xmlString = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(AnimalParameter.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(animalParameter, xmlString);

我的问题是我只想用我收到的动物(狗或猫不是整个参数)打印一个 xml,这似乎非常困难,因为在编译时我不知道我的网络服务将被调用的动物和。因此,即使我上面的 bean 也能够将请求与 dog 和 cat 绑定,你如何在没有根元素的情况下将其编组为 xml。我试图在我的 bean 中放置一个方便的方法:

 @XmlRootElement
    public class AnimalParameter implements Serializable 
        .
        .
        .   
        @XmlElement
        public Animal   getAnimal(){
                return animal;
        }
}

并使用:

JAXBContext jaxbContext = JAXBContext.newInstance(Animal.class);
jaxbMarshaller.marshal(animalParameter.getAnimal(), xmlString);

打印的xml是:

<animal>...</animal> and not the desired <cat>...</cat> or <dog>...</dog>

我的理解是,JAXB 用于将 xml 绑定到 java 类/字段的绑定元数据没有存储在任何地方,它只是运行时执行的代码。所以java字段“animal”真​​的不知道它真正绑定到哪个xml节点。

我用这个解决了:

String animalName = animalParameter.getAnimal().getClass().getSimpleName();
JAXBContext jaxbContext = JAXBContext.newInstance(Animal.class);
jaxbMarshaller.marshal(new JAXBElement<Operation>(new QName(animalName), Animal.class, animalParameter.getAnimal()), stringWriter);
4

0 回答 0