当前位置: 首页 > 知识库问答 >
问题:

如何使用同一个JAXB类将数据打包和解压到不同的名称空间?

郎雪风
2023-03-14

注意:这是与Java7。此外,我没有使用JAXB从模式生成任何东西。我只/只是想使用JAXB来反序列化现有SOAP消息的片段。所以JAXB bean是"手写的"。

我试图用JAXB反序列化以下XML。我无法作为字符串访问它。相反,我是作为一个组织获得它的。w3c。多姆。元素对象:

<SynchInfo xmlns="urn:InitronSOAPService">
    <HandshakeInfo>
        <dnsName>foo.bar</dnsName>
        <ip>1.2.3.4</ip>
        <id>TheId</id>
        <key>SomeKey</key>
        <version>1.0</version>
    </HandshakeInfo>
</SynchInfo>

但我还想将HandshakeInfo实例整理成一个SOAPBody,它是属于不同名称空间的消息的一部分。

我首先尝试编写一个根本没有提到名称空间的握手信息类:

@XmlRootElement(name = "HandshakeInfo")
@XmlAccessorType(XmlAccessType.NONE)
final private static class HandshakeInfo
{
    private String version;
    private String id;
    private String key;
    private String ip;
    private String dnsName;

    public String getVersion() {
        return version;
    }

    @XmlElement(name = "version")
    public void setVersion(String version) {
        this.version = version;
    }

    public String getId() {
        return id;
    }

    @XmlElement(name = "id")
    public void setId(String id) {
        this.id = id;
    }

    public String getKey() {
        return key;
    }

    @XmlElement(name = "key")
    public void setKey(String key) {
        this.key = key;
    }

    public String getIp() {
        return ip;
    }

    @XmlElement(name = "ip")
    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getDnsName() {
        return dnsName;
    }

    @XmlElement(name = "dnsName")
    public void setDnsName(String dnsName) {
        this.dnsName = dnsName;
    }
}

但是当我用它来尝试反序列化包含HandshakeInfo元素的Element对象时,我得到了以下异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"urn:InitronSOAPService", local:"HandshakeInfo"). Expected elements are <{}HandshakeInfo>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
...

因此,我尝试将,namespace=“urn:InitronSOAPService”添加到类中的所有元素和属性(在本例中为无)注释中。(或者,在package-info.java文件中使用@XmlSchema注释。)这对反序列化该名称空间中的元素起到了作用。

但是,当我试图使用该类将其序列化到另一个名称空间时,我(并非完全出乎意料地)得到了如下结果:

<SomeMessage xmlns="urn:differentNamespace">
    <ns5:HandshakeInfo xmlns:ns5="urn:InitronSOAPService">
        <ns5:dnsName>foo.bar</ns5:dnsName>
        <ns5:ip>1.2.3.4</ns5:ip>
        <ns5:id>TheId</ns5:id>
        <ns5:key>SomeKey</ns5:key>
        <ns5:version>1.0</ns5:version>
    </ns5:HandshakeInfo>
</SomeMessage>

这不是我想要的。我希望序列化的东西成为urn:differentNamespace的一部分。

那么,有没有办法在多个名称空间中使用同一个JAXB类呢?还是说我必须要有多个类的副本,并且每个副本都被标注在相应的名称空间中?

我见过一些使用过滤器等的技巧,但这些技巧似乎是假设XML是从流或文件中读取或写入的。同样,对于解组我正在使用org.w3c.dom.Element对象,对于编组我正在使用SOAPBody对象。

共有1个答案

昝枫
2023-03-14

我看到以下选项:

  • 使用MOXy XML绑定并将映射从注释转移到XML资源中。然后可以为不同的名称空间定义和加载不同的资源

AnnotationReader解决方案有点“黑客”,还将您与JAXB RI联系在一起。XML绑定将要求您以XML形式重写注释,并将您绑定到MOXy(我认为)。XSLT非常优雅,但会降低处理速度。您必须使用XSLT侵入处理链。

所有的选择都有利弊,你必须根据具体情况仔细考虑。

 类似资料:
  • 问题内容: 我有一个这样的架构层次结构: 一个文件夹中的所有文件都具有相同的命名空间。 现在,我想将名称空间映射到特定的Java包(我不能更改名称空间)。 我找到了将架构绑定到程序包的解决方案。但是然后我必须为每个xsd文件创建一个条目: 有没有一种方法可以直接定义名称空间和程序包名称之间的绑定? 另一种方法是在maven中定义包: 但是然后我必须为每个文件夹创建一个执行,这并不是我真正想要的。

  • 我得到了(超过)两个Api POSTendpoint。每一个都需要一个json作为参数。但是当我在两个endpoint参数类中使用相同的类名负载时,Swagger就不起作用了。当我改变其中的一个,例如从有效载荷到有效载荷1时,它就不起作用了。当然,我在包装类中设置了正确的名称空间,以便它找到负载。但我希望每次都使用相同的名称“有效载荷”。如何使用相同的类名负载?在这两种情况下,我都可以保留json

  • 我用的是spring soap ws。 我有以下对应于复杂类型的JAXB域类 我有以下带有@XmlRegistry注释的类 以下是endpoint 当我发出 Soap 请求时,我正在使用 soap 请求中的终结点中给出NAMESPACE_URI。 在这里,在这种情况下,我得到以下回应 如果我使用"超文本传输协议://命名空间/url"作为NAMESPACE_URI在endpoint和肥皂请求我得到

  • 问题内容: 我有一个Animal类和一个名为AnimalExtension的Animal扩展。 这两个类之间的唯一区别是AnimalExtension还有另一个实例变量叫做animalId。Animal没有此实例变量。 我也有自己的数据类型,想要对XML进行封送处理。此数据类型称为AnimalList。在AnimalList内,有一个Animals列表作为实例变量。 animalList可以包含A

  • 我需要创建和解析一组结构非常相似但不幸的是在几个不同的命名空间中定义的xml。我通常能够使用JAXB解析和创建所有XML,但似乎在让JAXB处理命名空间定义方面存在一些问题。下面的简单示例应该可以说明这个问题。 如果我定义一个带有类似如下命名空间的带注释的类: 并定义该类使用的另一个类,而不指定命名空间 同时,我有以下包级定义,允许我在<code>总线 我有一个这样的xml: 然后,我可以简单地使

  • 问题内容: 如何在不同的程序包中访问两个具有相同名称的类? 和 所有这些都在同一个班级 谢谢。 问题答案: 您将必须导入另一个,您将编写完全合格的路径 例如在您的代码中: