服务器无法识别HTTP标头SOAPAction的值

丹尼尔·纽敦(Daniel Newtown):

当我将SOAP请求发送到服务器时,尽管我使用SoapUI发送了类似的请求,但它返回以下错误,并且可以正常工作。看来我需要将SOAP请求更改为使用SoapUI发送的请求。WSDL这里

 [ 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发送以下请求

<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>

我可以使用SoapUI发送以下请求,它可以正常工作

<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>

我不确定如何使使用Java创建的请求与使用SoapUI发送的请求相同。

搜索航班

@XmlRootElement(name = "SearchFlights")
@XmlAccessorType(XmlAccessType.FIELD)
public class SearchFlights {
    @XmlElement(name = "SoapMessage")
    private SoapMessage soapMessage;

    getter and setter

肥皂消息

@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

包信息.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.in​​dex

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");
                                }
                           }
                       );

在此处输入图片说明

安迪(AndyN):

SOAP版本1.1在您的SOAP请求中需要HTTP标头来指定SOAP操作。它不在实际的XML中,而是请求的一部分(在HTTP标头中),因此这就是为什么您没有看到SoapUI请求xml与使用WebServiceTemplate发送的请求之间存在任何差异的原因。Soap 1.2允许您将其设置为媒体类型的属性,但是对于1.1服务器无效。请注意,根据规范,您使用的值不必是可解析的。

SOAP对URI的格式或特殊性或其可解析性没有任何限制。发出SOAP HTTP请求时,HTTP客户端必须使用此标头字段。

通常,它是在您的WSDL中指定的,类似于(从此处获取):

<soap:operation
        soapAction="http://www5v80.elsyarres.net/searchFlights"
        style="document" />

如果这不在您的WSDL中,则可以通过action在Spring的webservice端点类中使用注释来添加它

@Endpoint
public class MyFlightEndpoint{
    @Action("http://www5v80.elsyarres.net/searchFlights")
    public SearchFlights request() {
        ...
    }
}

如果它在您的WSDL中,则需要将该值放入客户端的HTTP标头中。为此,您需要在创建消息之后但在发送之前在客户端访问消息,以便添加操作标头。Spring提供了一个消息回调接口,所描述的在这里您想要做的是这样的:

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动作头的讨论在这里,和点(或缺少点)为他们,如果你想知道更多。

编辑:所以在这里看wsdl:

<soap:operation soapAction="ElsyArres.API/SearchFlights" style="document"/>

您需要执行以下操作:

ElsyArres.API/searchFlights

现在只需更新代码以阅读

((SoapMessage)message).setSoapAction("ElsyArres.API/searchFlights");

你很高兴去!

编辑2:在使用SOAP 1.1时,我还注意到您要连接的服务接受SOAP 1.2连接。您可以通过在工厂中进行设置来强制客户端使用SOAP 1.2。

messageFactory.setSoapVersion(SoapVersion.SOAP_12);
messageFactory.afterPropertiesSet();

看起来服务器使用相同的端点,因此这应该是唯一的更改。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从服务器收到重复的标头

本地服务器可识别HTTP请求标头,但在线服务器无法识别

我的问题是“发送HTTP标头后服务器无法设置状态”。

发送HTTP标头后服务器无法设置状态-Web API CORS

OAuthBearerAuthenticationMiddleware-服务器无法在发送HTTP标头后追加标头

发送HTTP标头后,服务器无法追加标头@ Html.AntiForgery

无法删除服务器:Apache标头

服务器如何设置HTTP响应标头?

服务器响应的.NET标头

当HTTP服务器接收到“ Origin:null”标头时,该怎么办?(CORS)

无法获得任何响应-发送HTTP标头后,服务器无法附加标头

发送标头后无法设置标头。:Raspbian Web服务器上的Sendgrid邮件响应

服务器时区值“ KST”无法识别:如何修复服务器端?

服务器时区值“ Ostereuropeische Zeit”无法识别

ErrorSessionTokenFilter:通过HTTP标头提供的令牌与服务器生成的令牌不匹配

AzureStorage:服务器无法验证请求。确保正确构成Authorization标头的值(包括签名)

使用“ Range”标头时,无法从服务器获取Java的GZIPInputStream来读取服务器的“ gzip”响应

监视出站服务器http标头信息?

ASP.NET MVC-发送HTTP标头后,服务器无法修改Cookie

MVC4-发送HTTP标头后,服务器无法设置状态

从libevent中的HTTP服务器响应获取所有HTTP标头

更改Apache httpd“服务器:” HTTP标头

HTTP响应标头,用于识别响应请求的实际服务器

在行命令上发送HTTP标头后,服务器无法设置内容类型

Python-SOAP Server无法识别HTTP标头的值

NULL http 标头从 Angular2 应用程序传递到服务器

发送 HTTP 标头后,间歇性服务器无法设置状态

返回服务器可用内容类型的 HTTP 标头

如何解决错误?“服务器无法识别 HTTP 标头 SOAPAction 的值”