Вопрос

I am trying to write a client for publicly exposed service. I only need to pass raw XML (as Java string) and view raw response. No binding is required.

Service is publicly exposed here: http://www.webservicex.net/periodictable

I verified that following request XML works correctly (via Soap UI):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
   <soapenv:Header/>
   <soapenv:Body>
      <web:GetAtomicWeight>
         <!--Optional:-->
         <web:ElementName>Aluminium</web:ElementName>
      </web:GetAtomicWeight>
   </soapenv:Body>
</soapenv:Envelope>

I am using Spring's template for WS, Maven dependency here:

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

Now, here is my simple "main" application. It just delegates XML string to Spring's WebServiceTemplate and expect to see result in System.out.

package sk.xorty.ws;

import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.client.core.SoapActionCallback;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;

public class WsTest {

    private static final String REQUEST_PERIODIC =
            "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:web=\"http://www.webserviceX.NET\">\n" +
            "   <soap:Header/>\n" +
            "   <soap:Body>\n" +
            "      <web:GetAtomicWeight>\n" +
            "         <web:ElementName>Aluminium</web:ElementName>\n" +
            "      </web:GetAtomicWeight>\n" +
            "   </soap:Body>\n" +
            "</soap:Envelope>\n";

    private static final String URL_PERIODIC = "http://www.webservicex.net/periodictable";

    private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

    // send to an explicit URI
    public void customSendAndReceive() throws SOAPException {
        MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(messageFactory);
        webServiceTemplate.setMessageFactory(newSoapMessageFactory);

        StreamSource source = new StreamSource(new StringReader(REQUEST_PERIODIC));
        StreamResult result = new StreamResult(System.out);
        webServiceTemplate.sendSourceAndReceiveToResult(URL_PERIODIC, source,
                new SoapActionCallback("GetAtomicWeight"), result);
    }

    public static void main(String[] args) throws SOAPException {
        new WsTest().customSendAndReceive();
    }
}

Example is runnable (it only needs dependency above in classpath). It throws following error:

INFO: Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
Exception in thread "main" org.springframework.ws.client.WebServiceTransportException: Not Found [404]
    at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:663)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:587)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:492)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:436)
    at sk.xorty.ws.WsTest.customSendAndReceive(WsTest.java:38)
    at sk.xorty.ws.WsTest.main(WsTest.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

EDIT: Correct value for request is this one:

private static final String REQUEST_PERIODIC = "<web:GetAtomicWeight xmlns:web=\"http://www.webserviceX.NET\">\n" +
        "         <!--Optional:-->\n" +
        "         <web:ElementName>Aluminium</web:ElementName>\n" +
        "      </web:GetAtomicWeight>";
Это было полезно?

Решение

I think your problem has to do with the soapActionCallBack. You are calling the operation only not the operation with the uri. Below is the example from here:

If you remark the namespace is http://tempuri.org and the provided argument for soapActionCallback is http://tempuri.org/SOAPACTION*

 WebServiceTemplate template = new WebServiceTemplate(messageFactory);
 Result result = new DOMResult();
 template.sendSourceAndReceiveToResult(
     new StringSource("<content xmlns=\"http://tempuri.org\"/>"),
     new SoapActionCallback("http://tempuri.org/SOAPAction"),
     result);

In your case, the soap action should be http://www.webserviceX.net/GetAtomicWeight ( I am not so sure about the capitalization though)

Другие советы

If you are using annotations, make sure the namespace attribute of the following annotations match the namespace attribute of the corresponding WSDL Elements:

@XmlRootElement(namespace = "http://webService.mydomain.com", name = "someSOAPRequest")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {      
        "xmlTag#1",
        "xmlTag#2",
        "xmlTag#3",
        "xmlTag#4",
},  namespace = "http://webService.mydomain.com", name = "someSOAPRequest")

If you are not using annotations make sure the namespace attributes match between the code and the WSDL elements.

I had the same error and I was using Soap1.1, I've noticed that the WS was exposed by Spring throgh the @SoapAction annotation and my client generated with Spring WS and JAXB did not set any soapAction by default, so I had to use a SoapActionCallback to set it with the SoapAction specified in WSDL for that operation.

 SoapActionCallback soapActionCallback = new SoapActionCallback("restituisciStatiMessaggioListRequestSA");
    RestituisciStatiMessaggioListResponse response = (RestituisciStatiMessaggioListResponse) getWebServiceTemplate().marshalSendAndReceive(request,soapActionCallback);

I fixed my issue by removing SOAP request headers from my message. So let spring worry about the SOAP request, and your code just sends your request data.

So try:

   private static final String REQUEST_PERIODIC =
               "<web:GetAtomicWeight xmlns:web=\"http://www.webserviceX.NET\">\n" +
               "    <web:ElementName>Aluminium</web:ElementName>\n" +
               "</web:GetAtomicWeight>\n";
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top