我正在尝试向SOAP Web服务发送请求。我阅读了this tutorial并准备了以下代码。但是,我将向多个SOAP Web服务发送不同的请求,而本教程则关注一个请求。如何使用WebserviceTemplate
发送SOAP请求?
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());
答案 0 :(得分:15)
您可以使用以下代码,您无需在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();
}
答案 1 :(得分:8)
要将不同的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 marshaller;有关详细信息,请参阅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类。
答案 2 :(得分:2)
以下是您应该寻找的示例
与REST
不同,Soap有很多限制,它遵循一些必须满足的标准才能让网络呼叫工作,
但与Rest
不同,如果你有WSDL
网址,你可以获得拨打肥皂电话所需的所有信息
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
,{ {1}},FahrenheitToCelsiusResponse
,CelsiusToFahrenheit
3 现在你必须确定
CelsiusToFahrenheitResponse
SOAP Action
但是WSDL也提供了有关它的信息,查找标记NAMESPACE+METHOD
并且它的soap:operation
属性具有Soap操作,因为它在这种情况下的值我们要调用是soapAction
http://www.w3schools.com/webservices/CelsiusToFahrenheit
答案 3 :(得分:2)
假设您的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
答案 4 :(得分:0)
我尝试了许多选项,如果您必须发送带有身份验证的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;
}