如何更改 Spring-WS 的“SOAP-ENV”默认前缀更好的解决方案
2022-09-03 00:30:10
我使用Spring-WS创建了一个Web服务。为了保持与旧系统的兼容性,我需要将命名空间前缀从 更改为 。SOAP-ENV
soap
我知道这一点,只是命名空间前缀。只要它们引用正确的命名空间(),就应该没问题。SOAP-ENV
soap
"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>
以下是我到目前为止尝试过的方法
-
创建子类。这将截获 SOAP 响应/故障并更改 SOAP 包络。这有效,但就性能而言并不理想。
EndpointInterceptorAdapter
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); } } }
-
包含 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