Metro JAX-WS
Webサービスを作るのもアノテーション使って楽ちんになってたのね。
でもサービスを公開する側(サーバ側)はAXIS2は組み込みの仕方がいまだにわからんので。
他にないかと調べてたらGlassfishがMetroていうプロダクトも作っててどうもこれが組み込み簡単ぽそう。
準備
環境はこんな感じ。
Eclipse 3.7 Indigo(ちょい前にDLしてたpleiades-e3.7-java-jre_20110924.zip)
JavaSE 7 update3
Ant1.8.3
Tomcat7(Pleiades同梱の)
Metroをダウンロード→Metro 2.2 download
あとJAVA_HOMEとANT_HOME、CATALINA_HOMEを環境変数に追加してPATHにも追加。
Metroのインスト
> ant -Dcatalina.home=%CATALINA_HOME% -f metro-on-tomcat.xml install
これでTomcatの共有ライブラリにJarがコピーされる。
次にJDK7の更新。
これはJDK7付属のJAX-WSが2.1のため(Metroは2.2のRI)
> mkdir %JAVA_HOME%\jre\lib\endorsed
作成したendorsedフォルダにmetro/lib/webservices-api.jarをコピー。
eclipseの設定
インストしたJDK7をインストール済みJREに追加。
Pleiadesで初めから入っているJREでもシステムライブラリに「webservices-api.jar」を一番上に追加でもいいかも?
サービスクラスの作成
Tomcatプロジェクトを作成しておもむろにサービスクラスを作成。
(プロジェクトのシステムライブラリは追加したJREのJDK7)
package sample.service; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; @WebService public class HelloWorld { @WebMethod public String hello(@WebParam String param) { return param + " World"; } }
ただのPOJOに「@WebService」アノテーションを付与。
publicなメソッドは「@WebMethod」を付与しなくてもいいぽい。
jaxws.xmlの作成
サービスエンドポイントを定義するsun-jaxwx.xmlをWEB-INF直下に作成。
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'> <endpoint name="hello" implementation="sample.service.HelloWorld" url-pattern="/service/HelloWorld.ws"/> </endpoints>
web.xmlの作成(編集)
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>wsservlet</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>wsservlet</servlet-name> <url-pattern>*.ws</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app>
デプロイ&起動
Tomcat Launcherで起動して次のURLにアクセス。
http://localhost:8080/jax-wx/service/HelloWorld.ws
こんな画面が表示されれば成功。
クライアントの作成
WSDLが手に入ったので今度はクライアント側のスタブを作成。
これはWsImport Ant Taskを使って生成。
<?xml version="1.0" encoding="utf-8"?> <project name="HelloWorld" basedir="." default="wsdl2java"> <property name="metro.home" value="../metro2.2"/> <path id="metro.classpath"> <fileset dir="${metro.home}/lib"> <include name="*.jar"/> </fileset> </path> <taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport"> <classpath refid="metro.classpath"/> </taskdef> <target name="wsdl2java"> <wsimport wsdl="http://localhost:8080/jax-ws/service/HelloWorld.ws?wsdl" sourcedestdir="src" destdir="classes" package="sample.client" xnocompile="yes"> </wsimport> </target> </project>
生成したスタブはもちろんJAX-WS2.2準拠になってるのでプロジェクトで使用しているJREにMetro2.2のwebservices-api.jarが無いとコンパイルエラーになる。
クライアント部分のソースはこちら。
public class Client { public static void main(String[] args) throws Exception { HelloWorldService ws = new HelloWorldService(); HelloWorld proxy = ws.getHelloWorldPort(); // サービス呼び出し System.out.println(proxy.hello("Hello")); } }
おまけ:javaからWSDL生成
axisでjava2wsdlがあるんだしと調べたらすぐしたにあった。
<?xml version="1.0" encoding="utf-8"?> <project name="HelloWorld" basedir="." default="java2wsdl"> <property name="metro.home" value="../metro2.2"/> <path id="metro.classpath"> <fileset dir="${metro.home}/lib"> <include name="*.jar"/> </fileset> </path> <taskdef name="wsgen" classname="com.sun.tools.ws.ant.WsGen"> <classpath refid="metro.classpath"/> </taskdef> <target name="java2wsdl" depends="init"> <wsgen sei="sample.service.HelloWorld" sourcedestdir="src" destdir="classes" resourcedestdir="wsdl" genwsdl="true"> <classpath path="WEB-INF/classes"/> </wsgen> </target> </project>
wsgenタスクでWSDLだけ作って欲しいんだけど、スタブも作成されるのが…。
EclipseでAntを実行したときにエラーでてwsgenが止まる場合、外部ツール構成でランタイムを指定すればOK。
Ant Taskの詳細は以下。
Tools 3. wsimport Ant Task
Tools 5. wsgen Ant Task