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:为啥在生成的 xml 文档中未使用定义的命名空间前缀?