Ключевые слова:soap, perl, rpc, (найти похожие документы)
From: Cre0NIX <slash-y3k@yandex.ru.>
Newsgroups: email
Date: Mon, 30 Aug 2008 18:21:07 +0000 (UTC)
Subject: Пример использования Perl модуля SOAP::Lite
Натолкнулся в ЖЖ (http://dil.livejournal.com/632284.html) на вопрос о
том, почему SOAP::Lite возвращает скаляр.
Попутно сказано о проблеме с тэгами "s-gensym"/"c-gensym".
Итак, необходимо создать клиент/серверное приложение использующее
протокол SOAP (смотрим документы W3C на
http://www.w3.org/2000/xp/Group/), в котором клиент вызывает
определенную функцию с параметрами, а сервер возвращает ответ в
XML-тэгах.
Для примера будем использовать CPAN библиотеку SOAP::Lite.
В настройках Apache прописываем настройки двух серверов:
WebApp: 10.0.0.1:7080
SOAP: 10.0.0.2:7082
В форме присутствуют элементы ввода ф-ции function - param1,param2:
<form name="f1" action="/cgi-bin/func.cgi" method="POST">
<input type="text" name="param1" value="">
<input type="text" name="param2" value="">
Скрипт производящий обработку func.cgi:
#!/usr/bin/perl -w
use CGI;
use SOAP::Lite;
use Data::Dumper;
my $soap = SOAP::Lite
-> uri('http://10.85.0.241:7099/function')
-> proxy('http://10.85.0.241:7099/cgi-bin/function.cgi');
my $query = new CGI;
my $param1 = $query->param('param1');
my $param2 = $query->param('param2');
my $result = $soap->Func1($param1,$param2);
my $id = $result->valueof('//Func1Response/details/id');
my $list = $result->valueof('//Func1Response/details/func/list');
my $dump = Dumper($result->result);
unless ($result->fault) {
print $query->header;
print "<p><b>id=</b>$id<br><b>list=</b>$list<br><b>dump: </b>$dump</b></p>";
}
else {
print join ', ',
$result->faultcode,
$result->faultstring;
}
Скрипт SOAP-сервера function.cgi:
#!/usr/bin/perl -w
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
-> dispatch_to('/usr/local/soaplite/modules', 'function')
-> handle;
Модуль /usr/local/soaplite/modules/function.pm
use SOAP::Lite;
package function;
sub Func1 {
my ($class, $param1, $param2) = @_;
my $id = $param1 . $param2;
return SOAP::Data->name("details" => \SOAP::Data->value( SOAP::Data->name('id' => $id)->type('string'),
SOAP::Data->name('func' => \SOAP::Data->value( SOAP::Data->name('list' => '1,2,5')->type('string'))) ));
}
1;
При вводе в браузере в param1 "123" и param2 "321" получаем:
id=123321
list=1,2,5
dump: $VAR1 = { 'func' => { 'list' => '1,2,5' }, 'id' => '123321' };
передающиеся xml удобнее смотерть в tcpdump:
tcpdump -i any -A -s0 port xxx (на сервере, xxx - порт сервера)
по tcpdump видим:
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<LoginResponse xmlns="http://10.85.0.241:7099/auth">
<details>
<id xsi:type="xsd:string">123321</id>
<func>
<list xsi:type="xsd:string">1,2,5</list>
</func>
</details>
</LoginResponse>
</soap:Body>
</soap:Envelope>
если возникли проблемы с лишними тэгами типа "s-gensym" или "c-gensym",
читаем http://www.soaplite.com/2003/08/how_do_you_turn.html и убираем
лишние бэкслэши перед "SOAP::Data" ;)