2010-10-27 28 views
15

Ich rufe einen SOAP-Webservice mit Spring-WS auf. Die WebService in Frage erfordert mir einige Informationen im SOAP-Header passieren, wie hier gezeigt:Hinzufügen von untergeordneten Elementen zum benutzerdefinierten SOAP-Header in Spring-WS

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header> 
     <CustomHeaderElement> 
     <clientID>xyz</clientID> 
     <wsdlVersion>1.0</wsdlVersion> 
     <serviceType>ExampleService_v1</serviceType> 
     </CustomHeaderElement> 
    </soapenv:Header> 
    <soapenv:Body> 
    ... 
    </soapenv:Body> 
</soapenv:Envelope> 

Ich habe herausgefunden, wie die Top-Level CustomHeaderElement musste, aber ich sehe nichts im Frühling-WS API, mit der ich ein untergeordnetes Element hinzufügen kann. Hier ist, was ich bisher:

WebServiceTemplate template = ...; 

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){ 
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{ 
     SoapMessage soapMessage = (SoapMessage)message; 
     SoapHeader soapHeader = soapMessage.getSoapHeader(); 
     QName qName = new QName("CustomHeaderElement"); 
     SOAPHeaderElement headerElement = soapHeader.addHeaderElement(qName); 
     //would like to do something like headerElement.addChild(clientIdNode); 
    } 
}); 

Das Problem ist headerElement keine Mittel auszusetzen scheint tatsächlich ein Kind hinzufügen. Ich weiß, dass ich ein Attribut hinzufügen kann, aber das ist nicht das, was ich für diesen Serviceanruf benötige. Weiß jemand, wie ich die erforderlichen Kindelemente zu meinem benutzerdefinierten Header hinzufügen könnte?

Antwort

1

Ich bin nicht zufrieden mit dieser Lösung, aber wie sich herausstellt, können Sie die Nachricht tatsächlich an eine SOAPMessage übergeben, die Ihnen vollen Zugriff auf alle SAAJ-APIs bietet. Von dort können Sie die gewünschten Elemente in der Kopfzeile erstellen.

+1

Meinst du etwas ähnliches zu diesem Beitrag: http://stackoverflow.com/questions/4046075/how-to-add-soap-headers-to-spring-jax-ws-client, wo ein Transformer nach Gießen verwendet wird die Nachricht an eine SOAPMessage? Ich stimme zu, dass es nicht wirklich angenehm oder elegant ist. Ich wundere mich warum. – chris

+1

-1 Nicht wirklich eine Antwort. P.S. Der Link von @chris bietet gute Lösungen. – kaskelotti

+1

Ihre Antwort, sogar als die richtige markiert, hat uns überhaupt nicht geholfen. – marionmaiden

8

Ich kam in der gleichen Ausgabe, hier meine Lösung ist, aber es wird nur einfache Elemente nicht für komplexe Arbeit:

template.marshalSendAndReceive(request, new WebServiceMessageCallback(){ 
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{ 
     SaajSoapMessage soapMessage = (SaajSoapMessage) message; 
     SoapHeaderElement messageId = soapMessage.getSoapHeader().addHeaderElement(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa")); 
     messageId.setText("urn:abcdef1234"); 
    } 
}); 

es produziert XML folgende:

<SOAP-ENV:Header> 
    <wsa:MessageID>urn:abcdef1234</wsa:MessageID> 
</SOAP-ENV:Header> 

BTW javax.xml.soap.SOAPMessage kann auch funktionieren, siehe hier: http://docs.oracle.com/javaee/5/tutorial/doc/bnbhr.html#bnbia

3
final String datPrefix = "dat"; 
final String datNamespaceUri = "UPRS/Services/IProviderDataManagement/Datatypes"; 

final String mesPrefix = "mes"; 
final String mesNamespaceUri = "UPRS/Services/IProviderDataManagement/Messages"; 

SoapEnvelope se = s.getEnvelope(); 
se.addNamespaceDeclaration(mesPrefix, 
     mesNamespaceUri); 
se.addNamespaceDeclaration(datPrefix, 
     datNamespaceUri); 

SoapMessage s = (SoapMessage) message; 

Element root = new Element("requestContext", mesPrefix, mesNamespaceUri); 
Element child = new Element("commandId", datPrefix, datNamespaceUri).addContent(guid); 
root.addContent(child); 

TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
Transformer transformer = transformerFactory.newTransformer(); 
transformer.transform(new JDOMSource(root), s.getSoapHeader().getResult()); 

Es produziert Ausgabe

<SOAP-ENV:Header> 
     <mes:requestContext xmlns:mes="UPRS/Services/IProviderDataManagement/Messages"> 
      <dat:commandId xmlns:dat="UPRS/Services/IProviderDataManagement/Datatypes">ba7b1e13-8a06-49b6-a264-fc0298f55f4f</dat:commandId> 
     </mes:requestContext> 
    </SOAP-ENV:Header> 
+3

Willkommen bei SO! Bitte geben Sie an, was Ihr Code tut und wie er die Frage beantwortet. Wenn Sie ein Code-Snippet als Antwort erhalten, wissen Sie möglicherweise nicht, was Sie damit machen sollen. Antwort sollte dem OP Hinweise dazu geben, wie das Problem behoben und behoben werden kann. Die Idee hinter Ihrem Code ist sehr hilfreich, um das Problem zu verstehen und Ihre Lösung anzuwenden oder zu modifizieren. – Palec

0

Ich hatte das gleiche Problem und gelöst es mit dem folgenden Ausschnitt:

Result result = ((SoapMessage) message).getSoapHeader().getResult(); 
webServiceTemplate.getMarshaller().marshal(createCustomHeader(), result); 

Die createCustomerHeader() Methode erstellt eine JAXB Bohne, die aus der XSD generiert wurden.