ヴァル研究所の駅すぱあとのウェブサービス版RailGo(レイルゴー).
これを使って、鉄道の経路検索/乗り換え検索とかやってみたい……

でもインターフェースがRESTじゃなくてSOAP?らしい。

XML-RPC -> 進化?発展? -> SOAP

調べてみたら、Apache Axis2 が Java のライブラリとして使えそう。

Apache Axis2

-Apache Axis2 の気になる特徴 (参考: Java WORLD 2006.4 - Jakarta活用指南 第35回)
--AXIOMというオブジェクトモデル
--非同期型Webサービスの実現
--org.apache.axis2.om.OMElement
--StAXパーサを利用

とりあえず Axis2/Java - Apache Axis2/Java - Next Generation Web Services から axis2-1.2.zip をダウンロード。

おおまかな流れ

1. Axis2 に同梱されている WSDL2Java にて RailGo のクライアント用スタブクラス(プロキシクラス)を生成する。
2. RailGo のスタブクラスを使って RailGo のウェブサービスへアクセスする。

環境変数の設定


set JAVA_HOME=C:\jdk1.5.0_12
set PATH=C:\jdk1.5.0_12\bin;%PATH%
set AXIS2_HOME=C:\wsdl\axis2-1.2
 
C:\wsdl>java -version
java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Client VM (build 1.5.0_12-b04, mixed mode, sharing)

スタブクラスの作成

スタブの種類がデータバインディングで決まる。
データバインディングの種類がいろいろ選べる(databinding: adb, xmlbeans, jibx, jaxme and jaxbri)

adb(Axis Data Binding) un-wrapping の場合:
ソースファイル(.java)2つとbuild.xmlが生成される。
ソースファイル2つの中には内部クラスがたくさんできる。


C:\wsdl\axis2-1.2\bin\wsdl2java.bat -uri http://wstest.railgo.jp/Expservice06.asmx?WSDL -p rail2go.client.adb.uw -s -uw -o rail2go_client

adb(Axis Data Binding) wrapping の場合:
ソースファイル(.java)2つとbuild.xmlが生成される。
ソースファイル2つの中には内部クラスがたくさんできる。


C:\wsdl\axis2-1.2\bin\wsdl2java.bat -uri http://wstest.railgo.jp/Expservice06.asmx?WSDL -p rail2go.client.adb.w -s -o rail2go_client

xmlbeans の場合:
いろいろxml操作系のファイルも生成される。


C:\wsdl\axis2-1.2\bin\wsdl2java.bat -uri http://wstest.railgo.jp/Expservice06.asmx?WSDL -p rail2go.client.xmlbeans -s -uw -o rail2go_client -d xmlbeans

jaxbri の場合:
まだまだ実験的なタイプ? 単独のクラスとなるソースファイル(.java)がたくさんできる。


C:\wsdl\axis2-1.2\bin\wsdl2java.bat -uri http://wstest.railgo.jp/Expservice06.asmx?WSDL -p rail2go.client.jaxbri -s -o rail2go_client -d jaxbri

これらの生成例では、rail2go_client ディレクトリ以下にスタブクラスのソースコードが生成される。

参考: Axis2/Java - Axis2 Quick Start Guide - Creating Clients

どのスタブクラスを使おうか……

結果としては、Axis2/ADB > XFire/JAXB > Axis2/JAXB であったようです。
Axis2/ADBのパフォーマンスが良かった点と、Axis2/JAXBのパフォーマンスが
XFire/JAXBに及ばなかった点がグラフを交えて報告されています。

Apache Axis2 : メモ:Axis2ベンチマーク(2007/1時点)

参考:

-Apache Axis2 : メモ:Axis2ベンチマーク(2007/1時点) その2
-Axis2/Java Performance Testing Round #2 - Apache Axis2 vs. Codehaus XFire in a Contract First Scenario | Web Services are Not Slow | WSO2 Oxygen Tank
-Oh Hani (or a tale of two benchmarks) - Paul's blog - Powered By Bloglines

無難そうなのでadb(Axis Data Binding)を使うことにする。

