Pull to refresh

Как подружить java-ws и php4 не используя никаких дополнений и немножко попучить свой мозг.

Reading time4 min
Views655
Читал про Работу с веб-сервисами на php посредством SOAP.
Хочу рассказать очень занятную историю. Как-то раз передо мной встала задача расковырять админку поисковой системы FastSearch. Как говорится — не привыкать. Единственное, что меня смущало, так это то, что админка была написана на пхп 4.0, а я пишу на Джаве.
Ну что же, пхп так пхп. Естественно, гугль мне сразу выдал Pear:Soap. Как бы скормишь ему wsld от веб-сервиса и все начнут смеяться и плакать от счастья. Либо от того, что я не умею читать примеры, либо потому что веб-сервис был написан на Джаве и болтался на IBM WebSphere Application Server 6.0, а, IBM, как вы знаете — впереди планеты всей, очень любит делать стандартизованные вещи по-своему, в общем Pear:Soap не работал.

Ну что же, веб-сервис ты, или не веб-сервис, а работаешь по http и шлешь xml-ку.
Думаю так — вряд ли пхп4 не даст мне послать xml-ку по http.
Для того, чтобы не изобретать велосипед и не наступить на грабли я сосниффил заголовок soap-сообщения, которое отправляет Жабийный ws-client. Эта сволочь, кстати, кушает линк на wsdl (описание веб-сервиса) и предлагает доступные методы сервиса, указывая их тип.
Получилось вот что:

/* sniffed HEADER of SOAP message use it as template
POST /AuditServiceEAR/services/AuditService HTTP/1.1

Host: superhost.ru:9081
Content-Type: text/xml; charset=utf-8
Content-Length: 589
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: IBM Web Services Explorer

Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Connection: close
*/

Это уже что-то.
Теперь пора немножко поговнякать код.
Чтобы коллегам-Джавистам было проще, пишу просто и без вкуса:

/*CONSTANTS*/
$URL_TO_WEB_SERVICE =«superhost.ru/AuditServiceEAR/services/AuditService»; //path to web-service
$PORT_NUMBER = 9081;
* This source code was highlighted with Source Code Highlighter.


Теперь смастерю функцию, которая будет слать матерное soap-сообщение веб-сервису. Хвала яйцам, получать ответ от этого чудища мне не нужно.

/**
  function opens socket, prepares and sends SOAP message. It doesn't read response.
  $data is a SOAP message <Envelope>
*/
function do_post_request($data) {
   global $PORT_NUMBER, $URL_TO_WEB_SERVICE;

   
   $url=$URL_WEB_SERVICE;
   $start = strpos($url,'//')+2;
   $end = strpos($url,'/',$start);
   $host = substr($url, $start, $end-$start);
   $domain = substr($url,$end);
   
   $fp = pfsockopen($host, $PORT_NUMBER);//it is persistent version of fsockopen(). It behaves the same way. But it doesn't close connection

   if(!$fp){
       return null;
   }
    fputs ($fp,«POST $domain HTTP/1.1\n»);            
    fputs ($fp,«Host: $host\n»);               
    fputs ($fp,«Content-type: text/xml; charset=utf-8\n»);

    fputs ($fp,«Content-length: „.strlen($data).“\n»);      
    fputs ($fp,«Accept: application/soap+xml, application/dime, multipart/related, text/*\n»);
    fputs ($fp,«Cache-Control: no-cache\n»);

    fputs ($fp,«Pragma: no-cache\n»); 
    fputs ($fp,'SOAPAction: ""\n');
    fputs ($fp,«Connection: close\n\n»);
    fputs ($fp,"$data\n\n");
    fclose ($fp);
}
* This source code was highlighted with Source Code Highlighter.


шикарно, теперь надо сформировать soap-сообщение. В общем, есть такой веб-сервисный конверт (envelope), куда я запихну свои данные. Сделаю-ка я еще одну функцию. Вдруг сигнатура метода веб-сервиса поменяется? Да и в любом случае, хоть я на пхп4 и не кодю, но элементарный элемент реюзабельности я должен привнести.

function write_audit_message($source, $evt, $server, $message, $userIP, $action){
   $data = '<soapenv:Envelope xmlns:q0=«audit.service.company» xmlns:soapenv=«schemas.xmlsoap.org/soap/envelope» xmlns:xsd=«www.w3.org/2001/XMLSchema» xmlns:xsi=«www.w3.org/2001/XMLSchema-instance»>'

       .'<soapenv:Body>'
      .'<q0:addEvent>'
       .'<arg_0_0>'.$source.'</arg_0_0>'
       .'<arg_1_0>'.$evt.'</arg_1_0>'
       .'<arg_2_0>'.$server.'</arg_2_0>'
       .'<arg_3_0>'.$message.'</arg_3_0>'
       .'<arg_4_0>'.$userIP.'</arg_5_0>'
        .'<arg_5_0>'.$action.'</arg_6_0>'
       .'</q0:addEvent>'
       .'</soapenv:Body>'
       .'</soapenv:Envelope>';

    //now send prepared envelope
   do_post_request($data);
}
* This source code was highlighted with Source Code Highlighter.


В общем-то все готово. Веб-сервис находится, получает сообщение и остается доволен.

Порой, обладая самыми современными средствами, можно оказаться в жопе. Да, можно отправить soap-сообщение в три строчки, да пхп4 — позавчерашний день, ну а что теперь делать, если под рукой самые примитивные средства и соснифенный заголовок и тело soap-сообщения.

Так что не все так просто, что пишется двумя строками!

Tags:
Hubs:
+5
Comments9

Articles

Change theme settings