2010-10-27 31 views
15

J'appelle un service Web SOAP avec Spring-WS. Le webservice en question me demande de transmettre des informations dans l'en-tête SOAP comme indiqué ici:Ajouter des éléments enfants à l'en-tête SOAP personnalisé dans 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> 

J'ai compris comment avait le niveau supérieur CustomHeaderElement, mais je ne vois rien dans le printemps-WS API qui me permet d'ajouter un élément enfant. Voici ce que j'ai jusqu'à présent:

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); 
    } 
}); 

Le problème est headerElement ne semble pas exposer tout moyen d'ajouter effectivement un enfant. Je sais que je peux ajouter un attribut, mais ce n'est pas ce dont j'ai besoin pour cet appel de service. Est-ce que quelqu'un sait comment je pourrais ajouter les éléments enfants nécessaires à mon en-tête personnalisé?

Répondre

1

Je ne suis pas satisfait de cette solution, mais comme il s'avère que vous pouvez réellement lancer le message à un message SOAPMessage qui vous donne un accès complet à toutes les API de SAAJ. De là, vous pouvez construire tous les éléments que vous voulez dans l'en-tête.

+1

Voulez-vous dire quelque chose de similaire à ce post: http://stackoverflow.com/questions/4046075/how-to-add-soap-headers-to-spring-jax-ws-client où un transformateur est utilisé après la coulée le message à un message SOAPMessage? Je suis d'accord que ce n'est pas vraiment agréable ni élégant. Je me demande pourquoi. – chris

+1

-1 Pas vraiment une réponse. P.S. le lien fourni par @chris a de bonnes solutions. – kaskelotti

+1

Votre réponse, même marquée comme la bonne, ne nous a pas aidé du tout. – marionmaiden

8

je suis tombé sur la même question, voici ma solution, mais il ne fonctionnera que des éléments simples non pour le complexe:

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"); 
    } 
}); 

il produit XML suivant:

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

BTW javax.xml.soap.SOAPMessage peut travailler aussi, voir ici: 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()); 

Il a produit la sortie

<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

Bienvenue sur SO! Veuillez inclure une explication de ce que votre code fait et comment il répond à la question. Si vous obtenez un extrait de code en guise de réponse, vous ne savez peut-être pas quoi en faire. La réponse devrait donner au PO des conseils sur la façon de déboguer et de résoudre leur problème. Soulignant, quelle est l'idée derrière votre code, aide grandement à comprendre le problème et à appliquer ou modifier votre solution. – Palec

0

J'ai eu le même problème et résolu avec l'extrait suivant:

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

La méthode createCustomerHeader() crée un haricot JAXB qui a été généré à partir du XSD.