当前位置: 首页 > 面试题库 >

使用JAXB和Any进行序列化

荣波
2023-03-14
问题内容

我有一个定义以下类型的架构:

<xsd:complexType name="Payload">
   <xsd:sequence>
      <xsd:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
   </xsd:sequence>
</xsd:complexType>

这样就创建了一个对象,如下所示:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Payload", propOrder = {
    "any"
})
public class Payload {

    @XmlAnyElement(lax = true)
    protected List<Object> any;
}

现在,我尝试将另一个生成的JAXB对象添加到该有效负载中,如下所示:

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:any的使用将如何与JAXB一起使用?似乎什么都不想工作,因为JAXB将有效负载转换为对象,并且它不会序列化对象中的任何内容。这也都在Axis2内部,因此达到这一点非常困难。


问题答案:

下面我将演示 JAXB(JSR-222)any用一个例子:

有效载荷

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

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<Object> any;

}

oo

以下是带有注释的类的示例@XmlRootElement

package forum13941747;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo {

}

酒吧

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

package forum13941747;

public class Bar {

}

对象工厂

下面是@XmlElementDeclBar该类指定注释的示例。

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<Bar> createBar(Bar bar) {
        return new JAXBElement<Bar>(new QName("bar"), Bar.class, bar);
    }

}

input.xml

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

<?xml version="1.0" encoding="UTF-8"?>
<payload>
    <foo/>
    <bar/>
    <other/>
</payload>

演示版

在下面的演示代码中,我们将解组输入文档,然后在结果any属性中输出对象的类,然后将payload对象编组回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。该other元素成为了一个实例org.w3c.dom.Element

class forum13941747.Foo
class javax.xml.bind.JAXBElement
class com.sun.org.apache.xerces.internal.dom.ElementNSImpl
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<payload>
    <foo/>
    <bar/>
    <other/>
</payload>


 类似资料:
  • 问题内容: 我有一个使用Jersey实现的JAX-RS REST服务。JAX-RS / Jersey的很酷的功能之一是,只需添加一些Java批注,就可以将POJO轻松转换为REST服务…包括使用JAXB批注将POJO转换为JSON的简单方法。 现在,我希望能够将这个酷炫的JSON修饰功能用于非REST用途-我很希望能够将其中一些对象序列化为JSON文本到磁盘。这是我要序列化的示例JAXB对象: J

  • 问题内容: 我有一个问题。我想使用JAXB将一个对象转换为另一个对象。就像在中,我有一个class 和另一个class ,它们都有相同的参数,实际上都是相同的(复制粘贴),但是包不同。我想使用进行它们之间的转换。 怎么做,请帮帮我。 问题答案: 您可以执行以下操作。 注意: 不需要利用JAXBSource将数据具体化为XML。 它在对象模型上不需要任何注释。 com.home.Student co

  • 我正在使用DataTables,并将这个有点尴尬的Javascript拼凑在一起,以允许行和列高亮显示。它基于本页的示例(http://datatables.net/release-datatables/examples/api/highlight.html ). 下面是dataTable配置的相关部分: 服务器上的模板代码插入了一些常量。这是列数。以下是DataTables调试输出:http:/

  • 本文向大家介绍C#使用Json.Net进行序列化和反序列化及定制化,包括了C#使用Json.Net进行序列化和反序列化及定制化的使用技巧和注意事项,需要的朋友参考一下 序列化(Serialize)是将对象转换成字节流,并将其用于存储或传输的过程,主要用途是保存对象的状态,以便在需要时重新创建该对象;反序列化(Deserialize)则是将上面的字节流转换为相应对象的过程;在.Net阵营中,Json

  • 问题内容: 谁能告诉我Java中对序列化的需求是什么,并给我一个示例场景来说明需求?(我已经知道什么是序列化,我只想了解何时使用它)。 问题答案: 通常在需要通过网络发送数据或存储在文件中时使用序列化。数据是对象,而不是文本。 现在的问题是您的网络基础结构和硬盘是可以理解位和字节但不能理解JAVA对象的硬件组件。 序列化是将Java对象的值/状态转换为字节,以便通过网络发送或保存它。 这类似于通过

  • 我有一个字段,它通过类序列化为ISO-8601格式。 当我收到以下JSON时, 通过将jackson-datatype-jsr310模块包含到项目中,并使用和解决了这个问题。