JAXB:需要所有元素的命名空间前缀

Posted

技术标签:

【中文标题】JAXB:需要所有元素的命名空间前缀【英文标题】:JAXB :Need Namespace Prefix to all the elements 【发布时间】:2011-10-17 06:03:06 【问题描述】:

我正在使用 Spring WebServiceTemplate 进行 Web 服务调用,该调用使用 JAXB 生成请求 XML。我的要求需要所有元素(包括根)在 SOAP 请求中都有一个命名空间前缀(只有一个命名空间)。

例如:

<ns1:Login xmlns:ns1="www.example.com/a">
    <ns1:username>abc</ns1:username>
    <ns1:password>abc</ns1:password>
</ns1:Login>

但我得到了

<Login xmlns="www.example.com/a">
    <username>abc<username>
    <password>abc<password>
</Login>

xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="www.example.com/a"   xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ilreq="www.example.com/a" elementFormDefault="qualified" attributeFormDefault="unqualified">

<xs:complexType name="Login">
    <xs:sequence>
        <xs:element name="username" type="xs:string"/>
        <xs:element name="password" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

从 XSD 生成的 Java 类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Login", propOrder = 
    "username",
    "password"
)

@XmlRootElement
public class Login 

@XmlElement(required = true)
protected String username;
@XmlElement(required = true)
protected String password;
......

包信息.java

@javax.xml.bind.annotation.XmlSchema(
    namespace = "www.example.com/a",
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package authenticator.beans.login;

想知道如何为包括根在内的所有元素生成带有命名空间前缀的请求 XML。

【问题讨论】:

如果我错了,请纠正我,但开头的这两个 XML sn-ps 不是等效的吗? @TomasZ :XML 是等效的,但服务器不接受没有命名空间前缀的请求。所以我想给所有元素加上前缀。 相关问题? JAXB namespaces missing @perp :感谢您的链接。能够生成所需格式的 XML。 @MSK 请按照meta.stackexchange.com/questions/38149/…中给出的指南“关闭”这个问题 【参考方案1】:

要指定多个命名空间来提供前缀,请使用以下内容:

@javax.xml.bind.annotation.XmlSchema(
    namespace = "urn:oecd:ties:cbc:v1", 
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
    xmlns =@XmlNs(prefix="cbc", namespaceURI="urn:oecd:ties:cbc:v1"), 
            @XmlNs(prefix="iso", namespaceURI="urn:oecd:ties:isocbctypes:v1"),
            @XmlNs(prefix="stf", namespaceURI="urn:oecd:ties:stf:v4"))

... 在 package-info.java 中

【讨论】:

@D.Throne 命名空间的值可以是 "urn:oecd:ties:isocbctypes:v1" 或 "urn:oecd:ties:stf:v4" 而不是 "urn:oecd:ties:cbc: v1”?如果不是,那么当有多个命名空间前缀时,我们将把命名空间值放在什么参数上。【参考方案2】:

遇到了这个问题,通过在我的包中添加 package-info 解决了

以及下面的代码:

@XmlSchema(
    namespace = "http://www.w3schools.com/xml/",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns = 
        @XmlNs(prefix="", namespaceURI="http://www.w3schools.com/xml/")
    
)  
package com.gateway.ws.outbound.bean;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

【讨论】:

【参考方案3】:

添加解决

@XmlSchema(
    namespace = "http://www.example.com/a",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns = 
        @XmlNs(prefix="ns1", namespaceURI="http://www.example.com/a")
    
)  

package authenticator.beans.login;
import javax.xml.bind.annotation.*;

在 package-info.java 中

在jaxb-namespaces-missing 的帮助下:Blaise Doughan 提供的答案

【讨论】:

如何定义多个命名空间?就像上面的例子一样,我想再添加一个namespace url,它是prefix? @sai 我对 java6 cxf webservices 采用相同的方法。但我仍然没有看到正确的前缀。就我而言,我得到的是前缀“a​​”而不是 ns2。有什么想法吗? @Sai 您能否为使用两(2)个命名空间前缀的 SOAP 请求编写代码(package-info.java 的内容和从 XSD 生成的 Java 类)。这意味着对于某些元素名称空间前缀是 ns1 而对于某些元素名称空间前缀是 ns2【参考方案4】:

marshaller.setProperty 仅适用于 Sun 的 JAX-B 编组器。问题是关于来自 SpringSource 的 JAX-B 编组器,它不支持 setProperty

【讨论】:

但是 Spring Marshaller 确实通过“marshallerProperties”映射支持 marshaller 属性,该映射可以在 Spring marshaller 定义中进行配置,并将它们传递给包装的 JAXB 上下文实现【参考方案5】:

另一种方法是告诉编组器始终使用某个前缀

marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() 
             @Override
            public String getPreferredPrefix(String arg0, String arg1, boolean arg2) 
                return "ns1";
            
        );'

【讨论】:

这在 java 8 中不起作用,请参阅 ***.com/questions/2326107/…【参考方案6】:

MSK,

您是否尝试过像这样为您的成员变量设置命名空间声明? :

@XmlElement(required = true, namespace = "http://example.com/a")
protected String username;

@XmlElement(required = true, namespace = "http://example.com/a")
protected String password;

对于我们的项目,它解决了命名空间问题。我们还必须创建 NameSpacePrefixMappers。

【讨论】:

我没有使用 NameSpacePrefixMappers。我只需要在 package-info.java 中使用注释方法。 perp 提供的链接起到了作用i.e. reply from Blaise Doughan

以上是关于JAXB:需要所有元素的命名空间前缀的主要内容,如果未能解决你的问题,请参考以下文章

使用命名空间和前缀的 JAXB 解组

在 JAXB 编组时删除命名空间前缀

JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?

Xml Jaxb 命名空间和属性顺序

在不使用 NamespacePrefixMapper 的情况下定义 Spring JAXB 命名空间

使用 jaxb 将命名空间添加到 xml 的根元素