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>
これが私がこれまでに試したことです
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);
}
}
}
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
DOMの代わりに SOAPMessage API を使用します。
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を使用します。これを試して。
忘れないでください:soapMessage.saveChanges();