当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《服务器无法识别HTTP标头"SOAPAction"的值》经验,为你挑选了1个好方法。

当我向服务器发送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发送以下请求


   
   
      
         
            Test
            TestPassword
            EN
            
               ONT
               EWR
               2016-01-20
               2016-01-28
               1
               0
               0
               EUR
               true
               true
               true
               false
               false
            
         
      
   

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


   
   
      
         
            Test
            TestPassword
            EN
            
               ONT
               EWR
               2016-01-20
               2016-01-28
               1
               0
               0
               EUR
               true
               true
               true
               false
               false
            
         
      
   

我不知道如何使用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.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");
                                }
                           }
                       );

在此输入图像描述



1> AndyN..:

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

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

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


如果这不在您的WSDL中,您可以action在Web服务端点类中使用spring中的注释添加它.

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


你需要以下行动:

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();

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

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有