如何更改Spring-WS的“SOAP-ENV”默认前缀

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何更改Spring-WS的“SOAP-ENV”默认前缀相关的知识,希望对你有一定的参考价值。

我使用Spring-WS创建了一个Web服务。为了保持与旧系统的兼容性,我需要将命名空间前缀从SOAP-ENV更改为soap

我知道SOAP-ENVsoap只是命名空间前缀。只要他们引用正确的命名空间("http://schemas.xmlsoap.org/soap/envelope/"),它应该没问题。

但旧系统硬编码解析器代码只期望soap名称空间前缀。

目前的回应:

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

预期回复:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header/>
   <soap:Body>
   ...
   </soap:Body>
</soap:Envelope>

这是我到目前为止所尝试的内容

  1. 创建EndpointInterceptorAdapter子类。这将拦截SOAP响应/错误并更改SOAP信封。这有效,但在性能方面并不理想。 public class CustomEndpointInterceptor extends EndpointInterceptorAdapter { private static final String DEFAULT_NS = "xmlns:SOAP-ENV"; private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/"; private static final String PREFERRED_PREFIX = "soap"; private static final String HEADER_LOCAL_NAME = "Header"; private static final String BODY_LOCAL_NAME = "Body"; private static final String FAULT_LOCAL_NAME = "Fault"; @Override public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception { SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse(); alterSoapEnvelope(soapResponse); return super.handleResponse(messageContext, endpoint); } @Override public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception { SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse(); alterSoapEnvelope(soapResponse); return super.handleFault(messageContext, endpoint); } private void alterSoapEnvelope(SaajSoapMessage soapResponse) { Document doc = soapResponse.getDocument(); Element rootElement = doc.getDocumentElement(); rootElement.setPrefix(PREFERRED_PREFIX); // Remove default SOAP namespace rootElement.removeAttribute(DEFAULT_NS); NodeList headerNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, HEADER_LOCAL_NAME); NodeList bodyNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, BODY_LOCAL_NAME); NodeList faultNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, FAULT_LOCAL_NAME); // Remove Header node. if (headerNodes.getLength() != 0) { rootElement.removeChild(headerNodes.item(0)); } // Change Body's SOAP namespace prefix. if (bodyNodes.getLength() != 0) { Element bodyElement = (Element) bodyNodes.item(0); bodyElement.setPrefix(PREFERRED_PREFIX); } if (faultNodes.getLength() != 0) { Element faultElement = (Element) faultNodes.item(0); faultElement.setPrefix(PREFERRED_PREFIX); } } }
  2. 在包含WSDL生成的类的包中更改package-info.java。我用公司的名称空间前缀成功完成了这项工作,但它不适用于SOAP-ENV前缀。 @javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/ns/2008/02/02/webservices/blah", xmlns = { @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.example.com/ns/2008/02/02/webservices/blah", prefix = ""), @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.example.com/ns/2007/10/blah", prefix = "ns2"), @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://example.com/ns/2007/23/05/blah/fundamental", prefix = "ns3"), @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap") // doesn't work }, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package com.thomsonreuters.ts.ets.interdayws.soap.webservice;

有没有一种理想的方法可以在Spring-WS中将SOAP-ENV更改为soap

顺便说一句,这是设置此前缀的代码。 StroapElement.java

答案

A better solution

使用SOAPMessage API而不是DOM。

  private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
    try {
      SOAPMessage soapMessage = soapResponse.getSaajMessage();
      SOAPPart soapPart = soapMessage.getSOAPPart();
      SOAPEnvelope envelope = soapPart.getEnvelope();
      SOAPHeader header = soapMessage.getSOAPHeader();
      SOAPBody body = soapMessage.getSOAPBody();
      SOAPFault fault = body.getFault();
      envelope.removeNamespaceDeclaration(envelope.getPrefix());
      envelope.addNamespaceDeclaration(PREFERRED_PREFIX, SOAP_ENV_NAMESPACE);
      envelope.setPrefix(PREFERRED_PREFIX);
      header.setPrefix(PREFERRED_PREFIX);
      body.setPrefix(PREFERRED_PREFIX);
      if (fault != null) {
        fault.setPrefix(PREFERRED_PREFIX);
      }
    } catch (SOAPException e) {
      e.printStackTrace();
    }
  }

它现在快得多。

另一答案

我用SAAJ。试试这个。

  1. soapEnvelope.removeNamespaceDeclaration( “SOAP-ENV”);
  2. soapEnvelope.addNamespaceDeclaration(“soapenv”,“http://schemas.xmlsoap.org/soap/envelope/”);
  3. soapEnvelope.setPrefix( “soapenv”);
  4. soapHeader.setPrefix( “soapenv”);
  5. soapBody.setPrefix( “soapenv”);

别忘了:soapMessage.saveChanges();

参考:Changing the default XML namespace prefix generated with JAXWS

以上是关于如何更改Spring-WS的“SOAP-ENV”默认前缀的主要内容,如果未能解决你的问题,请参考以下文章

如果我使用 wcf,如何将 <s:Envelope 更改为 <SOAP-ENV:Envelope?

来自 WSDL 的 Spring-ws 客户端

Spring-WS WS-Security LDAP 身份验证

Spring-WS:具有 WSDL 多节点分类的 SimpleWsdl11Definition

spring-ws:找不到端点映射

基于Spring-WS的Restful API的集成测试