// 下階層用テンプレート #topicpath ---- //ここにコンテンツを記述します。 Eclipse + WTPを使って、WEBサービスの開発をプロトしてみました。プリミティブオブジェクト以外の型についても、正しくWSDLとプロキシクライアントが作成され、使い物になるものが生成されることが確認できました。 #contents WEBサービス開発の流れは -Webプロジェクトの作成 -公開したいJavaBeansの作成 -そのJavaBeansから、WEBサービスの作成 --WSDLの作成 --プロキシクライアントを保存するJavaプロジェクトの作成 --プロキシクライアントの作成 といった感じになります。 ** Webプロジェクトの作成 [#o459cc66] 動的Webプロジェクト プロジェクト名 : WebServicesSamplesWeb Content Directory: war Source Deirectory: source EARプロジェクト プロジェクト名 : WebServicesSamplesEAR #ref(project.png) **公開したいJavaBeansの作成 [#o68f2f73] 例として -java.lang.Stringを返すsayHelloメソッド -java.lang.String[]を返すsayHellosメソッド -JavaBeans nu.mine.kino.services.Model を返すgetModelメソッド を持つ nu.mine.kino.services.HelloWorld クラスを作成し、これをWEBサービスとして公開したいと思います。 -nu.mine.kino.services.HelloWorld package nu.mine.kino.services; /** * @author Masatomi KINO * @version $Revision$ */ public class HelloWorld { public String sayHello() { // Stringを返す return "Hello"; } public String[] sayHellos() { // String[] を返す return new String[] { "Hello World.", "hello world." }; } public Model getModel() { // Model を返す return new Model(); } } -nu.mine.kino.services.Model package nu.mine.kino.services; /** * @author Masatomi KINO * @version $Revision$ */ public class Model { public String getName() { return "なまえ"; } } ** JavaBeansからWEBサービスの作成 [#pee2d12b] ***WSDLの作成 [#na7a69c7] 次にWTPを使って、JavaBeansからWSDLなどなどを作成していきます。パッケージエクスプローラからHelloWorldを選択して右クリックし Create Web services を選択します。そうすると下のようなダイアログが表示されます。 #ref(01.png) このダイアログで Web Service Type: Bottom up Java Bean Web Service Generate a proxy にチェック Install Web Service client on server は外す など選択して、次へ進みます。ちなみに一般的に Bottom up Java Bean Web Service: JavaBeansからWSDL作成 Top down Java Bean Web Service: WSDLからJavaBeans作成 という意味だそうです。 次画面ではBeansを選択する画面です。このままHelloWorldを選択して、次へ進みます #ref(02.png) 次は公開するWEBサービスをどのWebプロジェクトにDeployするか、またクライアントプロキシをどのプロジェクトに配置するかを指定します。Client Project typeは Java Utility Project にしておきます。 #ref(03.png) 次に公開するメソッドを選択します。下のように選択し、次に進みます。 #ref(04.png) ここまできて、ようやくWEBプロジェクトにWSDLファイルが作成されます。J次の画面で、JBossをスタートしますかと聞いてくるので、サーバをスタートさせます。自動的にEARプロジェクトがデプロイされ、WEBサービスが公開された状態になります((あらかじめJBossを設定済みの必要があると思います))。 #ref(05.png) ***プロキシクライアントの作成 [#h7f7922c] あとは次へ次へと進んでいけばさっき指定したJavaProjectにプロキシクライアントが配置され、全て完了です。 #ref(tree.png) 最終的に上のようなディレクトリ構造になります。 **実行してみる。 [#f6d05d0d] いま、WEBサービスが公開されている状態なので、実際にテストクラスを作って稼動確認してみます。プロキシが置かれたプロジェクト内で以下のMainクラスを作成します。 import java.rmi.RemoteException; import javax.xml.rpc.ServiceException; import nu.mine.kino.services.HelloWorld; import nu.mine.kino.services.HelloWorldServiceLocator; import nu.mine.kino.services.Model; public class Main { public static void main(String[] args) { try { HelloWorld helloWorld = new HelloWorldServiceLocator() .getHelloWorld(); System.out.println(helloWorld.sayHello()); String[] hellos = helloWorld.sayHellos(); for (int i = 0; i < hellos.length; i++) { System.out.println(hellos[i]); } Model model = helloWorld.getModel(); System.out.println(model.getName()); } catch (ServiceException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } } 実行結果は以下のようになります。 2006/04/25 17:36:29 org.apache.axis.utils.JavaUtils isAttachmentSupported 警告: 要求されたクラス(javax.activation.DataHandler と javax.mail.internet. MimeMultipart)が見つかりません。Attachmentサポートが利用できません。 / [en]-(Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.) Hello Hello World. hello world. なまえ なんか警告が出てますが、Stringも配列もJavaBeansも正しく稼動していることが確認できました!! **deploy/undeployをするためのantのbuild.xml [#kdcebbcc] さて、ここまでで既存のJavaBeansをWEBサービスとして公開するところまでができました。あとは公開したWEBサービスを、デプロイしたりアンデプロイするantのbuildスクリプトを作成しておこうと思います。 -build.xml <?xml version="1.0" encoding="UTF-8"?> <project name="WebServices Deploy" basedir="."> <property file="build.win.properties" /> <property file="build.properties" /> <!-- http://ws.apache.org/axis/java/ant/ant.html --> <path id="axis.classpath"> <fileset dir="${web.lib.dir}" includes="*.jar" /> <fileset dir="${axis.dir}/lib" includes="*.jar" /> </path> <taskdef resource="axis-tasks.properties" classpathref="axis.classpath" /> <target name="deploy"> <axis-admin port="8080" hostname="localhost" failonerror="true" servletpath="${axisservlet}" debug="true" xmlfile="${wsdd.deployfile}" /> </target> <target name="undeploy"> <axis-admin port="8080" hostname="localhost" failonerror="true" servletpath="${axisservlet}" debug="true" xmlfile="${wsdd.undeployfile}" /> </target> </project> -build.properties wsdd.dir=war/WEB-INF/HelloWorldService/nu/mine/kino/services wsdd.deployfile=${wsdd.dir}/deploy.wsdd wsdd.undeployfile=${wsdd.dir}/undeploy.wsdd web.lib.dir=war/WEB-INF/lib axis.dir=C:/javatools/axis axisservlet=WebServicesSamplesWeb/servlet/AxisServlet **TIPS集 [#r00d3b75] ***TCPモニタを使う [#l9c1164b] Apache Axisにはサーバとの通信をキャプチャするTCPモニタが同梱されています。Eclipseから、メインクラス名:org.apache.axis.utils.tcpmon で起動できます。 つかいかたですが、今までは クライアント(接続先:8080) -> (ポート:8080)サーバ という接続でしたが、あいだにこのツールをかますためにはクライアントの接続先ポート番号を例えば クライアント(接続先:8081) -> (ポート:8081)tcpmon(接続先:8080) -> (ポート:8080)サーバ と変更する必要があります。つまりクライアントのプロクシが接続しに行くサーバのポート番号を変更する必要があるのですが、それは HelloWorldServiceLocator#setHelloWorldEndpointAddress ("http://localhost:8081/WebServicesSamplesWeb/services/HelloWorldService") というエンドポイントを変更するメソッドで行うことができます。 参考:~ - http://ws.apache.org/axis/java/ant/ant.html -[[Webサービス:http://jomora.bne.jp/wiki/pukiwiki.php?Web%A5%B5%A1%BC%A5%D3%A5%B9]] -[[WebServices - Axis:http://ws.apache.org/axis/ja/java/user-guide.html]] -[[SOAPベースのWebサービスにおける複雑なデータ・タイプ:http://www-06.ibm.com/jp/developerworks/webservices/030718/j_ws-complex.html]] -[[Webサービス・プログラミングのヒントと秘訣: JAX-RPCアプリケーションにてステートフル・セッションを構築:http://www-06.ibm.com/jp/developerworks/webservices/040924/j_ws-tip-stateful.html]] ---- この記事は #vote(おもしろかった[7],そうでもない[4]) -java2wsdlで、返り値をIModelっていうinterfaceにしてたら、どうしてもcomplexTypeが生成されなかった。。クラスに変えたらすぐできたんだけど。。。。これで半日つかったよ。 -- [[きの]] &new{2006-04-25 16:15:51 (火)}; -セッション管理について調べています。挙動を見ると、クライアントはlocator.setMaintainSession(true)とするとサーバが返却してきたCookieを再送するみたいです。 falseとすると再送しない、と。サーバは少なくともJBoss/Axis環境ではセッション管理(<-Servlet/JSPでいうHttpSession管理ね)を行おうとしてるみたい。。 -- [[きの]] &new{2006-06-09 09:14:20 (金)}; -でもこれだと、Axis依存しちゃうよなあ。WebサービスもしくはJAX-RPC準拠にやる方法を調べよう。 -- [[きの]] &new{2006-06-09 09:22:33 (金)}; -ポータブルにやるには javax.xml.rpc.Stub jaxrpcStub = (javax.xml.rpc.Stub) getVendorSpecificStub(); jaxrpcStub._setProperty(javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); みたいだけど、そもそもプロクシがAxis依存だから、まあいっかー -- [[きの]] &new{2006-06-09 09:36:52 (金)}; -強引にやると、 ((Stub) service)._setProperty( javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); でできるね。serviceは new HelloWorldServiceLocator().getHelloWorld();の返り値ね。-- [[きの]] &new{2006-06-09 09:46:15 (金)}; -基本的に、Statelessに作れーってのが基本かなぁ。 -- [[きの]] &new{2006-06-09 13:13:28 (金)}; -ちなみに、サーバがCookieを返すには、公開されたサービスが、javax.xml.rpc.server.ServiceLifecycleをimplementsしないとダメみたい。 -- [[きの]] &new{2006-07-05 21:37:00 (水)}; -↑違う。。Filterかましてrequest.getSession()やっても、サーバがcookie返すようになった。 -- [[きの]] &new{2006-07-05 23:01:26 (水)}; -例外クラスは、引数なしのコンストラクタや、フィールドを初期化するコンストラクタが必要なんですね -- [[きの]] &new{2006-07-17 21:43:06 (月)}; #comment #topicpath SIZE(10){現在のアクセス:&counter;}