如何更改使用 SOAPMessage 创建的 SOAP web 服务请求中的命名空间前缀?

How to change namespace prefix in SOAP webservice request created with SOAPMessage?

当我使用 javax.xml.soap.SOAPMessage class 创建我的 SOAP 请求时,我在 XML 中得到一个名称空间前缀,例如 <SOAP-ENV:Envelope>.

有没有一种简单的方法可以将命名空间前缀更改为 <soapenv:Envelope>

XML 命名空间前缀 should not matter 只要您调用的是行为良好的 Web 服务。所以 SOAP-ENV:soapenv:whatever: 基本上是同一件事,只要它们都引用相同的命名空间。

话虽如此,如果您出于某种原因确实需要这样做,这里有一些最低限度的工作代码。我打电话给 this service.

package soap;

import java.io.IOException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

public class Client {
    public static void main(String[] args) throws SOAPException, IOException {
        MessageFactory factory = MessageFactory.newInstance();
        SOAPMessage message = factory.createMessage();

        MimeHeaders mimeHeader = message.getMimeHeaders();
        mimeHeader.setHeader("SOAPAction", "http://tempuri.org/Add");
        
        SOAPBody body = message.getSOAPBody();
        SOAPHeader header = message.getSOAPHeader();
        
        QName bodyName = new QName("http://tempuri.org/", "Add", "tmp");
        SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
        
        
        SOAPElement intA = bodyElement.addChildElement(new QName("http://tempuri.org/", "intA", "tmp"));
        intA.addTextNode("123");
        
        SOAPElement intB = bodyElement.addChildElement(new QName("http://tempuri.org/", "intB", "tmp"));
        intB.addTextNode("456");

        message.writeTo(System.out);
        System.out.println();
        
        // -----------------> Now changing the prefix before making the call
        
        SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
        envelope.removeNamespaceDeclaration(envelope.getPrefix());
        
        String prefix = "soapenv";
        envelope.addNamespaceDeclaration(prefix, "http://schemas.xmlsoap.org/soap/envelope/");
        envelope.setPrefix(prefix);
        header.setPrefix(prefix);
        body.setPrefix(prefix);
        
        // <---------------- done changing the prefix
        
        message.writeTo(System.out);
        System.out.println();
        
        SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
        SOAPConnection connection = soapConnectionFactory.createConnection();
        URL endpoint = new URL("http://www.dneonline.com/calculator.asmx");
        SOAPMessage response = connection.call(message, endpoint);
        connection.close();
        
        response.writeTo(System.out);
    }
}

我打印了转换前后的请求消息。输出如下(不包括格式:D):

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <tmp:Add xmlns:tmp="http://tempuri.org/">
      <tmp:intA>123</tmp:intA>
      <tmp:intB>456</tmp:intB>
    </tmp:Add>
  </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
     <tmp:Add xmlns:tmp="http://tempuri.org/">
       <tmp:intA>123</tmp:intA>
       <tmp:intB>456</tmp:intB>
     </tmp:Add>
   </soapenv:Body>
 </soapenv:Envelope>

 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
     <AddResponse xmlns="http://tempuri.org/">
       <AddResult>579</AddResult>
     </AddResponse>
   </soap:Body>
</soap:Envelope>