3

SUDS と Python を使用して SOAP Web サービスと通信しようとしています。Python の学習 (はい、これは初めてです) と SUDS の使用方法を考え出すのに何度も悩まされた後、問題に遭遇しました。

suds によると、私が呼び出している Web メソッドのシグネチャは次のとおりです。

(FWTCaseCreate){
ClassificationEventCode = None
Priority = None
Title = None
Description = None
Queue = None
DueDate = None
AssociatedObject = 
  (FWTObjectBriefDetails){
     ObjectID = 
        (FWTObjectID){
           ObjectType = None
           ObjectReference[] = <empty>
        }
     ObjectDescription = None
     Details = None
     Category = None
  }
Form = 
  (FWTCaseForm){
     FormField[] = <empty>
     FormName = None
     FormKey = None
  }
Internal = None
InteractionID = None
XCoord = None
YCoord = None
}

そのため、SUDS を使用して必要なクラスを作成し、それをメソッドに送信します。ただし、エラーが発生します。そのため、ログをオンにすると、送信されている XML が正しくなく、逆シリアル化エラーが発生していることがわかります。SOAP パッケージは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://www.CRM.com/wsdl/FLTypes"    xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
   <wsse:Security>
      <wsse:BinarySecurityToken>eaadf1ddff99a8</wsse:BinarySecurityToken>
   </wsse:Security>
</SOAP-ENV:Header>
<ns1:Body>
   <ns0:FWTCaseCreate>
      <ClassificationEventCode>
         <ClassificationEventCode>2000023</ClassificationEventCode>
         <Priority>1</Priority>
         <Title>testing</Title>
         <Description>testing</Description>
         <Queue/>
         <Internal>True</Internal>
         <XCoord>356570</XCoord>
         <YCoord>168708</YCoord>
      </ClassificationEventCode>
   </ns0:FWTCaseCreate>
</ns1:Body>

ご覧のとおり、他のすべての要素の周りに「ClassificationEventCode」要素がありますが、これは存在しないはずです。この xml を SOAPUI にカット アンド ペーストし、最初にこの要素を削除してから Web サービスに直接投稿すると、正常に機能します。

これが私が電話をかけるために使用しているコードです

client = Client(url)

