[英]How to send a SOAP request using WebServiceTemplate?
I am trying to send a request to a SOAP webservice.我正在尝试向 SOAP 网络服务发送请求。 I readthis tutorial and prepared the following code.
我阅读了本教程并准备了以下代码。 However, I am going to send different requests to multiple SOAP webservices, whereas the tutorial focused on one request.
但是,我将向多个 SOAP Web 服务发送不同的请求,而本教程只关注一个请求。 How can I send SOAP request using
WebserviceTemplate
?如何使用
WebserviceTemplate
发送 SOAP 请求?
WebServiceTemplate 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());
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();
}
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 类。
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,与
REST
不同,Soap 有很多限制,它遵循一些必须满足的标准,才能让网络调用工作,
But unlike Rest
, in Soap if you have WSDL
URL you can get all the information needed to call the Soap call但与
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";
this code was written in Android
so 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
targetNamespace
whose value would beNamespace
which you will use in this caseNamespace
ishttp://www.w3schools.com/webservices/
1 您将看到一个属性
targetNamespace
,其值为Namespace
,您将在本例中使用Namespace
为http://www.w3schools.com/webservices/
2 Now you require the name of the method this
WSDL
has four method each of the are int attributes:element
with the value is the name of the Method in this case four methods areFahrenheitToCelsius
,FahrenheitToCelsiusResponse
,CelsiusToFahrenheit
,CelsiusToFahrenheitResponse
2 现在你需要方法的名称,这个
WSDL
有四个方法,每个方法都是 int 属性s:element
,其值是方法的名称,在这种情况下,四个方法是FahrenheitToCelsius
、FahrenheitToCelsiusResponse
、CelsiusToFahrenheit
、CelsiusToFahrenheitResponse
3 Now you have to fure out the
SOAP Action
which isNAMESPACE+METHOD
but WSDL also gives information about that as well, look for the tagsoap:operation
and it'ssoapAction
attribute havs the Soap action as it's value in this case which we want to call ishttp://www.w3schools.com/webservices/CelsiusToFahrenheit
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);
}
}
Assuming that your SoapMessage is marhsallable假设您的 SoapMessage 是可编组的
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
I tried many options and finally below one worked for me if you have to send soap header with authentication(Provided authentication object created by wsimport) and also need to set soapaction.我尝试了很多选项,如果您必须发送带身份验证的 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.