Ruby,PHP, Python から JAX-WS な Web サービスへの通信方法

Java で Web サービスを作るには NetBeans を使えば簡単にできる。
http://share.java.net/kb/docs/websvc/jax-ws_ja.html
チュートリアルには Java のクライアントからデータを取得する方法しか書いておらず、Perl で Web サービスにアクセスし結果を取得したかった。
その過程で色々ハマった& Python, Ruby, PHP でアクセスを試したので以下メモ書き。
まずは、Ruby, PHP, Python から。

Java

アプリケーションサーバに NetBeans6.9 に付属している Tomcat6 を使用。
こんな感じの Web サービスを作った。
ただ単に引数を計算する add() と、リストを加算する addList() というので、int 型を応答する。

@WebService()
public class CalculatorWS {
    @WebMethod(operationName = "add")
    public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
        return i + j;
    }

    @WebMethod(operationName = "addList")
    public int addList(@WebParam(name = "params")List<Integer> params) {
        Integer ret = 0;
        for (Integer data : params) {
            ret += data;
        }
        return ret.intValue();
    }
}

Ruby

Ruby はデフォルト(追加パッケージなし)で Web サービスへのアクセスを提供している。

#!/usr/bin/env ruby
require 'soap/wsdlDriver'
wsdl = 'http://localhost:8084/CalculatorWSApplication/CalculatorWS?wsdl'
driver = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
drivet = generate_explicit_type = true
driver.wiredump_dev = STDOUT if $DEBUG

response = driver.add({ 'i' => 1, 'j' => 2})
p response.return
response = driver.addList({'params' => [100, 200]})
p response.return
ignored attr: {}version
ignored attr: {http://www.w3.org/2007/05/addressing/metadata}Action
"3"
"300"

なんかワーニングが出てるっぽいけど、とりあえず取得できた。

PHP

PHPコンパイル時に soap オプションをつけていれば、拡張モジュールが使用できる。
# Zend_Soap_Client はエラーが出たので追いかけていない

<?php
ini_set('soap.wsdl_cache_enabled', '0');
$uri    = 'http://localhost:8084/CalculatorWSApplication/CalculatorWS?wsdl';
$client = new SoapClient($uri, array('trace' => 1));

$result = $client->add(array('i' => 1, 'j' => 10));
var_dump($result->return);

$result = $client->addList(array('params' => array(100, 200)));
var_dump($result->return);
int(11)
int(300)

特にエラーやワーニングが出ずに取得できた。
ただ、wsdl をキャッシュするようで、ini_set('soap.wsdl_cache_enabled', '0'); をしておかないと Web サービス側でメソッド名を変えた場合、クライアントでは取得できなかった。
開発環境とかは php.ini でキャッシュしないようにしておいた方が良さそう。

Python

Python は suds というライブラリを使った。
Infrastructure/Fedorahosted-retirement - Fedora Project Wiki
pip で入れた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from suds.client import Client

wsdl = 'http://localhost:8084/CalculatorWSApplication/CalculatorWS?wsdl'
client = Client(wsdl)
ret = client.service.add(1, 200);
print(ret)

ret = client.service.addList([100, 200])
print(ret)
3
300

こちらも wsdl をキャッシュするので手こずった。
キャッシュを抑制するオプションがあるみたいだが、設定したがうまくいかなかった。
キャッシュファイルは、ドキュメントでは /tmp/suds にあるとあったが、Mac OS X でみたところなかった。
ソースを追いかけた所、以下のような記述があった。
suds/cache.py

from tempfile import gettempdir as tmp
def __init__(self, location=None, **duration):
    if location is None:
        location = os.path.join(tmp(), 'suds')

pythonインタプリタで、tmp() を実行すると、

>>> from tempfile import gettempdir as tmp
>>> tmp()
'/var/folders/j3/j3UgRe1TFtSPUzl8GvBCBE+++TI/-Tmp-'

と出た。この tmp() の出力先に suds ディレクトリがあるのでキャッシュを消したい場合はそれを消す。

まとめ

それぞれ割と簡単にアクセスできる。
引数の渡し方とかそれぞれ違いがあるのと、キャッシュがハマった所。