如何使用WebServiceTemplate发送SOAP请求?

时间:2015-12-19 06:29:18

标签: java spring web-services soap jaxb

我正在尝试向SOAP Web服务发送请求。我阅读了this tutorial并准备了以下代码。但是,我将向多个SOAP Web服务发送不同的请求,而本教程则关注一个请求。如何使用WebserviceTemplate发送SOAP请求?

WebServiceTemplate

    SoapMessage soapMsg = new SoapMessage();
    soapMsg.setUsername("Requester");
    soapMsg.setPassword("Pass");
    soapMsg.setLanguageCode("EN");
    Request request = new Request();
    request.setDeparture("FDH");
    request.setDestination("HAM");
    Date date = new Date();
    SimpleDateFormat frm2 = new SimpleDateFormat("yyyy-MM-dd");
    request.setDepartureDate(frm2.parse(frm2.format(date)));
    request.setNumADT(1);
    request.setNumCHD(0);
    request.setNumInf(0);
    request.setCurrencyCode("EUR");
    request.setWaitForResult(true);
    request.setNearByDepartures(true);
    request.setNearByDestinations(true);
    request.setRronly(false);
    request.setMetaSearch(false);
    soapMsg.setRequest(request);
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate().  //how to create object and send request!
    Object response = webServiceTemplate.marshalSendAndReceive(
            "https://aaa5.elsyarres.net", soapMsg);
    Response msg = (Response) response;
    System.err.println("size of results of wogolo:"
            + msg.getFlights().getFlight().size());

5 个答案:

答案 0 :(得分:15)

您可以使用以下代码,您无需在xml文件中定义任何内容。

  try {
            SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(
                    MessageFactory.newInstance());
            messageFactory.afterPropertiesSet();

            WebServiceTemplate webServiceTemplate = new WebServiceTemplate(
                    messageFactory);
            Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

            marshaller.setContextPath("PACKAGE");
            marshaller.afterPropertiesSet();

            webServiceTemplate.setMarshaller(marshaller);
            webServiceTemplate.afterPropertiesSet();

            Response response = (Response) webServiceTemplate
                    .marshalSendAndReceive(
                            "address",
                            searchFlights);

            Response msg = (Response) response;
        } catch (Exception s) {
            s.printStackTrace();
        }

答案 1 :(得分:8)

要将不同的SOAP请求发送到不同的SOAP服务,您只需要让WebServiceTemplate知道它必须处理的所有请求和响应。

为每个请求和响应创建一个Java类,如下所示:

package models;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;

@XmlRootElement
public class FlyRequest implements Serializable {

    private boolean nearByDeparture;

    public FlyRequest() {}

    public boolean isNearByDeparture() {
        return nearByDeparture;
    }

    public void setNearByDeparture(boolean nearByDeparture) {
        this.nearByDeparture = nearByDeparture;
    }
}

(@ XmlRootElement是因为我们在下面使用JAXB marshaller;有关详细信息,请参阅Jaxb参考。)

模板的设置就像这样完成:

    SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());
    messageFactory.afterPropertiesSet();

    WebServiceTemplate webServiceTemplate = new WebServiceTemplate(messageFactory);
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("models");
    marshaller.afterPropertiesSet();

    webServiceTemplate.setMarshaller(marshaller);
    webServiceTemplate.afterPropertiesSet();

“models”是请求/响应类所在的包的名称,以便jaxb可以找到它们。

然后,您只需实例化要执行调用的类的请求,如下所示:

    // call fly service:
    FlyRequest flyRequest = new FlyRequest();
    flyRequest.setNearByDeparture(false);
    Object flyResponse = webServiceTemplate.marshalSendAndReceive("https://example.net/fly", flyRequest);

    // call purchase service:
    PurchaseRequest purchaseRequest = new PurchaseRequest();
    purchaseRequest.setPrice(100);
    Object purchaseResponse = webServiceTemplate.marshalSendAndReceive("https://example.net/purchase", purchaseRequest);

类似地,您可以将响应对象强制转换为上面定义的JAXB类。

答案 2 :(得分:2)

以下是您应该寻找的示例

REST不同,Soap有很多限制,它遵循一些必须满足的标准才能让网络呼叫工作,

但与Rest不同,如果你有WSDL网址,你可以获得拨打肥皂电话所需的所有信息

private final String NAMESPACE = "http://www.w3schools.com/webservices/";
private final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
private final String SOAP_ACTION = "http://www.w3schools.com/webservices/CelsiusToFahrenheit";
private final String METHOD_NAME = "CelsiusToFahrenheit";

这段代码是用Android编写的,所以你可以忽略它的某些部分,但我仍然保留它的答案,所以android背景的人可以很好地使用它

在浏览器中打开[WSDL][1]并检查在服务器上调用远程方法的重要事项。

  

1   您会看到一个属性targetNamespace,其值Namespace,在这种情况下您将使用Namespace http://www.w3schools.com/webservices/

     

2   现在您需要方法的名称,此WSDL有四个方法,每个都是int属性s:element,其值是方法的名称,在这种情况下,四个方法是FahrenheitToCelsius,{ {1}},FahrenheitToCelsiusResponseCelsiusToFahrenheit

     

3   现在你必须确定CelsiusToFahrenheitResponse SOAP Action   但是WSDL也提供了有关它的信息,查找标记NAMESPACE+METHOD并且它的soap:operation属性具有Soap操作,因为它在这种情况下的值我们要调用是soapAction

http://www.w3schools.com/webservices/CelsiusToFahrenheit

答案 3 :(得分:2)

假设您的SoapMessage是可马尔的

要将相同的消息发送到多个端点,您只需要循环发送代码和请求处理程序。

这样的事情:

{
    String endpoint = "https://aaa5.elsyarres.net"
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate().
    webServiceTemplate.setDefaultUri(endpoint);
    Object response = webServiceTemplate.marshalSendAndReceive(soapMsg);
    // handle you are response as you are currently doing.
    // Loop changing the endpoint as you need.
}

此代码使用Spring WebServiceTemplate

答案 4 :(得分:0)

我尝试了许多选项,如果您必须发送带有身份验证的soap标头(由wsimport创建的提供的身份验证对象)并且还需要设置soapaction,那么下面的一个选项对我有用。

public Response callWebService(String url, Object request)

{
    Response res = null;
    log.info("The request object is " + request.toString());

    try {
        
        

        res = (Response) getWebServiceTemplate().marshalSendAndReceive(url, request,new WebServiceMessageCallback() {
                 @Override
                  public void doWithMessage(WebServiceMessage message) {
                    try {
                      // get the header from the SOAP message
                      SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();

                      // create the header element
                      ObjectFactory factory = new ObjectFactory();
                      Authentication auth =
                          factory.createAuthentication();
                      auth.setUser("****");
                      auth.setPassword("******");
                     ((SoapMessage) message).setSoapAction(
                                "soapAction");

                      JAXBElement<Authentication> headers =
                          factory.createAuthentication(auth);

                      // create a marshaller
                      JAXBContext context = JAXBContext.newInstance(Authentication.class);
                      Marshaller marshaller = context.createMarshaller();

                      // marshal the headers into the specified result
                      marshaller.marshal(headers, soapHeader.getResult());
                      
                    } catch (Exception e) {
                      log.error("error during marshalling of the SOAP headers", e);
                    }
                  }
                });

        
    } catch (Exception e) {
        e.printStackTrace();
    }
    return res;

}