使用 jax-ws 注释将 xml 命名空间声明移动到根元素

move xml namespace declarations to root element with jax-ws annotations

我正在尝试使用 jax-ws 生成一个 xml 负载,但没有成功。服务器期望所有名称空间都在信封标记中。例如:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://somewhere.namespace1.com" xmlns:ns2="http://somewhere.namespace2.com">

是我需要的,而

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

我有。

jax-ws 生成类似

的有效负载
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns1:Element1 xmlns:ns1="http://somewhere.namespace1.com" xmlns:ns1="http://somewhere.namespace2.com">
            <ns2:Element2>value</ns2:Element2>
        </ns1:Element1>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

但我需要

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://somewhere.namespace1.com" xmlns:ns2="http://somewhere.namespace2.com">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns1:Element1>
            <ns2:Element2>value</ns2:Element2>
        </ns1:Element1>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我尝试将 package-info.java 文件与 @javax.xml.bind.annotation.XmlSchema 放在一起,我能够更改前缀但不能将实际名称空间声明从子节点移动到根节点。例如,我可以(显然?)在信封中定义我需要的所有命名空间

@javax.xml.bind.annotation.XmlSchema(
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
    xmlns = {
            @XmlNs(
                prefix = "ns1",
                namespaceURI="http://somewhere.namespace1.com"),
            @XmlNs(
                prefix = "ns2",
                namespaceURI="http://somewhere.namespace2.com"),
    }
)

但是在 Element1.javaElement2.java 所在的 package-info.java 中,我不希望在那里定义名称空间。我试过了

@javax.xml.bind.annotation.XmlSchema(
    namespace="http://schemas.xmlsoap.org/soap/envelope/",
    location = ""
)

但是没用。

有没有其他人遇到过类似的问题?我确定这只是注释的问题,但我一直无法弄清楚。

我通过调用 Spring 的 WebServiceTemplate#sendAndReceive(String, WebServiceMessageCallback, WebServiceMessageExtractor<T>) 解决了这个问题,在第二个参数(回调)中我手动添加了我需要在 [=14 中的名称空间=].例如像

wsResponse = this.webServiceTemplate.sendAndReceive(uri,
        (webServiceMessage) -> {
            ...
            SoapMessage soapMessage = (SoapMessage) webServiceMessage;
            ...
            final SoapEnvelope envelope = soapMessage.getEnvelope();
            headerNamespaces.forEach(envelope::addNamespaceDeclaration);
            ...
        }, this.responseExtractor);