#Add a header for the security
ssnns = ('wsse', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd')

ssn = Element('BinarySecurityToken', ns=ssnns).setText(binaryKey)

ssn1 = Element('Security',ns=ssnns)

ssn1.append(ssn)

client.set_options(soapheaders=ssn1) 

newCase = client.factory.create('ns1:FWTCaseCreate')

classEventCode = client.factory.create('ns1:FWTEventCode')
classEventCode.value = 2000023

newCase.ClassificationEventCode = classEventCode
newCase.Priority = 1
#optional
newCase.AssociatedObject = None
#optional
newCase.Form = None
#optional
newCase.Internal = None
#optional
newCase.InteractionID =  None
#optional
newCase.DueDate = None
#optional
newCase.Queue = None

newCase.Title = 'Title'

newCase.Description = 'description'

newCase.XCoord = '356570'

newCase.YCoord = '168708'

caseID = client.service.createCase(newCase)

なぜこれが起こっているのか、誰にもアイデアがありますか? SUDSは、WSDLに基づいてそこにあるはずだと考えていると思います。

ありがとう。

4

5 に答える 5

6

まったく同じ問題を抱えていました。SOAP リクエストの一連のパラメーターが、最初のパラメーターと同じ名前の要素にラップされています。例えば

....
   <ns0:Body>
      <ns1:CreationReq>
         <ReqType>
            <ReqType>1</ReqType>
            <Title>Mr</Title>
            ....
         </ReqType>
      </ns1:CreationReq>
   </ns0:Body>
....

WSDL をチェックして、問題がないことを確認しました。

どうやら問題は、client.factory.create メソッドを使用して CreationReq オブジェクトを作成したためです。印刷してクライアントを確認すると、呼び出しているメソッドがそのオブジェクトをパラメーターとして使用していないことがわかります。むしろ、名前付き引数のリストを取ります。

だから私のコードは:

req = client.factory.create('CreationReq')
req.ReqType = 1
req.Title = 'Mr'
resp = client.service.Create(req)

今は次のとおりです。

req = {}
req['ReqType'] = 1
req['Title'] = 'Mr'
resp = client.service.Create(**req)
于 2010-08-12T09:21:50.567 に答える
1

suds サービスのクライアントを作成する場合、サービス呼び出しに渡す必要があるオブジェクトを判断するために表示できる属性がいくつかあります。

例えば:

import suds
client = suds.Client(url)
for a in client.sd: #print the whole service definition
    print a

これにより、プレフィックス、メソッドを含むポート、およびタイプが表示されます。コードでは、createCase へのサービス呼び出しで何を渡す必要があるかを確認できるはずです。WSDL が「FWTCaseCreate」を必要とするメソッドを定義している場合でも、suds は createCase の定義を取得して ClassificationEventCode、Priority、Title タイプなどを必要とする場合があります。

したがって、次のことはしたくありません: (最初の引数に newCase を渡し、すべての詳細をそのタグの下に置きます)

newCase = client.factory.create('ns1:FWTCaseCreate')
caseID = client.service.createCase(newCase)

ただし、代わりに次のようにサービスを呼び出します: (サービス定義に基づく)

newCase = client.factory.create('ns1:FWTCaseCreate')
caseID = client.service.createCase(newCase.ClassificationEventCode, newCase.Priority, ...)

または多分:

newCase = client.factory.create('ns1:FWTCaseCreate')
caseID = client.service.createCase(*[getattr(newCase,a) for a in newCase.__keylist__])

サービス呼び出しに必要な引数のリストを渡します。

サービス コールの定義が誤ってそのまま解決される理由はわかりませんが、正しいオブジェクトを渡しても、必要な正しい引数リストに自動的に展開されません。おそらく、suds のソース ( http://jortel.fedorapeople.org/suds/doc/ ) を読むと、答えが明らかになるでしょう。

于 2012-07-16T20:14:53.067 に答える
0

これを構成ファイルとして使用するのですか、それとも情報を保存するために使用するのですか。それとも、これはWeb全体にデータを送信するためですか?

では、そうであれば、jsonまたはjson-rpcを使用しないのはなぜですか。これらは、はるかに高速で、解析が簡単で、はるかに読みやすいと言われています。XMLは恐ろしいデータ型であり、私は個人的にそれが死ぬまで待つことができません。データ送信を探しているなら、jsonを使用する価値が十分にあります。

于 2010-05-10T13:39:50.930 に答える
0

要素を2回作成します。これを削除します:

classEventCode = client.factory.create('ns1:FWTEventCode') 
classEventCode.value = 2000023 

そしてこれを変更します:

newcase.ClassificationEventCode = 2000023

これにより、余分なタグが削除されます。

于 2010-05-12T15:32:24.587 に答える
0

同じ問題の解決策を探しているこのスレッドを見つけました。これまでのところ、ファクトリで作成されたオブジェクトをサービスメソッドに直接渡す場合にのみ発生することを調査しました。また、拡張 (継承) を使用した wsdl データ型のみ。

私が考えることができるより多くの解決策があります。

  • トップレベルのタイプに factory を使用しないでください。
  • 生成後にxmlを変更するsudsプラグインを書く
  • 継承を使用しないように wsdl を書き直します (拡張タグ)
  • サービスメソッドに渡す前にオブジェクトの型を変更する

最も簡単な方法なので、最後の方法を選択しました。だからコードがあります。

def sudsToDict(data):
    return dict([(str(key),val) for key,val in data])

このように使用します。

data = client.factory.create('wsdl_data_type')
# now fill with values and then
data = sudsToDict(data)
client.service.some_method(**data)
于 2014-10-02T08:57:04.763 に答える