惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
罗磊的独立博客
F
Fortinet All Blogs
T
Threatpost
Y
Y Combinator Blog
博客园_首页
美团技术团队
Security Latest
Security Latest
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
V
V2EX - 技术
The Cloudflare Blog
L
LINUX DO - 热门话题
博客园 - 司徒正美
Jina AI
Jina AI
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Hacker News
The Hacker News
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
M
MIT News - Artificial intelligence
Latest news
Latest news
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
雷峰网
雷峰网
Application and Cybersecurity Blog
Application and Cybersecurity Blog
B
Blog RSS Feed
W
WeLiveSecurity
D
DataBreaches.Net
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
Spread Privacy
Spread Privacy
Know Your Adversary
Know Your Adversary
TaoSecurity Blog
TaoSecurity Blog
S
Securelist
Help Net Security
Help Net Security

博客园 - Jaypei

archlinux中启用sshd [转] AT89C52资料 VirtualBox中安装PuppyLinux4 [转]比较全的Vim 中的正则表达式 luacurl的一个获得html的函数 [转]使用Mac OS X系统必须了解的10条命令 [原]Qt4.5中Plugins使用方法 用nuSOAP传递对象数组的问题终于解决 粗心导致的gsoap一个错误 MinGW环境使用gSOAP rdesktop中剪切板共享 [转]在Windows XP下用GCC 4.3.2编译Qt 4.4.3实战 Ubuntu下安装Postgresql 8.3 [原创]关于python的Singleton [转]如何讀取文字檔? (C/C++) (STL) 简单的python读写windows剪切板 LinkedServer的用法 解决Smarty中trancate使用UTF8时中文乱码问题 关于wxPython中多线程修改主界面 - Jaypei
关于SOAPpy传递对象参数调用WebService的问题总结
Jaypei · 2008-12-01 · via 博客园 - Jaypei

第一次使用SOAPpy传递对象,谁知遇到了好多麻烦的问题,于是网上搜啊搜,找到了CPyUGqgg的一篇“使用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 SOAPpyclass 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)