簡體   English   中英

如何使用 WebServiceTemplate 發送 SOAP 請求?

[英]How to send a SOAP request using WebServiceTemplate?

我正在嘗試向 SOAP 網絡服務發送請求。 我閱讀了本教程並准備了以下代碼。 但是,我將向多個 SOAP Web 服務發送不同的請求,而本教程只關注一個請求。 如何使用WebserviceTemplate發送 SOAP 請求?

Web服務模板

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

你可以使用下面的代碼,你不需要在 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();
        }

要將不同的 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 編組器;有關更多信息,請參閱 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 類。

這是您應該尋找的示例

REST不同,Soap 有很多限制,它遵循一些必須滿足的標准,才能讓網絡調用工作,

但與Rest不同,在 Soap 中,如果您有WSDL URL,您可以獲得調用 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";

這段代碼是用Android編寫的,所以你可以忽略它的一部分,但我仍然保留它作為答案,這樣來自 Android 背景的人可以很好地利用它

在瀏覽器中打開[WSDL][1]並檢查在服務器上調用遠程方法的重要事項。

1 您將看到一個屬性targetNamespace ,其值為Namespace ,您將在本例中使用Namespacehttp://www.w3schools.com/webservices/

2 現在你需要方法的名稱,這個WSDL有四個方法,每個方法都是 int 屬性s:element ,其值是方法的名稱,在這種情況下,四個方法是FahrenheitToCelsiusFahrenheitToCelsiusResponseCelsiusToFahrenheitCelsiusToFahrenheitResponse

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

假設您的 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

我嘗試了很多選項,如果您必須發送帶身份驗證的 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;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM