2010-02-19 2 views
8

제어 할 수없는 SOAP 서비스에 액세스하려고합니다. 작업 중 하나는 ProcessMessage입니다. 예제를 따라 SOAP 요청을 생성했지만 동작이 존재하지 않는다는 오류가 다시 발생했습니다. 나는 봉투의 몸체가 생성되는 방식으로 문제를 추적했다.루비 비누 통신에 savon을 사용할 때 "wsdl"네임 스페이스가 작업 이름에 삽입되는 이유는 무엇입니까?

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

. 이 태그는 내 Ruby 앱에서 생성되는 Java App과 샘플 Java App 간의 유일한 차이점입니다. 해당 태그 앞에 "wsdl:" 네임 스페이스를 없애고 그런 속성을 추가 할 수있는 방법이 있습니까? 그게 아니라면, 신체의 나머지 부분과 같이 끈으로 전달 된 동작을 강제로 생성하지 못하도록하는 방법이 있습니까?

여기 내 코드입니다 : 내가 handsoap을 시도

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 

하지만 HTTPS를 지원하고 혼란하지 않습니다. 나는 soap4r를 시도했지만 handsoap보다 훨씬 혼란 스럽다.

+0

: http://github.com/rubiii/savon/issues#issue/39 – rubiii

+0

닉 안녕, 당신은 어디셨어요 나는이 문제를보고 있습니다. –

+0

안녕하세요 스티브. 프로젝트의이 부분을 대기 상태에 두었습니다. 구현이 필요한 다른 중요한 기능이 있었기 때문에 "좋은 목록"목록에있었습니다. 나는 오늘 나중에 당신의 해결책을 시험해 볼 것이고 작동하는지 볼 것입니다. 너를 알게 해줘서 고마워! – konung

답변

4

스티브, ProcessMessage 태그 앞에 wsdl :이 보입니까? - 그게 아니라 나를 꺼내는 유일한 방법이라고 생각합니다. (160 번 라인의 Savon lib에있는 soap.rb에 하드 세트 된 방식으로). 비록 내가 soap.namespaces에서 그것을 구체화하지 않는다고하더라도 - 그것은 생성되고 최종 XML에 첨부됩니다. 내 서비스에서 허용되지 않는 서비스입니다.

생성 된 xml은 유효한 xml이지만 - 말하고자하는 서비스의 요구 사항에 의해 완전하지는 않습니다. 즉 :

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

태그가없는, 생성 된 XML에서, 또한, 내가 헤더에 PayloadManifest 필요 플러스 나는 WSU 필요 만든 WSU : 내 WSSE 만료 : 태그, 그러나 그들은 등, 구현되지 않습니다 , 등등. 나의 케이스에 너무 특정한 다른 작은 단점들의 무리. 그러나 비누에는 개인적인 방법 = xml_body가있다. 또한 to_xml 메서드의 soap lib는 자신의 xml을 생성하기 전에 @xml_body가 이미 설정되었는지 여부를 확인합니다. 그래서 나는 비누의 slighly 수정 행동을 끝내었다. soap.xml_body = 공개적으로 액세스 가능하도록 설정하십시오. 그래서 나는 할 수 있었다 :

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 

어느 쪽이 결국 작용한다! !!!

이 옵션을 사용하면 많은 드문 경우를 해결할 수 있습니다. 사람들이 사용자 정의 XML을 생성하고 나머지 savon lib를 사용할 수 있습니다.

+0

그것은 내가 생각하기에 좋은 해결책이 될 것입니다. IIS/.net에서 네임 스페이스가 없다는 것에 대해 불평하지만 파일 상단에 지시어가 있는지 여부는 신경 쓰이지 않았습니다. 행운을 빈다, 그 점에 도착하는 것은 꽤 아팠다. –

10

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> 

같은 요소 앞에 네임 스페이스 선언으로 종료됩니다 그러나 이것은 나에게 문제가 아니었다, 그것은 문제였다 네임 스페이스 속성의 부족이 아니라이었다 요소 앞에 네임 스페이스가 있음.

+0

스티브. 귀하의 메시지를 보내 주셔서 감사합니다. 그것은 제 해결책이 아니지만보다 조심스럽게 통나무를 생각하고 바라 보았습니다. 내 대답을 보라. 댓글에 충분한 공간이 없습니다. :-) – konung

+0

정확하게 똑같은 문제가 있었을 때 당신의 솔루션이 매력을 발휘했습니다. –

+0

당신의 솔루션이 저에게 효과적이었습니다. 액션 안에 xmlns가 없습니다. 본문 내부에 wsdl : namespace가 여전히 있지만 SOAP 요청에는 영향을 미치지 않습니다. – pedrofalcaocosta

7

웹 서비스의 경우 Steve의 솔루션 위에 "wsdl" 네임 스페이스를 제거해야했습니다.

는 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 잡았다 # 2 .. – abhijit

+0

화려한 대답. –

+0

Gotcha 2가 나를 죽이고있었습니다, Kenji에게 감사합니다! – zrl3dx