Как отправить запрос 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
имеет четыре метода, каждый из которых является атрибутом ints: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;
}