SOAP-WS 无法识别 HTTP Header SOAPAction 的值
Unrecognized value of HTTP Header SOAPAction with SOAP-WS
我正在尝试使用与第 3 方预订服务器相关的 SOAP Web 服务。
这是工作请求(使用 SOAPUI 测试):
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<OGHeader transactionID="SomeID" primaryLangID="E"
timeStamp="SomeTimeStamp" channelValidation="false"
timeStampSpecified="true" xmlns="http://webservices.****">
<Origin entityID="****" systemType="****" />
<Destination entityID="***" systemType="**" />
<Authentication>
<UserCredentials>
<UserName>*****</UserName>
<UserPassword>*****</UserPassword>
<Domain>***</Domain>
</UserCredentials>
</Authentication>
</OGHeader>
</soapenv:Header>
<soapenv:Body>
<FutureBookingSummaryRequest
canHandleVaultedCreditCard="true"
xmlns="*****.wsdl">
<AdditionalFilters GetList="true"
IncludePseudoRoom="false" ReservationDisposition="***"
ReservationStatus="RESERVED">
<ns1:HotelReference hotelCode="******"
xmlns:ns1="http://webservices.****" />
</AdditionalFilters>
</FutureBookingSummaryRequest>
</soapenv:Body>
</soapenv:Envelope>
从 WSDL 生成所需的包后
我创建了我的 SOAP 客户端,如下所示:
public class GloriaWClient {
private static final Logger log = LoggerFactory.getLogger(GloriaWClient.class);
public void getFutureBooking() {
FutureBookingSummaryRequest futurebookingrequest = new FutureBookingSummaryRequest();
/********** Setting the BookingFilters ****************************/
FetchBookingFilters booking_filters = new FetchBookingFilters();
booking_filters.setGetList(true);
booking_filters.setIncludePseudoRoom(false);
booking_filters.setReservationDisposition(ReservationDispositionType.***);
booking_filters.setReservationStatus(ReservationStatusType.***);
/************************** HotelReference ****************************/
HotelReference hotelReference = new HotelReference();
hotelReference.setHotelCode("***");
booking_filters.setHotelReference(hotelReference);
/****************************** REQUEST ********************************/
futurebookingrequest.setCanHandleVaultedCreditCard(true);
futurebookingrequest.setAdditionalFilters(booking_filters);
log.info("Requesting future booking");
try {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());
/******* Adding the SOAP Header ****/
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.GeneratedPackage's name");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
FutureBookingSummaryResponse response = (FutureBookingSummaryResponse) webServiceTemplate
.marshalSendAndReceive("https://***********.asmx",
futurebookingrequest, new WebServiceMessageCallback() {
@Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
try {
// Setting header values
OGHeader ogHeader = new OGHeader();
ogHeader.setTransactionID("****");
ogHeader.setPrimaryLangID("**");
ogHeader.setChannelValidation(false);
log.debug("Created ogHeader");
OGHeaderAuthentication ogHeaderAuth = new OGHeaderAuthentication();
OGHeaderAuthenticationUserCredentials ogHeaderAuthUserCredentials = new OGHeaderAuthenticationUserCredentials();
ogHeaderAuthUserCredentials.setUserName("******");
ogHeaderAuthUserCredentials.setUserPassword("****");
ogHeaderAuthUserCredentials.setDomain("***");
ogHeaderAuth.setUserCredentials(ogHeaderAuthUserCredentials);
ogHeader.setAuthentication(ogHeaderAuth);
// get the header from the SOAP message
SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
log.debug("Got header from the SOAP message");
// create the header element
ObjectFactory factory = new ObjectFactory();
OGHeader futureBookingsummarySoapHeaders = factory.createOGHeader(); futureBookingsummarySoapHeaders.setAuthentication(ogHeaderAuth);
JAXBElement<OGHeader> headers = factory .createOGHeader(futureBookingsummarySoapHeaders);
log.debug("Header element created");
// create a marshaller
JAXBContext context = JAXBContext.newInstance(OGHeader.class);
Marshaller marshaller = context.createMarshaller();
log.debug("Marshaller created");
// 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);
}
}
});
FutureBookingSummaryResponse msg = (FutureBookingSummaryResponse) response;
} catch (Exception s) {
s.printStackTrace();
}
}
}
请注意,我确保设置了适当的 Body 和 header 的属性。
这个客户端的执行抛出这个:
org.springframework.ws.soap.client.SoapFaultClientException: Server did not recognize the value of HTTP Header SOAPAction: .
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at com.lbc.migration.GloriaClient.GloriaWClient.getFutureBooking(GloriaWClient.java:104)
at com.lbc.migration.main.main(main.java:16)
有什么想法吗?或创建 Spring 引导 SOAP 客户端的任何相关示例 header ??
如您的错误所示,您缺少 SOAPAction header。
SOAPAction is HTTP Header and its different from SOAPEnvelope Header.
WSDL 应该有 SOAPAction 的定义,例如,
<soap1:operation style="document" soapAction="petition"
它在 HTTP Header 中, 而不是 在 SOAPEnvelope Header 中,正如您在请求信封中提到的那样。
HTTP Header 在 TCPMONitor
中将类似于下面的内容
POST /StockQuote HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "petition"
应该设置成类似--
webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
}});
我正在尝试使用与第 3 方预订服务器相关的 SOAP Web 服务。
这是工作请求(使用 SOAPUI 测试):
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<OGHeader transactionID="SomeID" primaryLangID="E"
timeStamp="SomeTimeStamp" channelValidation="false"
timeStampSpecified="true" xmlns="http://webservices.****">
<Origin entityID="****" systemType="****" />
<Destination entityID="***" systemType="**" />
<Authentication>
<UserCredentials>
<UserName>*****</UserName>
<UserPassword>*****</UserPassword>
<Domain>***</Domain>
</UserCredentials>
</Authentication>
</OGHeader>
</soapenv:Header>
<soapenv:Body>
<FutureBookingSummaryRequest
canHandleVaultedCreditCard="true"
xmlns="*****.wsdl">
<AdditionalFilters GetList="true"
IncludePseudoRoom="false" ReservationDisposition="***"
ReservationStatus="RESERVED">
<ns1:HotelReference hotelCode="******"
xmlns:ns1="http://webservices.****" />
</AdditionalFilters>
</FutureBookingSummaryRequest>
</soapenv:Body>
</soapenv:Envelope>
从 WSDL 生成所需的包后 我创建了我的 SOAP 客户端,如下所示:
public class GloriaWClient {
private static final Logger log = LoggerFactory.getLogger(GloriaWClient.class);
public void getFutureBooking() {
FutureBookingSummaryRequest futurebookingrequest = new FutureBookingSummaryRequest();
/********** Setting the BookingFilters ****************************/
FetchBookingFilters booking_filters = new FetchBookingFilters();
booking_filters.setGetList(true);
booking_filters.setIncludePseudoRoom(false);
booking_filters.setReservationDisposition(ReservationDispositionType.***);
booking_filters.setReservationStatus(ReservationStatusType.***);
/************************** HotelReference ****************************/
HotelReference hotelReference = new HotelReference();
hotelReference.setHotelCode("***");
booking_filters.setHotelReference(hotelReference);
/****************************** REQUEST ********************************/
futurebookingrequest.setCanHandleVaultedCreditCard(true);
futurebookingrequest.setAdditionalFilters(booking_filters);
log.info("Requesting future booking");
try {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());
/******* Adding the SOAP Header ****/
messageFactory.afterPropertiesSet();
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(messageFactory);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.GeneratedPackage's name");
marshaller.afterPropertiesSet();
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.afterPropertiesSet();
FutureBookingSummaryResponse response = (FutureBookingSummaryResponse) webServiceTemplate
.marshalSendAndReceive("https://***********.asmx",
futurebookingrequest, new WebServiceMessageCallback() {
@Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException{
try {
// Setting header values
OGHeader ogHeader = new OGHeader();
ogHeader.setTransactionID("****");
ogHeader.setPrimaryLangID("**");
ogHeader.setChannelValidation(false);
log.debug("Created ogHeader");
OGHeaderAuthentication ogHeaderAuth = new OGHeaderAuthentication();
OGHeaderAuthenticationUserCredentials ogHeaderAuthUserCredentials = new OGHeaderAuthenticationUserCredentials();
ogHeaderAuthUserCredentials.setUserName("******");
ogHeaderAuthUserCredentials.setUserPassword("****");
ogHeaderAuthUserCredentials.setDomain("***");
ogHeaderAuth.setUserCredentials(ogHeaderAuthUserCredentials);
ogHeader.setAuthentication(ogHeaderAuth);
// get the header from the SOAP message
SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
log.debug("Got header from the SOAP message");
// create the header element
ObjectFactory factory = new ObjectFactory();
OGHeader futureBookingsummarySoapHeaders = factory.createOGHeader(); futureBookingsummarySoapHeaders.setAuthentication(ogHeaderAuth);
JAXBElement<OGHeader> headers = factory .createOGHeader(futureBookingsummarySoapHeaders);
log.debug("Header element created");
// create a marshaller
JAXBContext context = JAXBContext.newInstance(OGHeader.class);
Marshaller marshaller = context.createMarshaller();
log.debug("Marshaller created");
// 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);
}
}
});
FutureBookingSummaryResponse msg = (FutureBookingSummaryResponse) response;
} catch (Exception s) {
s.printStackTrace();
}
}
}
请注意,我确保设置了适当的 Body 和 header 的属性。
这个客户端的执行抛出这个:
org.springframework.ws.soap.client.SoapFaultClientException: Server did not recognize the value of HTTP Header SOAPAction: . at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38) at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830) at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624) at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) at com.lbc.migration.GloriaClient.GloriaWClient.getFutureBooking(GloriaWClient.java:104) at com.lbc.migration.main.main(main.java:16)
有什么想法吗?或创建 Spring 引导 SOAP 客户端的任何相关示例 header ??
如您的错误所示,您缺少 SOAPAction header。
SOAPAction is HTTP Header and its different from SOAPEnvelope Header.
WSDL 应该有 SOAPAction 的定义,例如,
<soap1:operation style="document" soapAction="petition"
它在 HTTP Header 中, 而不是 在 SOAPEnvelope Header 中,正如您在请求信封中提到的那样。
HTTP Header 在 TCPMONitor
POST /StockQuote HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "petition"
应该设置成类似--
webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
}});