java jaxb_java – 使用JAXB和Any进行序列化

这篇博客介绍了在Java中使用JAXB处理@XmlAnyElement(lax=true)属性时遇到的问题,包括尝试将一个JAXB对象添加到Payload类的any属性中遇到的异常。解决方案涉及了如何正确地序列化和反序列化包含@XmlAnyElement的JAXB对象,并提供了一个示例代码展示如何处理包含不同类型元素的XML。
摘要由CSDN通过智能技术生成

我有一个定义以下类型的模式:

这会创建一个像这样的对象:

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "Payload", propOrder = {

"any"

})

public class Payload {

@XmlAnyElement(lax = true)

protected List any;

}

现在我尝试将另一个生成的JAXB对象添加到该Payload,执行以下操作:

Class payloadClass = ...;

JAXBContext context = JAXBContext.newInstance( WrapperRequest.class, payloadClass);

...

marshaller.marshal( wrappedRequest );

但是我得到了一个可怕的异常,看起来它永远不会工作所以我决定先将有效负载对象序列化为XML,然后将其作为字符串添加到有效负载中.

StringWriter writer = new StringWriter();

JAXBContext context = JAXBContext.newInstance( sdoRequest.getClass() );

Marshaller marshaller = context.createMarshaller();

marshaller.marshal(new JAXBElement(new QName("uri", sdoRequest.getClass().getSimpleName()), sdoRequest.getClass(), sdoRequest), writer);

payload.getAny().add( writer.toString() );

这会引发异常,说“java.lang.String”不包含@XmlRootElement.

那么如何使用xs:任何使用过的JAXB?似乎没有什么可以工作,因为JAXB将Payload转换为Object,并且它不会仅对Object中的任何内容进行序列化.这一切都在Axis2内部,因此达到这一点非常具有挑战性.

解决方法:

下面我将演示JAXB (JSR-222)和任何一个例子:

有效载荷

any属性使用@XmlAnyElement注释(lax = true).这意味着对于该属性,如果元素通过@XmlRootElement或@XmlElementDecl与类关联,则相应对象的实例将用于填充属性,否则该元素将被设置为org.w3c.dom的实例.元件.

package forum13941747;

import java.util.List;

import javax.xml.bind.annotation.*;

@XmlRootElement

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "Payload", propOrder = {

"any"

})

public class Payload {

@XmlAnyElement(lax = true)

protected List any;

}

下面是使用@XmlRootElement注释的类的示例.

package forum13941747;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

public class Foo {

}

酒吧

下面是没有@XmlRootElement注释的类的示例.在这个用例中,我们将在使用@XmlRegistry注释的工厂类(通常称为ObjectFactory)上利用@XmlElementDecl注释.

package forum13941747;

public class Bar {

}

的ObjectFactory

下面是为Bar类指定@XmlElementDecl注释的示例.

package forum13941747;

import javax.xml.bind.JAXBElement;

import javax.xml.bind.annotation.*;

import javax.xml.namespace.QName;

@XmlRegistry

public class ObjectFactory {

@XmlElementDecl(name="bar")

public JAXBElement createBar(Bar bar) {

return new JAXBElement(new QName("bar"), Bar.class, bar);

}

}

input.xml中

下面是我们将用于此示例的输入文档.有3个元素对应于any属性.第一个对应于Foo类上的@XmlRootElement注释.第二个对应于Bar类的@XmlElementDecl注释,第三个对应于任何域类.

演示

在下面的演示代码中,我们将解组输入文档,然后在生成的any属性中输出对象的类,然后将有效负载对象封送回XML.

package forum13941747;

import java.io.File;

import javax.xml.bind.*;

public class Demo {

public static void main(String[] args) throws Exception {

JAXBContext jc = JAXBContext.newInstance(Payload.class, Foo.class, ObjectFactory.class);

Unmarshaller unmarshaller = jc.createUnmarshaller();

File xml = new File("src/forum13941747/input.xml");

Payload payload = (Payload) unmarshaller.unmarshal(xml);

for(Object o : payload.any) {

System.out.println(o.getClass());

}

Marshaller marshaller = jc.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

marshaller.marshal(payload, System.out);

}

}

产量

以下是运行演示代码的输出.请注意与any属性中的对象相对应的类. foo元素成为Foo类的一个实例. bar元素成为JAXBElement的一个实例,它包含一个Bar实例.另一个元素成为org.w3c.dom.Element的一个实例.

class forum13941747.Foo

class javax.xml.bind.JAXBElement

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl

标签:axis2,java,jaxb,xsd

来源: https://codeday.me/bug/20190929/1829895.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值