关于SOAPpy传递对象参数调用WebService的问题总结

第一次使用 SOAPpy传递对象,谁知遇到了好多麻烦的问题,于是网上搜啊搜,找到了 CPyUG qgg的一篇“使用 SOAPpy的体会 ,借鉴了一些经验,得到一些启发,感谢 qgg

SOAPpy调用 .net写的 WebService为例。

UserInfo.py

public   class  UserInfo
{
    
protected   string  _userName;
    
protected   string  _password;
    
protected  DateTime _birthday;
    
protected   int  _salary;

    
public   string  UserName
    {
        
get  {  return   this ._userName; }
        
set  {  this ._userName  =  value; }
    }
    
public   string  Password
    {
        
get  {  return   this ._password; }
        
set  {  this ._password  =  value; }
    }
    
public  DateTime Birthday
    {
        
get  {  return   this ._birthday; }
        
set  {  this ._birthday  =  value; }
    }
    
public   int  Salary
    {
        
get  {  return   this ._salary; }
        
set  {  this ._salary  =  value; }
    }
}

 

UserService.cs

[WebService(Namespace  =   " http://testwebservice.localhost/ " )]
public   class  UserService : System.Web.Services.WebService {

    [WebMethod]
    
public   string  Register(UserInfo user)
    {
        
string  result  =   string .Format( " Result : (UserName: {0}, Password: {1}, Birthday: {2}, Salary: {3}) " ,
            user.UserName, user.Password, user.Birthday.ToString(
" yyyy-MM-dd HH:mm:ss " ), user.Salary.ToString());
        
return  result;
    }

 

描述格式如下:

POST /t_web/UserService.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://testwebservice.localhost/Register"

<? xml version="1.0" encoding="utf-8" ?>
< soap:Envelope  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd ="http://www.w3.org/2001/XMLSchema"  xmlns:soap ="http://schemas.xmlsoap.org/soap/envelope/" >
  
< soap:Body >
    
< Register  xmlns ="http://testwebservice.localhost/" >
      
< user >
        
< UserName > string </ UserName >
        
< Password > string </ Password >
        
< Birthday > dateTime </ Birthday >
        
< Salary > int </ Salary >
      
</ user >
    
</ Register >
  
</ soap:Body >
</ soap:Envelope >

 

在构建对象时,刚开始我简单的这么想的:

class  UserInfo(object):
    pass
...
=  UserInfo()
u.UserName 
=   " jaypei "
u.Password 
=   " ************* "
u.Birthday 
=  SOAPpy.dateTimeType(( 2008 , 1 , 1 ,0,0,0))
u.Salary 
=   10

发送结果:

<? xml version="1.0" encoding="UTF-8" ?>
< SOAP-ENV:Envelope
  
SOAP-ENV:encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC
="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi
="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:SOAP-ENV
="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd
="http://www.w3.org/1999/XMLSchema" >
< SOAP-ENV:Body >
< ns1:Register  xmlns:ns1 ="http://testwebservice.localhost/"  SOAP-ENC:root ="1" >
< user  xsi:type ="xsd:UserInfo" > &lt; __main__.UserInfo object at 0x00D8C190 &gt; </ user >
</ ns1:Register >
</ SOAP-ENV:Body >
</ SOAP-ENV:Envelope >

 

 

看来需要实现__str__函数,但是这么做在逻辑层牵扯到SOAP的传递格式了,显然不会是它本意。

 

于是看Demo里面发现了SOAPpy.types。于是,模仿demo改了一下程序:

=  SOAPpy.structType()
u._addItem(
' UserName ' ' jaypei ' )
u._addItem(
' Password ' ' ************ ' )
u._addItem(
' Birthday ' , SOAPpy.dateTimeType(( 2008 , 1 , 1 ,0,0,0)))
u._addItem(
' Salary ' 10 )

发送结果:

<? xml version="1.0" encoding="UTF-8" ?>
< SOAP-ENV:Envelope
  
SOAP-ENV:encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC
="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi
="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:SOAP-ENV
="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd3
="http://www.w3.org/2001/XMLSchema"
  xmlns:xsd
="http://www.w3.org/1999/XMLSchema" >
< SOAP-ENV:Body >
< ns1:Register  xmlns:ns1 ="http://testwebservice.localhost/"  SOAP-ENC:root ="1" >
< xsd:user >
< UserName  xsi:type ="xsd:string" > jaypei </ UserName >
< Password  xsi:type ="xsd:string" > ************ </ Password >
< Birthday  xsi:type ="xsd3:dateTime" > 2008-01-01T00:00:00Z </ Birthday >
< Salary  xsi:type ="xsd:int" > 10 </ Salary >
</ xsd:user >
</ ns1:Register >
</ SOAP-ENV:Body >
</ SOAP-ENV:Envelope >

 

还是报类型错误。于是仔细研究格式上的不同。

首先是user的命名空间不同,描述中的user是没有指定命名空间的,说明是默认命名空间,读了一下types.py的代码,发现anyType是类型的基类,刚刚用到的structType的继承关系是anyType - compoundType structType ,再往下又发现了一个bodyType,于是想到UserInfo应该继承自bodyType才对。在anyType的__init__中有一个成员 _validURIs,默认赋了 (NS.XSD, NS.XSD2, NS.XSD3, NS.ENC),但是从代码中只看到用了 _validURIs[0]

于是 UserInfo写成:

class  UserInfo(SOAPpy.bodyType):
    _validURIs 
=  ( " http://testwebservice.localhost/ " , )

 

user 的 命名空间问题解决了,又请求发现还是格式不对,困惑了好半天忽然想到可能是参数的命名空间的问题,于是又翻查代码想看看参数的命名空间如何加。不知是没有 这接口还是我没找到,我就想了一个不是很漂亮的解决方法,就是注册Item的时候直接把命名空间写上(如果有谁知道的话请留言告诉我)。。

至此,终于搞定了,SOAPpy代码虽没细看但结构也看的差不多了 :)

 

调用代码如下:

from  SOAPpy  import  WSDL
import  SOAPpy

class  UserInfo(SOAPpy.bodyType):
    _validURIs 
=  ( " http://testwebservice.localhost/ " , )

def  main():
    proxy 
=  WSDL.Proxy( ' http://localhost:xxxx/UserService.asmx?WSDL ' )
    
# proxy.soapproxy.config.dumpSOAPOut = 1
     # proxy.soapproxy.config.dumpSOAPIn = 1

    proxy.methods[
' Register ' ].namespace  =  ( " nsl " " http://testwebservice.localhost/ " )

    u 
=  UserInfo()
    u._addItem(
" nsl:UserName " " jaypei " )
    u._addItem(
" nsl:Password " " ************* " )
    u._addItem(
" nsl:Birthday " , SOAPpy.dateTimeType(( 2008 , 1 , 1 ,0,0,0)))
    u._addItem(
" nsl:Salary " 10 )

    proxy.Register(user
= u)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值