La valeur de l'en-tête HTTP de "SOAPAction" n'était pas reconnu par le serveur
Lorsque j'envoie une requête SOAP pour le serveur il renvoie d'erreur suivant, même si j'ai envoyer la demande à l'aide de SoapUI et qui fonctionne. Il semble que j'ai besoin de changer mon SAVON demande à celui que j'envoie à l'aide de SoapUI. WSDL est ici.
[ 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
Je suis d'envoi suite à la demande à l'aide de Java
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:SearchFlights xmlns:ns2="ElysArres.API">
<ns2:SoapMessage>
<ns2:Username>Test</ns2:Username>
<ns2:Password>TestPassword</ns2:Password>
<ns2:LanguageCode>EN</ns2:LanguageCode>
<ns2:Request>
<ns2:Departure>ONT</ns2:Departure>
<ns2:Destination>EWR</ns2:Destination>
<ns2:DepartureDate>2016-01-20</ns2:DepartureDate>
<ns2:ReturnDate>2016-01-28</ns2:ReturnDate>
<ns2:NumADT>1</ns2:NumADT>
<ns2:NumINF>0</ns2:NumINF>
<ns2:NumCHD>0</ns2:NumCHD>
<ns2:CurrencyCode>EUR</ns2:CurrencyCode>
<ns2:WaitForResult>true</ns2:WaitForResult>
<ns2:NearbyDepartures>true</ns2:NearbyDepartures>
<ns2:NearbyDestinations>true</ns2:NearbyDestinations>
<ns2:RROnly>false</ns2:RROnly>
<ns2:MetaSearch>false</ns2:MetaSearch>
</ns2:Request>
</ns2:SoapMessage>
</ns2:SearchFlights>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Je peux envoyer sur demande à l'aide de SoapUI et il œuvres
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:els="ElsyArres.API">
<soap:Header/>
<soap:Body>
<els:SearchFlights>
<els:SoapMessage>
<els:Username>Test</els:Username>
<els:Password>TestPassword</els:Password>
<els:LanguageCode>EN</els:LanguageCode>
<els:Request>
<els:Departure>ONT</els:Departure>
<els:Destination>EWR</els:Destination>
<els:DepartureDate>2016-01-20</els:DepartureDate>
<els:ReturnDate>2016-01-28</els:ReturnDate>
<els:NumADT>1</els:NumADT>
<els:NumINF>0</els:NumINF>
<els:NumCHD>0</els:NumCHD>
<els:CurrencyCode>EUR</els:CurrencyCode>
<els:WaitForResult>true</els:WaitForResult>
<els:NearbyDepartures>true</els:NearbyDepartures>
<els:NearbyDestinations>true</els:NearbyDestinations>
<els:RROnly>false</els:RROnly>
<els:MetaSearch>false</els:MetaSearch>
</els:Request>
</els:SoapMessage>
</els:SearchFlights>
</soap:Body>
</soap:Envelope>
Je ne suis pas sûr de savoir comment faire la demande que je suis en train de créer avec Java même chose que ce que je l'envoie avec SoapUI.
Code
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
Demande
@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.l'indice de
SearchFlights
Flight
Flights
Leg
Legs
Outbound
Request
Response
SoapMessage
Code pour envoyer la demande
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();
}
Mise à jour
J'ai enlevé package-info.java
et réussi à utiliser les suggéré de code, mais il est encore d'envoyer le même en-tête.
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");
}
}
);
1.1
(qui utilise le SAVON d'Action en-tête), de sorte que le client se comporte correctement: MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
comment puis-je utiliser dans mon code? souhaitez-vous approfondir?
Juste comme ça:
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
et puis WebServiceTemplate webServiceTemplate = new WebServiceTemplate(messageFactory);
. Laissez-moi savoir si cela fonctionne!J'ai changé le code pour MessageFactory messageFactory = MessageFactory .newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); SaajSoapMessageFactory soapMsgFac = new SaajSoapMessageFactory( messageFactory.newInstance()); mais je ne reçois toujours le même message d'erreur.
OriginalL'auteur Daniel Newtown | 2016-01-06
Vous devez vous connecter pour publier un commentaire.
Version SOAP 1.1 nécessite une en-tête HTTP dans votre requête SOAP pour spécifier le SAVON d'action. Il n'est pas dans le XML, c'est une partie de la demande (dans l'en-tête HTTP), de sorte que c'est pourquoi vous ne voyez pas la différence entre votre SoapUI demande xml, et la demande que vous envoyez à l'aide de la WebServiceTemplate. Soap 1.2 vous permet de le définir comme un attribut du type de support, mais qui n'est pas valide pour un 1.1 serveur. Note que, selon le spécification, la valeur que vous utilisez n'a pas à être résolu.
Généralement, il est spécifié dans votre fichier WSDL, quelque chose comme (prises de ici):
Si ce n'est pas dans votre WSDL, vous pouvez les ajouter à l'aide du
action
annotation au printemps dans votre webservice point de terminaison de la classe.Si c'est dans votre WSDL, vous aurez envie de placer cette valeur dans votre en-tête HTTP sur le côté client. Pour ce faire, vous devrez ensuite obtenir l'accès au message sur le côté client après sa création, mais avant d'être envoyé afin d'ajouter l'action d'en-tête. Spring fournit un message de rappel de l'interface pour que, qui est décrit ici. Ce que vous voulez faire, c'est quelque chose comme:
Il y a une discussion sur le SAVON d'action en-têtes ici, et le point (ou l'absence de point) pour eux si vous voulez en savoir plus.
Edit: Donc en regardant le wsdl ici:
vous allez vouloir l'action suivante:
Maintenant de simplement mettre à jour le code pour lire
et vous êtes bon pour aller!
Edit 2: j'ai aussi un avis sur le service que vous êtes connecté à accepte SOAP 1.2 connexions, tandis que vous êtes à l'aide de SOAP 1.1. Vous pouvez forcer votre client pour l'utilisation de SOAP 1.2 en la plaçant dans votre usine.
On dirait que le serveur utilise le même système d'extrémité, de sorte que devrait être le seul changement.
Quelle est la version de spring-ws utilisez-vous? Javadoc suggère la méthode n'existe pas (docs.printemps.io/spring-ws/site/apidocs/org/springframework/ws/...). Vérifiez vos importations, et assurez-vous que vous êtes un casting pour org.springframework.ws.le savon.SoapMessage correctement.
Je suis à l'aide 3.2.8.LIBÉRATION
Qui sonne comme la version de Printemps, vous êtes en utilisant. La version actuelle de spring-ws est 2.1.4. Quelle que soit la version, org.springframework.ws.le savon.SoapMessage a un setSoapAction(String soapAction) méthode d'aussi loin que 1.0-rc2. Je soupçonne fortement vos déclarations d'importation sont mauvais. Assurez-vous que vous pouvez voir un
import org.springframework.ws.soap.SoapMessage;
J'ai inclus mon importations, pas sûr de ce que tu veux dire par les importations.
OriginalL'auteur AndyN
Une autre façon d'ajouter de la
SOAPAction
d'en-tête lors de l'utilisation deWebServiceGatewaySupport
est de faire ce qui suit:C'est à l'aide de
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
OriginalL'auteur adnans
J'ai eu le même problème, ma solution était :
Et mon SoapService
Très important sur la création d'un message à l'usine
OriginalL'auteur sashanet buryk