Java 如何使用 WebServiceTemplate 发送 SOAP 请求?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34368029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:34:58  来源:igfitidea点击:

How to send a SOAP request using WebServiceTemplate?

javaspringweb-servicessoapjaxb

提问by Hyman

I am trying to send a request to a SOAP webservice. I read this tutorialand prepared the following code. However, I am going to send different requests to multiple SOAP webservices, whereas the tutorial focused on one request. How can I send SOAP request using WebserviceTemplate?

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

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

采纳答案by Daniel Newtown

You can use following code, you do not need to define anything in xml file.

您可以使用以下代码,您不需要在 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();
        }

回答by Pankaj Nimgade

Here is an Example what you should be looking for

这是您应该寻找的示例

Soap has a lot of restriction unlike REST, It follows some standards which have to be meet before you get Network call to work,

Soap 有很多限制,不像REST,它遵循一些标准,在您获得网络呼叫工作之前必须满足这些标准,

But unlike Rest, in Soap if you have WSDLURL you can get all the information needed to call the Soap call

但与RestSoap不同的是,如果您有WSDLURL,则可以获取调用 Soap 调用所需的所有信息

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

this code was written in Androidso you can ignore some part of it but I still kept it in answer so someone from android background can put a good use to it

这段代码是这样写的,Android所以你可以忽略它的一部分,但我仍然保留它的答案,所以来自 android 背景的人可以很好地利用它

Open [WSDL][1]in browser and check for the things which matter to call a remote method on server.

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

1 you will see an attribute targetNamespacewhose value would be Namespacewhich you will use in this case Namespaceis http://www.w3schools.com/webservices/

2 Now you require the name of the method this WSDLhas four method each of the are int attribute s:elementwith the value is the name of the Method in this case four methods are FahrenheitToCelsius, FahrenheitToCelsiusResponse, CelsiusToFahrenheit, CelsiusToFahrenheitResponse

3 Now you have to fure out the SOAP Actionwhich is NAMESPACE+METHODbut WSDL also gives information about that as well, look for the tag soap:operationand it's soapActionattribute havs the Soap action as it's value in this case which we want to call is http://www.w3schools.com/webservices/CelsiusToFahrenheit

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

2 现在你需要方法的名称,它WSDL有四个方法,每个都是 int 属性s:element,值是方法的名称,在这种情况下,四个方法是 FahrenheitToCelsius, FahrenheitToCelsiusResponse, CelsiusToFahrenheit,CelsiusToFahrenheitResponse

3 现在您必须确定SOAP Action哪个是,NAMESPACE+METHOD但 WSDL 也提供了相关信息,查找标记soap:operation,它的 soapAction属性具有 Soap 操作,因为在这种情况下,我们要调用它的值是http://www.w3schools.com/webservices/CelsiusToFahrenheit

private class MyTask extends AsyncTask<Void, Void, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            SoapObject soapObject = new SoapObject(NAMESPACE, METHOD_NAME);

            soapObject.addProperty("Celsius","12");


            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.dotNet = true;
            envelope.setOutputSoapObject(soapObject);
            HttpTransportSE httpTransportSE = new HttpTransportSE(URL);

            httpTransportSE.call(SOAP_ACTION, envelope);
            SoapPrimitive soapPrimitive = (SoapPrimitive)envelope.getResponse();
            Log.d("TAG", "doInBackground: "+soapPrimitive.toString());

            return soapObject.toString();

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

        return null;
    }

    @Override
    protected void onPostExecute(String aVoid) {
        super.onPostExecute(aVoid);
        progressDialog.dismiss();
        textView.setText(""+aVoid);
    }
}

回答by smarquis

To send different SOAP requests to different SOAP services, you just need to make your WebServiceTemplate aware of all requests and responses it will have to process.

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

Create a Java class for each request and response like so:

为每个请求和响应创建一个 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;
    }
}

(The @XmlRootElement is because we use JAXB marshaller below; see Jaxb reference for more info).

(@XmlRootElement 是因为我们在下面使用 JAXB 编组器;有关更多信息,请参阅 Jaxb 参考)。

The setup of the template is done for example like so:

模板的设置是这样完成的:

    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" is the name of the package where the Request/Responses classes are, so that jaxb can find them.

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

Then you just instantiate the request of the class you want to perform the call, like so:

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

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

Similarly, you can cast the response objects into your JAXB classes defined above.

同样,您可以将响应对象转换为上面定义的 JAXB 类。

回答by Mike Murphy

Assuming that your SoapMessage is marhsallable

假设你的 SoapMessage 是 marhsallable

To send the same message to multiple endpoints you only need to loop on the sending code and the request handler.

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

Something like this:

像这样的东西:

{
    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.
}

This code uses the Spring WebServiceTemplate

此代码使用 Spring WebServiceTemplate