2010-02-19 22 views
8

Tôi đang cố truy cập dịch vụ SOAP mà tôi không kiểm soát. Một trong những hành động được gọi là ProcessMessage. Tôi đã làm theo ví dụ và tạo ra một yêu cầu SOAP, nhưng tôi đã nhận được một lỗi nói rằng hành động đó không tồn tại. Tôi đã theo dõi vấn đề theo cách cơ thể của phong bì được tạo ra.Tại sao không gian tên "wsdl" xen vào tên hành động khi sử dụng savon cho truyền thông xà phòng ruby?

<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 thẻ nên là:

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

Đó là những gì nó là khi nó được tạo ra bởi các ứng dụng Java mẫu, và nó hoạt động. Thẻ đó là sự khác biệt duy nhất giữa ứng dụng Ruby của tôi tạo ra và ứng dụng Java mẫu. Có cách nào để loại bỏ không gian tên "wsdl:" trước một thẻ đó và thêm thuộc tính như vậy không. Nói cách đó, liệu có cách nào để ép buộc hành động không được tạo ra bằng cách chỉ chuyển qua như một chuỗi giống như phần còn lại của cơ thể?

Đây là mã của tôi:

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 

tôi đã cố gắng handsoap nhưng nó không hỗ trợ HTTPS và là khó hiểu. Tôi đã thử soap4r nhưng nó thậm chí còn khó hiểu hơn so với handsoap.

+0

một vé cho điều này là mở tại địa chỉ: http://github.com/rubiii/savon/issues#issue/39 – rubiii

+0

Hi Nick, bạn đã nhận được ở bất cứ đâu với điều này như tôi thấy cùng một vấn đề. –

+0

Xin chào Steve. Tôi đưa phần này của dự án vào trạng thái chờ đợi - vì có các tính năng khác, quan trọng hơn, cần thực hiện và đây là danh sách "tốt để có". Tôi sẽ thử giải pháp của bạn sau ngày hôm nay và xem có hoạt động không. Cảm ơn bạn đã cho tôi biết bạn! – konung

Trả lời

4

Steve, bạn thấy rằng wsdl: ở phía trước thẻ ProcessMessage? - Tôi nghĩ rằng đó là điều duy nhất đã ném tôi đi nhưng không phải của nó (bằng cách nó được thiết lập cứng trong soap.rb trong Savon lib trên dòng 160). Điều đó thậm chí nếu tôi không spacify nó trong soap.namespaces - nó khó tạo ra và gắn liền trong xml cuối cùng. Không được dịch vụ của tôi cho phép.

Trong khi xml được tạo là xml hợp lệ - nó không hoàn thành theo các yêu cầu của dịch vụ mà tôi đang cố gắng nói chuyện. Ví dụ: trong xml tạo,

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

thẻ là mất tích, cũng, tôi cần PayloadManifest trong tiêu đề, cộng với tôi cần WSU: tạo ra và WSU: hết hạn vào wsse tôi: thẻ, nhưng họ không thực hiện, vv , v.v. một loạt các quirks nhỏ khác quá cụ thể đối với trường hợp của tôi. Tuy nhiên xà phòng có một phương thức riêng = xml_body. Ngoài ra xà phòng lib trong phương pháp to_xml đang kiểm tra xem @xml_body đã được đặt chưa, trước khi tạo xml riêng của nó. Vì vậy, tôi đã kết thúc sửa đổi hành vi của xà phòng. bằng cách làm soap.xml_body = truy cập công khai. Vì vậy, tôi đã có thể làm:

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 

Mà cuối cùng hoạt động !!!!

Tôi sẽ đề xuất điều này với rubii - nếu tùy chọn này khả dụng sẽ giải quyết rất nhiều trường hợp hiếm hoi - nơi mọi người có thể tạo xml tùy chỉnh của họ và sử dụng phần còn lại của lib savon.

+0

Đó sẽ là một giải pháp tốt mà tôi nghĩ. Tôi thấy rằng IIS/.net đã phàn nàn về việc thiếu một không gian tên nhưng không quan tâm liệu có một chỉ thị ở đầu tệp hay không. Chúc may mắn, nó đã được khá đau đớn nhận được đến thời điểm đó. –

10

Bạn cần chuyển một mảng tới soap.input phần tử thứ hai trong số đó là một băm chứa các chi tiết về không gian tên.

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

Điều này sẽ đảm bảo bạn kết thúc khai báo không gian tên làm thuộc tính cho phần tử chính.

Có lẽ bạn cũng kết thúc với một bản tuyên bố namespace trước phần tử như vậy

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

nhưng điều này không phải là một vấn đề đối với tôi, đó là sự thiếu thuộc tính namespace đó là vấn đề, không phải là sự hiện diện của vùng tên trước phần tử.

+0

Steve. Cảm ơn vì thông điệp của bạn - đó không phải là giải pháp của tôi nhưng nó khiến tôi phải suy nghĩ và nhìn vào nhật ký một cách cẩn thận hơn. Xem câu trả lời của riêng tôi. Không có đủ không gian ở đây trong các bình luận. :-) – konung

+0

Cảm ơn giải pháp của bạn đã làm việc một sự quyến rũ ngay bây giờ khi tôi đã có cùng một vấn đề chính xác. –

+0

Giải pháp của bạn làm việc cho tôi. Tôi đã thiếu các xmlns bên trong hành động! Tôi vẫn nhận được wsdl: namespace bên trong cơ thể, nhưng nó không ảnh hưởng đến yêu cầu SOAP. – pedrofalcaocosta

7

Đối với dịch vụ web của tôi, tôi cần loại bỏ không gian tên "wsdl" phía trên giải pháp của Steve.

Thử nghiệm với Savon 0.9.6:

client = Savon::Client.new "https://example.com/webservice/account.asmx?WSDL" 
response = client.request "GetAccount" do 
    # Gotcha 1: set default namespace for body elements 
    soap.input = ["GetAccount", {"xmlns" => "https://example.com/webservice/"}] 
    soap.body = { 
    "AccountID" => 1234 
    } 
    # Gotcha 2: get rid of namespace declaration of body elements 
    soap.element_form_default = :unqualified 
    # Gotcha 3: set SOAPAction different from default 
    http.headers["SOAPAction"] = '"https://example.com/webservice/GetAccount"' 
end 
+2

+1 cho gotcha # 2 .. – abhijit

+0

câu trả lời xuất sắc. –

+0

Gotcha 2 đã giết chết tôi, cảm ơn Kenji! – zrl3dx

Các vấn đề liên quan