サンプルソースコードと実行結果

API は RailGoアプリケーションの手引き を参考にする。PDFのマニュアルがけっこう詳しい(サンプルコードはC#のしか載ってないけど)。

コンパイル時/実行時にどのJARファイルが必要なのか不明なので axis2-1.2\lib 以下の *.jar ファイルを全部クラスパスに通した。

un-wrapping版:


import rail2go.client.adb.uw.ExpService06ExpService06SoapStub;
 
public class UnwrappingSample {
 
  public static void main(String[] args) throws Exception {
    
    ExpService06ExpService06SoapStub.Authentication auth = new ExpService06ExpService06SoapStub.Authentication();
    auth.setUser("mctuser3");
    auth.setPassword("symfyws6");
    
    ExpService06ExpService06SoapStub.Authentication0 auth0 = new ExpService06ExpService06SoapStub.Authentication0();
    auth0.setAuthentication(auth);
    
    String targetEndpoint = "http://wstest.railgo.jp/Expservice06.asmx";
    ExpService06ExpService06SoapStub expsv = new ExpService06ExpService06SoapStub(targetEndpoint);
    ExpService06ExpService06SoapStub.ArrayOfStation stations =
      expsv.SearchStation(
        "なごや",
        ExpService06ExpService06SoapStub.AreaType.Japan,
        ExpService06ExpService06SoapStub.StationType.RailRoad,
        20070707,
        auth0);
    ExpService06ExpService06SoapStub.Station[] ss = stations.getStation();
    for(int i=0; i<ss.length; i++){
      System.out.println(ss[i].getName());
    }
  }
 
}

実行結果:


2007/07/06 16:00:00 org.apache.commons.httpclient.HttpMethodBase readResponse
情報: Discarding unexpected response: HTTP/1.1 100 Continue
名古屋
近鉄名古屋
名鉄名古屋
名古屋競馬場前
徳重・名古屋芸大
名古屋港
名古屋大学
ナゴヤドーム前矢田

wrapping版:


import rail2go.client.adb.w.ExpService06ExpService06SoapStub;
 
public class WrappingSample {
 
  public static void main(String[] args) throws Exception {
    
    ExpService06ExpService06SoapStub.Authentication auth = new ExpService06ExpService06SoapStub.Authentication();
    auth.setUser("mctuser3");
    auth.setPassword("symfyws6");
    
    ExpService06ExpService06SoapStub.Authentication0 auth0 = new ExpService06ExpService06SoapStub.Authentication0();
    auth0.setAuthentication(auth);
    
    ExpService06ExpService06SoapStub.SearchStation search = new ExpService06ExpService06SoapStub.SearchStation();
    search.setStationYomi("なごや");
    search.setAreaType(ExpService06ExpService06SoapStub.AreaType.Japan);
    search.setStationType(ExpService06ExpService06SoapStub.StationType.RailRoad);
    search.setDate(20070707);
    
    String targetEndpoint = "http://wstest.railgo.jp/Expservice06.asmx";
    ExpService06ExpService06SoapStub expsv = new ExpService06ExpService06SoapStub(targetEndpoint);
    ExpService06ExpService06SoapStub.SearchStationResponse resp = expsv.SearchStation(search, auth0);
    ExpService06ExpService06SoapStub.ArrayOfStation stations = resp.getSearchStationResult();
    ExpService06ExpService06SoapStub.Station[] ss = stations.getStation();
    for(int i=0; i<ss.length; i++){
      System.out.println(ss[i].getName());
    }
  }
 
}

実行結果:


2007/07/06 16:00:01 org.apache.commons.httpclient.HttpMethodBase readResponse
情報: Discarding unexpected response: HTTP/1.1 100 Continue
名古屋
近鉄名古屋
名鉄名古屋
名古屋競馬場前
徳重・名古屋芸大
名古屋港
名古屋大学
ナゴヤドーム前矢田

とりあえず動いた。RESTと違ってけっこう大変。

コンパイル時/実行時にどのJARファイルが必要なのか不明

JDepend plugin for Eclipse: JDepend4Eclipse を使ってみた。

こんな感じで依存するパッケージが出力される。


Depends Upon:
    java.lang
    java.lang.reflect
    java.math
    java.rmi
    java.util
    javax.xml.namespace
    javax.xml.stream
    org.apache.axiom.om
    org.apache.axiom.om.impl.dom
    org.apache.axiom.om.impl.llom
    org.apache.axiom.soap
    org.apache.axis2
    org.apache.axis2.addressing
    org.apache.axis2.client
    org.apache.axis2.context
    org.apache.axis2.databinding
    org.apache.axis2.databinding.utils
    org.apache.axis2.databinding.utils.reader
    org.apache.axis2.description
    org.apache.axis2.transport

が、その先の依存関係までは見れないし、どのJARファイルが必要かもわからない。使うなら、全部のJARファイルを使うことにして選別することはあきらめた。残念。

参考: @IT - Eclipseで使える静的テストツール - 第3回 Eclipseで使えるメトリクス計測ツール - 依存関係の循環を検出:JDepend4Eclipse

恐ろしい数の依存JARファイル51個

これは厳しすぎだろう……


C:\wsdl>dir C:\wsdl\axis2-1.2\lib\*.jar
 
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は CAFE-BABE です
 
 C:\wsdl\axis2-1.2\lib のディレクトリ
 
2007/04/27  16:36            62,983 activation-1.1.jar
2007/04/27  16:36           248,639 annogen-0.1.0.jar
2007/04/27  16:36           135,199 axiom-api-1.2.4.jar
2007/04/27  16:36           142,349 axiom-dom-1.2.4.jar
2007/04/27  16:36           113,690 axiom-impl-1.2.4.jar
2007/04/27  16:36           152,773 axis2-adb-1.2.jar
2007/04/27  16:36           125,872 axis2-adb-codegen-1.2.jar
2007/04/27  16:36           190,698 axis2-codegen-1.2.jar
2007/04/27  16:36             5,054 axis2-fastinfoset-1.2.jar
2007/04/27  16:36            60,187 axis2-java2wsdl-1.2.jar
2007/04/27  16:36            10,222 axis2-jaxbri-1.2.jar
2007/04/27  16:36           392,276 axis2-jaxws-1.2.jar
2007/04/27  16:36            42,285 axis2-jaxws-api-1.2.jar
2007/04/27  16:36            31,969 axis2-jibx-1.2.jar
2007/04/27  16:36            14,971 axis2-json-1.2.jar
2007/04/27  16:36           933,254 axis2-kernel-1.2.jar
2007/04/27  16:36           258,022 axis2-metadata-1.2.jar
2007/04/27  16:36            81,140 axis2-saaj-1.2.jar
2007/04/27  16:36            29,367 axis2-saaj-api-1.2.jar
2007/04/27  16:36            26,372 axis2-soapmonitor-1.2.jar
2007/04/27  16:36             9,629 axis2-spring-1.2.jar
2007/04/27  16:36             9,669 axis2-tools-1.2.jar
2007/04/27  16:36            23,431 axis2-xmlbeans-1.2.jar
2007/04/27  16:36           326,319 backport-util-concurrent-2.2.jar
2007/04/27  16:36            46,725 commons-codec-1.3.jar
2007/04/27  16:36            31,909 commons-fileupload-1.1.1.jar
2007/04/27  16:36           279,781 commons-httpclient-3.0.1.jar
2007/04/27  16:36            65,621 commons-io-1.2.jar
2007/04/27  16:36            52,915 commons-logging-1.1.jar
2007/04/27  16:36            30,838 geronimo-spec-jms-1.1-rc4.jar
2007/04/27  16:36           139,388 jakarta-httpcore-4.0-alpha4.jar
2007/04/27  16:36            73,081 jaxb-api-2.0.2.jar
2007/04/27  16:36           783,161 jaxb-impl-2.0.2.jar
2007/04/27  16:36         2,987,841 jaxb-xjc-2.0.2.jar
2007/04/27  16:36           239,001 jaxen-1.1-beta-10.jar
2007/04/27  16:36            54,169 jettison-1.0-RC1.jar
2007/04/27  16:36           351,805 jibx-bind-1.1.4.jar
2007/04/27  16:36           104,865 jibx-run-1.1.4.jar
2007/04/27  16:36           388,864 mail-1.4.jar
2007/04/27  16:36            26,078 neethi-2.0.1.jar
2007/04/27  16:36            77,977 servletapi-2.3.jar
2007/04/27  16:36            26,514 stax-api-1.0.1.jar
2007/04/27  16:36           128,475 stax-utils-20060915.jar
2007/04/27  16:36           312,753 woden-1.0-incubating-M7a.jar
2007/04/27  16:36           148,429 wsdl4j-1.6.2.jar
2007/04/27  16:36           505,825 wstx-asl-3.2.1.jar
2007/04/27  16:36         2,730,442 xalan-2.7.0.jar
2007/04/27  16:36         2,664,574 xbean-2.2.0.jar
2007/04/27  16:36         1,212,965 xercesImpl-2.8.1.jar
2007/04/27  16:36           195,119 xml-apis-1.3.03.jar
2007/04/27  16:36           133,923 XmlSchema-1.3.1.jar
              51 個のファイル          17,219,408 バイト
               0 個のディレクトリ  12,345,678,900 バイトの空き領域

これじゃ、メモリ食いすぎるよ orz

WSDL2Java のヘルプ


C:\wsdl>C:\wsdl\axis2-1.2\bin\wsdl2java.bat
Using AXIS2_HOME:   C:\wsdl\axis2-1.2
Using JAVA_HOME:    C:\jdk1.5.0_12
Usage: WSDL2Java -uri <url or path> : A url or path to a WSDL
      -o <path>                Specify a directory path for the generated code.
      -a                       Generate async style code only (Default: off).
      -s                       Generate sync style code only (Default: off). Takes precedence over -a.
      -p <pkg1>                Specify a custom package name for the generated code.
      -l <language>            Valid languages are java and csharp (Default: java).
      -t                       Generate a test case for the generated code.
      -ss                      Generate server side code (i.e. skeletons) (Default: off).
      -sd                      Generate service descriptor (i.e. services.xml). (Default: off). Valid with -ss.
      -d <databinding>         Valid databinding(s) are adb, xmlbeans, jibx, jaxme and jaxbri (Default: adb).
      -g                       Generates all the classes. Valid only with -ss.
      -pn <port_name>          Choose a specific port when there are multiple ports in the wsdl.
      -sn <service_name>       Choose a specific service when there are multiple services in the wsdl.
      -u                       Unpacks the databinding classes
      -r <path>                Specify a repository against which code is generated.
      -ns2p ns1=pkg1,ns2=pkg2  Specify a custom package name for each namespace specified in the wsdls schema.
      -ssi                     Generate an interface for the service implementation (Default: off).
      -wv                      WSDL Version. Valid Options : 2, 2.0, 1.1
      -S                      Specify a directory path for generated source
      -R                      Specify a directory path for generated resources
      -em                      Specify an external mapping file
      -f                      Flattens the generated files
      -uw                      Switch on un-wrapping.
      -xsdconfig <path to file> Use XMLBeans .xsdconfig file. Valid only with -d xmlbeans.

せっかくなので作ったスタブクラスのソースコードを置いておく

-rail2go.client.adb.uw.ExpService06ExpService06Soap12Stub
-rail2go.client.adb.uw.ExpService06ExpService06SoapStub
-rail2go.client.adb.w.ExpService06ExpService06Soap12Stub
-rail2go.client.adb.w.ExpService06ExpService06SoapStub

# それにしても、必要なJARファイルの多さには参った……
# もっと手軽なライブラリはないのかなぁ……

追記: 2007-11-18

JAX-WSのリファレンス実装でも試してみた ⇒ RailGo Webサービス と JAX-WS を試す

tags: zlashdot WebServices ApacheAxis Java RailGo SOAP WSDL

Posted by NI-Lab. (@nilab)