[原创] perl WebServices客户端

[原创] perl WebServices客户端

这是一个简单的perl WebServices客户端示例,阅读下面内容最好了解下列技术:

WebServices框架协议
HTTP SOAP协议
XML言语
RPC远程过程调用

该示例调用XMethods的 temperature service(http://www.xmethods.com/ve2/ViewListing.po;jsessionid=wwY9oY_kCAvsXXW3l9-V4Jes(QHyMHiRM)?key=uuid:477CEED8-1EDD-89FA-1070-6C2DBE1685F8)。temperature服务根据请求的美国某地区的邮码返回该地区当前的温度。

下面先看看完整的perl代码,然后我会对关键代码分步做出说明。
temperatureclient.pl

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl -w
# 一个简单的web service client.调用XMethods temperature service.
# http://www.xmethods.com

use strict;
use SOAP::EnvelopeMaker;
use SOAP::Parser;
use SOAP::Struct;
use SOAP::Transport::HTTP::Client;

my $zipcode = shift; $zipcode =~ /^\d+$/ or die "USAGE: $0 U.Szipcode\n";
my ($server, $port,$endpoint, $soapaction, $method, $method_urn,$message, $envelope, $response, $parser);

# service address
$server = 'services.xmethods.net';
$port = 80;
$endpoint = '/soap/servlet/rpcrouter';

$soapaction ='';
$method = 'getTemp';
# operator namespace
$method_urn = 'urn:xmethods-Temperature';

# create SOAP envelope
$envelope = SOAP::EnvelopeMaker->;new(\$message);

# set SOAP body,zipcode is the parameter name
$envelope->;set_body($method_urn, $method, 0,SOAP::Struct->;new(zipcode=>;$zipcode));
# create client call
$response = SOAP::Transport::HTTP::Client->;new()->;send_receive($server, $port,
$endpoint,$method_urn, $method,$message);

# parser SOAP response message
$parser = SOAP::Parser->;new;
$parser->;parsestring($response);
# get SOAP body
$response = $parser->;get_body;

if (exists $response->;{return}) {
     print "$zipcode Temperature: $response->;{return}\n";
} else {
     print "A fault ($response->;{faultcode}) occurred: " .$response->;{faultstring}\n";
}
exit;

如果你要在你的机子上测试以上程序,请确认是否安装了perl SOAP模块(下载地址:http://search.cpan.org/~kbrown/SOAP-0.28/).

请打开温度服务的WSDL:http://www.xmethods.net/sd/2001/TemperatureService.wsdl对照阅读。

[Copy to clipboard] [ - ]
CODE:
# service address
$server = 'services.xmethods.net';
$endpoint = '/soap/servlet/rpcrouter';

$soapaction ='';
$method = 'getTemp';
# operator namespace
$method_urn = 'urn:xmethods-Temperature';

从WSDL中获得以上信息:$server 服务地址,$port 端口号,$endpoint 服务端点,$method 调用方法,$method_urn 方法的名称空间,还有一个参数名称:zipcode。

[Copy to clipboard] [ - ]
CODE:
# create SOAP envelope
$envelope = SOAP::EnvelopeMaker->;new(\$message);
# set SOAP body,zipcode is the parameter name
$envelope->;set_body($method_urn, $method, 0,SOAP::Struct->;new(zipcode=>;$zipcode));

创建一个SOAP封套,传入一个字符串引用用来保存Envelope结构;当调用完set_body方法后,$message中将存有类似下面的SOAP消息:(为了便于阅读,我对其进行了格式化)

[Copy to clipboard] [ - ]
CODE:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:n1="urn:xmethods-Temperature"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">;
<s:Body>;
   <n1:getTemp id="ref-1" s:root="1">;
   <zipcode>;94041</zipcode>;
   </n1:getTemp>;
</s:Body>;
</s:Envelope>;

接着进行客户端调用,

[Copy to clipboard] [ - ]
CODE:
# create client call
$response = SOAP::Transport::HTTP::Client->;new()->;send_receive($server, $port,
$endpoint, $method_urn, $method,$message);

创建一个HTTP SOAP客户端,向服务器发送请求,并将服务器SOAP响应保存的$response中,如下:

[Copy to clipboard] [ - ]
CODE:
<?xml version='1.0' encoding='UTF-8'?>;
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">;
<SOAP-ENV:Body>;
<ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">;
<return xsi:type="xsd:float">;69.0</return>;
</ns1:getTempResponse>;

</SOAP-ENV:Body>;
</SOAP-ENV:Envelope>;

解析SOAP响应,取得body,返回一个哈希引用,里面包含SOAP body中XML文档结构。

[Copy to clipboard] [ - ]
CODE:
# parser SOAP response message
$parser = SOAP::Parser->;new;
$parser->;parsestring($response);
# get SOAP body
$response = $parser->;get_body;

最后打印出温度值.

[Copy to clipboard] [ - ]
CODE:
if (exists $response->;{return}) {
    print "$zipcode Temperature: $response->;{return}\n";
} else {
    print "A fault ($response->;{faultcode}) occurred: " .$response->;{faultstring}\n";
}

相关参考

SOAP 1.1规范 http://www.w3.org/TR/2000/NOTE-SOAP-20000508/
IBM developerWorks webservice专区 http://www-900.ibm.com/developerworks/cn/webservices/
<<rogramming Web Services with Perl>;>; By Pavel Kulchenko, Randy J. Ray http://safari.oreilly.com/

*更爽目的格式请阅读我的Blog http://swallor.blogdriver.com/swallor/index.html

另:我将该示例发在了XMethods上,借宝地存放一下源代码,为了perl的推广,请板主大人不要删除!谢谢!(唉,不让上传,另找地儿了:()
nice.

I believe fayland did something similar like this. oh, here
http://www.1313s.com/f/xml-rpc-client.html
我有過寫一個更簡單的...
Server端是用Java寫的..
Client端如下.....很簡單吧..只要有SOAP::Lite與wsdl
一切都沒問題....

[Copy to clipboard] [ - ]
CODE:
use SOAP::Lite;
my $dat = getdata(shift);
sub getdata(){
  my ($d)=@_;
#讀wsdl file
  my $service = SOAP::Lite
    ->;service('file:/xxx/xxx/xxx/xxx/xxxx.wsdl');
#----連上Webservice Server呼叫Server提供的method queryMethod
#----取得回傳值
  my $data= eval{
    local $SIG{ALRM}=sub {die "timeout\n"};
    alarm(5);  #---timeout---
    my $data=$service->;queryMethod(1,$d,"","xxxx");
    return $data;
  };
  alarm(0);
  $data;
}



QUOTE:
原帖由 "Qiang" 发表:
nice.

I believe fayland did something similar like this. oh, here
http://www.1313s.com/f/xml-rpc-client.html

Frontier只是一个基于XML技术的一个RPC应用库,它不同于同样基于XML技术的WebServices应用,SOAP技术有自己的规范。SOAP应用有很多种可能的实现技术,如SMTP,HTTP等等。基于HTTP的SOAP协议是将底层RPC请求与响应映射为HTTP请求与响应,SOAP请求与响应的XML或准确的叫消息Message必须按照SOAP的编码规范进行编码,而Frontier的编码是XMLRPC的编码,规范不同。
这里有SOAP规范:http://www.w3.org
这里有XMLRPC规范:http://www.xmlrpc.com/spec
我现在要用一个网络服务,它的wsdl如下:
http://www.ebi.ac.uk/Tools/webservices/wsdl/WSInterProScan.wsdl
这个服务的网络地址是
http://www.ebi.ac.uk/webservices/whatizit/info.jsf
我简单介绍一下,这个服务是文本处理,将你提交的文本中的基因、药物、疾病或者是蛋白质的信息标注出来,这个参数是由你自己选择的。我只需用到其中的一个方法contact,参数有三个,pipelineName、text和convertToHtml,其中pipelineName就是选择标注基因,还是蛋白质,还是疾病,text就是你要输入的文本信息,convertToHtml控制输出格式为Html还是XML。
我编写的程序如下:
#!/usr/bin/perl -w
use strict;
use SOAP::Lite;
my $str='Quercetin, a ubiquitous bioactive plant flavonoid, has been shown to inhibit the proliferation of cancer cells and induce the accumulation of hypoxia-inducible factor-1alpha (HIF-1alpha) in normoxia. In this study, under hypoxic conditions (1% O(2)), we examined the effect of quercetin on the intracellular level of HIF-1alpha and extracellular level of vascular endothelial growth factor (VEGF) in a variety of human cancer cell lines. Surprisingly, we observed that quercetin suppressed the HIF-1alpha accumulation during hypoxia in human prostate cancer LNCaP, colon cancer CX-1, and breast cancer SkBr3 cells. Quercetin treatment also significantly reduced hypoxia-induced secretion of VEGF. Suppression of HIF-1alpha accumulation during treatment with quercetin in hypoxia was not prevented by treatment with 26S proteasome inhibitor MG132 or PI3K inhibitor LY294002. Interestingly, hypoxia (1% O(2)) in the presence of 100 microM quercetin inhibited protein synthesis by 94% during incubation for 8 h. Significant quercetin concentration-dependent inhibition of protein synthesis and suppression of HIF-1alpha accumulation were observed under hypoxic conditions. Treatment with 100 microM cycloheximide, a protein synthesis inhibitor, replicated the effect of quercetin by inhibiting HIF-1alpha accumulation during hypoxia. These results suggest that suppression of HIF-1alpha accumulation during treatment with quercetin under hypoxic conditions is due to inhibition of protein synthesis. J. Cell. Biochem. (c) 2008 Wiley-Liss, Inc.';
my $whatizit=SOAP::Lite -> service('http://www.ebi.ac.uk/webservices/whatizit/ws?wsdl');
my %parameters=();
$parameters{'pipelineName'}='whatizitSwissprotGo2';
$parameters{'text'}=$str;
$parameters{'convertToHtml'}='false';
print $whatizit->contact(
             SOAP:ata->name('parameters')->type(map=>\%parameters)
             );
但是怎么也得不到结果,请各位高手指点迷津。