Почему “wsdl” пространство имен прервано на имя действия при использовании savon для рубиновой коммуникации мыла?

Я пытаюсь получить доступ к сервису SOAP, которым я не управляю. Одно из действий называют ProcessMessage. Я последовал примеру и генерировал запрос SOAP, но я получил ошибку, назад говоря, что действие не существует. Я проследил проблему до способа, которым сгенерировано тело конверта.

<env:Envelope ... ">
    <env:Header>
        <wsse:Security ... ">
            <wsse:UsernameToken ...">
                <wsse:Username>USER</wsse:Username>
                    <wsse:Nonce>658e702d5feff1777a6c741847239eb5d6d86e48</wsse:Nonce>
                    <wsu:Created>2010-02-18T02:05:25Z</wsu:Created>
                    <wsse:Password ... >password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </env:Header>
    <env:Body>
        <wsdl:ProcessMessage>
            <payload>
                ......
            </payload>
        </wsdl:ProcessMessage>
    </env:Body>
</env:Envelope>     

Это ProcessMessage тег должен быть:

    <ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">

Вот что это значит, когда это сгенерировано демонстрационным приложением Java, и это работает. Тот тег является единственной разницей между тем, что мое приложение Ruby генерирует и демонстрационное приложение Java. Есть ли любой способ избавиться от "wsdl:" пространство имен перед тем одним тегом и добавляет атрибут как этот. Запрет этого, там способ вынудить действие быть, чтобы не быть сгенерированным просто переданным как строка как остальная часть тела?

Вот мой код:

require 'rubygems'
require 'savon'
client = Savon::Client.new "https://gmservices.pp.gm.com/ProcessMessage?wsdl"

response = client.process_message! do | soap, wsse |
wsse.username = "USER"
wsse.password = "password"
soap.namespace = "http://www.starstandards.org/webservices/2005/10/transport" #makes no difference
soap.action = "ProcessMessage" #makes no difference
soap.input = "ProcessMessage" #makes no difference

#my body at this point is jsut one big xml string

soap.body = "<payload>...</payload>" 
# putting <ProccessMessage> tag here doesn't help as it just creates a duplicate tag in the body, since Savon keeps interjecting  <wsdl:ProcessMessage> tag.

  end

Я попробовал handsoap, но он не поддерживает HTTPS и сбивает с толку. Я попробовал soap4r, но но это еще более сбивает с толку, чем handsoap.

8
задан the Tin Man 15 February 2013 в 10:42
поделиться

2 ответа

Стив, ты видишь этот wsdl: перед тегом ProcessMessage? - Я думал, что это единственная вещь, которая выводит меня из строя, но это не так (кстати, это жестко задано в soap.rb в Savon lib на строке 160). То есть даже если я не прописываю его в soap.namespaces - он жестко генерируется и подключается в финальном xml. Что не разрешено моим сервисом.

Хотя сгенерированный xml является валидным xml - он не является полным по требованиям сервиса, с которым я пытаюсь общаться. Т.е.: в сгенерированном xml не хватает

<?xml version="1.0" encoding="UTF-8"?>

tag, также мне нужен PayloadManifest в заголовке, плюс мне нужны wsu:created и wsu:expires в моем wsse: tag, но они не реализованы, и т.д., и т.п. куча других мелких причуд, которые слишком специфичны для моего случая. Однако у soap есть приватный метод = xml_body. Также либа soap в методе to_xml проверяет, был ли уже установлен @xml_body, прежде чем генерировать свой собственный xml. В итоге я слегка изменил поведение мыла, сделав soap.xml_body = publicly accessable. Таким образом, я смог сделать:

response = client.process_message! do |soap| 
soap.action = "http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage"
soap.xml_body = "MY XML STRING GENERATED ELSEWHERE GOES HERE"
end

Что наконец-то работает!!!!

Я предложу это rubii - если эта опция станет доступной, это решит много редких случаев - когда люди могут генерировать свои собственные xml и использовать остальную часть savon lib.

4
ответ дан 5 December 2019 в 07:58
поделиться

Вам нужно передать массив в soap.input, второй элемент которого является хешем, содержащим детали пространства имен.

soap.input = [ 
  "ProcessMessage", 
  {"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]

Это должно гарантировать, что вы закончите с объявлением пространства имен в качестве атрибута для основного элемента.

Вы, вероятно, также получите объявление пространства имен перед элементом вроде этого

<env:Body>
    <wsdl:ProcessMessage xmlns="........." >
        <payload>
            ......
        </payload>
    </wsdl:ProcessMessage>
</env:Body>

, но это не было проблемой для меня, проблема заключалась в отсутствии атрибута пространства имен, а не в наличии пространства имен раньше элемент.

10
ответ дан 5 December 2019 в 07:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: