SOAP-сервер
Компонента POE::Component::Server::SOAP для реализации работы с SOAP использует достаточно популярный модуль SOAP::Lite.
В момент вызова метода new(), POE::Component::Server::SOAP создает новую сессию POE. Сразу после создания сессии запускается сервер, на основе компоненты POE::Component::Server::SimpleHTTP.
Пример кода SOAP-сервера:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#!/usr/bin/perl use POE; use POE::Component::Server::SOAP; POE::Component::Server::SOAP->new( 'ALIAS' => 'MySOAP', 'ADDRESS' => 'localhost', 'PORT' => 32080, 'HOSTNAME' => 'Localhost.com', ); POE::Session->create( 'inline_states' => { '_start' => \&setup_service, '_stop' => \&shutdown_service, 'SOAP_Handler' => \&soap_handler, }, ); $poe_kernel->run; exit 0; sub setup_service { my $kernel = $_[KERNEL]; $kernel->alias_set( 'MyServer' ); $kernel->post( 'MySOAP', 'ADDMETHOD', 'MyServer', 'SOAP_Handler'); } sub shutdown_service { $_[KERNEL]->post( 'MySOAP', 'DELMETHOD', 'MyServer', 'SOAP_Handler' ); } sub soap_handler { my $response = $_[ARG0]; my $params = $response->soapbody; # выводит поступивший запрос, удобно для логирования # print $response->soaprequest->as_string; # просто считывает все поступившие данные и собирает их # в одну строку my $result; foreach (values %$params) { $result= $result." | ".$_; } $response->content( "Your request was processed: $result" ); $_[KERNEL]->post( 'MySOAP', 'DONE', $response ); } |
После запуска этого сервера можно быстро проверить его работоспособность, набрав в строке браузера http://localhost:32080/ . В ответ на запрос, сервер выдаст ответ:
|
1 2 3 4 5 6 7 8 9 |
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <soap:Body> <soap:Fault> <faultcode>soap:Client</faultcode> <faultstring>Bad Request</faultstring> <detail xsi:type="xsd:string">Content-Type must be text/xml</detail> </soap:Fault> </soap:Body> </soap:Envelope> |
SOAP-клиент, вариант 1
Пример кода SOAP-клиента для вышеприведенного SOAP-сервера:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/usr/bin/perl use strict; use SOAP::Lite; my $soap = SOAP::Lite ->uri('http://localhost:32080/') ->proxy('http://localhost:32080/?session=MyServer') ->outputxml('true'); my $res_xml = $soap->call('SOAP_Handler', 'Value1', 'Value2'); print $res_xml; |
SOAP-клиент формирует вот такой запрос и отправляет его серверу:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
POST http://Localhost.com:32080/?session=MyServer HTTP/1.1 Connection: TE, close Accept: text/xml Accept: multipart/* Accept: application/soap Host: localhost:32080 TE: deflate,gzip;q=0.3 User-Agent: SOAP::Lite/Perl/0.715 Content-Length: 530 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://localhost:32080/#SOAP_Handler" <?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> <SOAP_Handler xmlns="http://localhost:32080/"> <c-gensym3 xsi:type="xsd:string">Value1</c-gensym3> <c-gensym5 xsi:type="xsd:string">Value2</c-gensym5> </SOAP_Handler> </soap:Body> </soap:Envelope> |
В ответ получает вот такой XML-документ:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
% perl soapclient.pl <?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> <namesp1:SOAP_HandlerResponse xmlns:namesp1="http://localhost:32080/"> <s-gensym3 xsi:type="xsd:string"> Your request was processed: | Value2 | Value1 </s-gensym3> </namesp1:SOAP_HandlerResponse> </soap:Body> </soap:Envelope> |
Данный SOAP-клиент использует в качестве параметра outputxml(‘true’), который приводит к тому, что SOAP::Lite возвращает ответ от сервера как чистый xml-код. Если данная опция не задана, будет возвращен SOM-объект (см. модуль SOAP::SOM).
Пример простого SOAP-клиента с использованием SOM см. далее.
SOAP-клиент, вариант 2
Данный клиент использует в своей работе объект SOAP::SOM.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/usr/bin/perl use Data::Dumper; use SOAP::Lite; my $som = SOAP::Lite ->uri('http://localhost:32080/') ->proxy('http://localhost:32080/?session=MyServer') ->SOAP_Handler('Value1', 'Value2'); if ($som->fault) { print $som->faultstring." ".$som->faultdetail." ".$som->faultactor."\n"; }; print $som->result."\n"; |
Клиент формирует к серверу точно такой же запрос, как в предыдущем примере, и выводит на консоль ответ:
|
1 2 3 |
% perl soapclient2.pl Your request was processed: | Value2 | Value1 |
Полезные ссылки
www.w3.org: SOAP Версия 1.2 Часть 0: Учебник для начинающих