Как отправить запрос SOAP с помощью WebServiceTemplate?

Я пытаюсь отправить запрос на веб-службу SOAP. Я прочитал этот урок и подготовил следующий код. Тем не менее, я собираюсь отправлять разные запросы нескольким веб-сервисам SOAP, тогда как учебное пособие сфокусировано на одном запросе. Как я могу отправить запрос 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());

4 ответа

Решение

Вы можете использовать следующий код, вам не нужно ничего определять в 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" - это имя пакета, в котором находятся классы Request/Response, чтобы 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Это соответствует некоторым стандартам, которые должны быть выполнены, прежде чем вы получите сетевой вызов на работу,

Но в отличие от Restв мыло если есть WSDL URL вы можете получить всю информацию, необходимую для вызова мыло вызов

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

Предполагая, что ваше SoapMessage является marhsallable

Чтобы отправить одно и то же сообщение нескольким конечным точкам, вам нужно только зациклить код отправки и обработчик запроса.

Что-то вроде этого:

{
    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

Я пробовал много вариантов, и, наконец, один из них работал у меня, если вам нужно отправить заголовок мыла с аутентификацией (предоставленный объект аутентификации, созданный 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;

}
Другие вопросы по тегам