当我向服务器发送SOAP请求时,它返回以下错误,尽管我使用SoapUI发送类似请求并且可以正常工作.我似乎需要将我的SOAP请求更改为我使用SoapUI发送的请求. WSDL是here.
[ truncated ] System.Web.Services.Protocols.SoapException : The value of the
HTTP header ' SOAPAction ' was not recognized by the server . \ r \ n at
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest ( )
\ r \ n at System.Web.Servic
我正在使用Java发送以下请求
MetaSearch>falseMetaSearch>
我可以使用SoapUI发送以下请求,它可以工作
MetaSearch>falseMetaSearch>
我不知道如何使用Java创建的请求与我使用SoapUI发送的请求相同.
码
SearchFlights
@XmlRootElement(name = "SearchFlights")
@XmlAccessorType(XmlAccessType.FIELD)
public class SearchFlights {
@XmlElement(name = "SoapMessage")
private SoapMessage soapMessage;
getter and setter
的SOAPMessage
@XmlRootElement(name = "SoapMessage")
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapMessage {
@XmlElement(name = "Username")
private String username;
@XmlElement(name = "Password")
private String password;
@XmlElement(name = "LanguageCode")
private String languageCode;
@XmlElement(name = "Request")
private Request request;
getters and setters
请求
@XmlRootElement(name = "Request")
@XmlAccessorType(XmlAccessType.FIELD)
public class Request {
@XmlElement(name = "Departure")
private String departure;
@XmlElement(name = "Destination")
private String destination;
@XmlElement(name = "DepartureDate")
private String departureDate;
@XmlElement(name = "ReturnDate")
private String returnDate;
@XmlElement(name = "NumADT")
private int numADT;
@XmlElement(name = "NumINF")
private int numInf;
@XmlElement(name = "NumCHD")
private int numCHD;
@XmlElement(name = "CurrencyCode")
private String currencyCode;
@XmlElement(name = "WaitForResult")
private boolean waitForResult;
@XmlElement(name = "NearByDepartures")
private boolean nearByDepartures;
@XmlElement(name = "NearByDestinations")
private boolean nearByDestinations;
@XmlElement(name = "RROnly")
private boolean rronly;
@XmlElement(name = "MetaSearch")
private boolean MetaSearch;
getters and setters
package-info.java
@XmlSchema(
namespace = "ElsyArres.API",elementFormDefault = XmlNsForm.QUALIFIED)
package com.myproject.flights.wegolo;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
jaxb.index
SearchFlights
Flight
Flights
Leg
Legs
Outbound
Request
Response
SoapMessage
代码发送请求
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConstants;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
......
// populate searchFlights and other classes to create request
try {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(
MessageFactory.newInstance());
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(
messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.myproject.flights.wegolo");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",searchFlights);
Response msg = (Response) response;
System.err.println("Wegolo >>>"
+ msg.getFlights().getFlight().size());
} catch (Exception s) {
s.printStackTrace();
}
更新
我删除了package-info.java并设法使用建议的代码,但它仍然发送相同的标头.
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",searchFlights,new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message)
{
((SoapMessage)message).setSoapAction("http://www5v80.elsyarres.net/searchFlights");
}
}
);
SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.
通常,它在您的WSDL中指定,类似于(取自here):
如果这不在您的WSDL中,您可以在Web服务端点类中使用spring中的action注释来添加它.
@Endpoint
public class MyFlightEndpoint{
@Action("http://www5v80.elsyarres.net/searchFlights")
public SearchFlights request() {
...
}
}
如果它在您的WSDL中,您将希望将该值放入客户端的HTTP标头中.为此,您需要在创建消息后在客户端访问该消息,但在发送消息之前,需要添加动作标头. Spring提供了一个消息回调接口,如here所述.您要做的是:
Response response = (Response) webServiceTemplate
.marshalSendAndReceive(
"http://www5v80.elsyarres.net/service.asmx",new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message)
{
((SoapMessage)message).setSoapAction("http://www5v80.elsyarres.net/searchFlights");
}
}
);
如果您想了解更多信息,可以讨论SOAP操作标题here以及它们的要点(或缺少一点).
编辑:所以看看这里的wsdl:
你需要以下行动:
ElsyArres.API/searchFlights
现在只需更新代码即可阅读
((SoapMessage)message).setSoapAction("ElsyArres.API/searchFlights");
你很高兴去!
编辑2:当您使用SOAP 1.1时,我还注意到您正在连接的服务接受SOAP 1.2连接.您可以通过在工厂中设置SOAP来强制客户端使用SOAP 1.2.
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
messageFactory.afterPropertiesSet();
看起来服务器使用相同的端点,因此应该是唯一的更改.