Le client Spring-WS ne définit pas l'en-tête SOAPAction

j'envoie une requête SOAP et le serveur se plaint que L'en-tête SOAPAction est vide. Je pense que je suis la droite, mais évidemment, je ne suis pas. Wireshark montre que ce n'est pas réglé.

@Test
public void testLogin() throws Exception {
    StringBuffer loginXml = new StringBuffer();
    loginXml.append("<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="http://example.com/xyz/2010/08">");
    loginXml.append("  <soapenv:Header>");
    loginXml.append("    <ns:loginOperationDetails>");
    loginXml.append("    </ns:loginOperationDetails>");
    loginXml.append("  </soapenv:Header>");
    loginXml.append("  <soapenv:Body>");
    loginXml.append("    <ns:LogIn>");
    loginXml.append("      <ns:logInInfo>");
    loginXml.append("        <ns:CustomerAccountId>customer1</ns:CustomerAccountId>");
    loginXml.append("        <ns:Username>JDoe</ns:Username>");
    loginXml.append("        <ns:Password>abc123</ns:Password>");
    loginXml.append("      </ns:logInInfo>");
    loginXml.append("    </ns:LogIn>");
    loginXml.append("  </soapenv:Body>");
    loginXml.append("</soapenv:Envelope>");

    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
    webServiceTemplate.setMessageFactory(newSoapMessageFactory);

    String uri = "http://xyz.example.com/xyz_1.0/membership.svc/ws";
    webServiceTemplate.setDefaultUri(uri);

    StreamSource source = new StreamSource(new StringReader(loginXml.toString()));
    StreamResult result = new StreamResult(System.out);

    boolean resultReturned = false;
    try {
        resultReturned = webServiceTemplate.sendSourceAndReceiveToResult(source, 
            new SoapActionCallback("http://example.com/xyz/2010/08/MembershipService/LogIn"), 
            result);
    } 
    catch (SoapFaultClientException sfe) {
        logger.error("SoapFaultClientException resultReturned: " + resultReturned, sfe);
        fail();
    }
}

L'erreur que je reçois du serveur dit:

500 Internal Server Error
The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://example.com/xyz/2010/08/MembershipService/LogIn'.
12
demandé sur approxiblue 2013-01-29 01:07:46

2 réponses

voici une réponse complète.

pendant que vous utilisez WebServiceTemplate en tant que classe pour communiquer avec le Webservice, Je ne comprends pas pourquoi mais il ne remplit pas correctement L'en-tête HTTP.

Certains WSDL ont une partie en disant:

<soap:operation
            soapAction="SOMELINK"
            style="document" />

Et WebServiceTemplate ne tient pas compte de cette partie. L'erreur ci-dessus signifie que votre soapAction paramètre dans l'en-tête est vide. Et il ne devrait pas être. Vérifiez avec Wireshark. Je l'ai fait-en utilisant un client et un ressort de savon de Chrome. Deuxième l'un a un en-tête non valide.


Pour y remédier, vous devez suivre la Section 6.2.4 ici: http://docs.spring.io/spring-ws/sites/2.0/reference/html/client.html

Ce qu'il dit est fondamentalement ajouter la partie en-tête sur votre propre, avec WebServiceMessageCallback interface. Vous pouvez lire plus dans la référence.

en gros, ça finit comme ça:

 webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {

    public void doWithMessage(WebServiceMessage message) {
        ((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
    }
});

Où vous pouvez configurer correctement la valeur d'en-tête. A fonctionné pour moi aussi. Toute la journée de lecture.

31
répondu Atais 2013-11-12 17:34:44

j'ai compris mais je n'ai jamais posté la réponse. Voici ce que j'ai trouvé qui fonctionne bien:

public WebServiceTemplate getWebServiceTemplate() throws SOAPException {
  if (webServiceTemplate == null) {
    final MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    final SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
    webServiceTemplate = new WebServiceTemplate(newSoapMessageFactory);
  }   

  return webServiceTemplate;
}

public Object sendReceive(Object requestObject, ArrayList<String> classesToMarshall, final String action)
        throws ClassNotFoundException, SoapFaultException, SoapFaultClientException, WebServiceTransportException,
        IllegalStateException, SOAPException {

  final WebServiceTemplate wst = getWebServiceTemplate();

    final SoapMarshallUtil smu = getSoapMarshallUtil();
    smu.configureMarshaller(wst, classesToMarshall);

    // soap 1.2
    SoapActionCallback requestCallback = new SoapActionCallback(action) {
        public void doWithMessage(WebServiceMessage message) {
            SaajSoapMessage soapMessage = (SaajSoapMessage) message;
            SoapHeader soapHeader = soapMessage.getSoapHeader();

            QName wsaToQName = new QName("http://www.w3.org/2005/08/addressing", "To", "wsa");
            SoapHeaderElement wsaTo =  soapHeader.addHeaderElement(wsaToQName);
            wsaTo.setText(uri);

            QName wsaActionQName = new QName("http://www.w3.org/2005/08/addressing", "Action", "wsa");
            SoapHeaderElement wsaAction =  soapHeader.addHeaderElement(wsaActionQName);
            wsaAction.setText(action);
        }
    };

    Object responseObject = wst.marshalSendAndReceive(this.uri, requestObject, requestCallback);
    return responseObject;
}
3
répondu Steve L 2013-09-03 22:08:46