Ответ 1
Если это сервис SOAP 1.1, вам также потребуется включить поле заголовка HTTP SOAPAction:
Я пытаюсь реализовать клиента для SOAP-службы National Rail Inquiries (http://www.livedepartureboards.co.uk/ldbws/).
Я вставляю WSDL (http://realtime.nationalrail.co.uk/ldbws/wsdl.aspx) в http://soapclient.com/soaptest.html, но я возвращаю сообщение об ошибке "Невозможно обработать запрос без действительного параметра действия. Пожалуйста, поставьте действительное действие мыла".; что на самом деле должно быть действие?
Спасибо, Стюарт
изменить:
Я просто использовал soapclient.com в качестве быстрого примера. В моем программном обеспечении я отправляю следующий XML; Я все еще понимаю, что мне не хватает действия.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://thalesgroup.com/RTTI/2008-02-20/ldb/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/types" xmlns:ldbt="http://thalesgroup.com/RTTI/2007-10-10/ldb/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ct="http://thalesgroup.com/RTTI/2007-10-10/ldb/commontypes" >
<SOAP-ENV:Body>
<ldbt2:GetDepartureBoardRequest xmlns:ldbt2="http://thalesgroup.com/RTTI/2008-02-20/ldb/" >
<ldbt2:numRows>5</ldbt2:numRows>
<ldbt2:crs>WAT</ldbt2:crs>
<ldbt2:filterCrs>GLD</ldbt2:filterCrs>
<ldbt2:filterType>to</ldbt2:filterType>
<ldbt2:timeOffset>0</ldbt2:timeOffset>
</ldbt2:GetDepartureBoardRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Если это сервис SOAP 1.1, вам также потребуется включить поле заголовка HTTP SOAPAction:
Я столкнулся с той же проблемой при попытке написать клиент для службы National Rail SOAP с Perl.
Проблема была вызвана тем, что модуль Perl, который я использую "SOAP:: Lite", вставляет заголовок "#" в заголовок SOAPAction...
SOAPAction: "http://thalesgroup.com/RTTI/2008-02-20/ldb/#GetDepartureBoard"
Это неправильно интерпретируется серверами .NET. Я нашел это из примера 3-19 в O'Reilly Программирование веб-сервисов с SOAP. Решение было дано ниже в разделе 3-20, а именно вам нужно явно указать формат заголовка с помощью метода on_action.
print SOAP::Lite
-> uri('urn:Example1')
-> on_action(sub{sprintf '%s/%s', @_ })
-> proxy('http://localhost:8080/helloworld/example1.asmx')
-> sayHello($name)
-> result . "\n\n";
Я предполагаю, что soapclient.com использует SOAP:: Lite за кулисами и так же сталкивается с той же проблемой, когда разговаривает с National Rail.
Решение состоит в том, чтобы написать собственный клиент, чтобы вы контролировали формат заголовка SOAPAction... но вы, вероятно, уже сделали это.
Ричард
SOAPAction требуется в SOAP 1.1, но может быть пустым ("").
См. https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
"Значение поля заголовка пустой строки (" ") означает, что намерение SOAP-сообщения предоставляется HTTP-Request-URI."
Попробуйте установить SOAPAction = ""
Я просто потратил некоторое время, пытаясь заставить это работать, написав Ruby gem, который обращается к API. Вы можете прочитать больше на нем страница проекта.
Это рабочий код в Ruby:
require 'savon'
client = Savon::Client.new do
wsdl.document = "http://realtime.nationalrail.co.uk/LDBWS/wsdl.aspx"
end
response = client.request 'http://thalesgroup.com/RTTI/2012-01-13/ldb/GetDepartureBoard' do
namespaces = {
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}
soap.xml do |xml|
xml.soap(:Envelope, namespaces) do |xml|
xml.soap(:Header) do |xml|
xml.AccessToken do |xml|
xml.TokenValue('ENTER YOUR TOKEN HERE')
end
end
xml.soap(:Body) do |xml|
xml.GetDepartureBoardRequest(xmlns: "http://thalesgroup.com/RTTI/2012-01-13/ldb/types") do |xml|
xml.numRows(10)
xml.crs("BHM")
xml.filterCrs("BHM")
xml.filterType("to")
end
end
end
end
end
p response.body
Надеюсь, что это поможет кому-то!
Мы собрали веб-службы на Windows Server и пытались подключиться к PHP на Apache. Мы получили ту же ошибку. В результате проблемы были разными версиями клиента Soap на разных серверах. Соответствие версий SOAP в вариантах на обоих серверах решило проблему в нашем случае.
служба имеет 4 операции: 1. GetServiceDetails 2. GetArrivalBoard 3. GetDepartureBoard 4. GetArrivalDepartureBoard
Когда <<20 > отсутствует в запросе SOAP 1.2 (и многие клиенты не устанавливают его, даже если он указан в WSDL), некоторые серверы приложений (например, jboss) выводят "фактический" soapAction
из {xsd:import namespace}+{wsdl:operation name}
.
Таким образом, чтобы предполагаемый "фактический" soapAction
соответствовал ожидаемому soapAction
, вы можете установить ожидаемое soapAction на {xsd:import namespace}+{wsdl:operation name}
в вашем определении WS (@WebMethod(action=...
) для Java EE)
Eg. для типичного случая Java EE это помогает (а не корпус Стюарта, National Rail WS имеет набор "soapAction" ):
@WebMethod(action = "http://packagename.of.your.webservice.class.com/methodName")
Если вы не можете изменить сервер, вам нужно заставить клиента заполнить soapAction
.
Я решил эту проблему в Java Code, добавив:
MimeHeaders headers = message.getMimeHeaders();
headers.addHeader("SOAPAction", endpointURL);