280 likes | 429 Views
Web サービス II ( 第 7 回 ). 2007 年 11 月 7 日 植田龍男. この時間の目標. JAX-WS 2.0 のアーキテクチャのまとめ クライアント側のクラスの働き SOAP メッセージとメッソッド呼び出し. 復習: Web サービスの構築開始. import javax.jws.*; @WebService public class Hello { public String sayHello( String name ) { return “ Hello, ” + name; }
E N D
WebサービスII (第7回) 2007年11月7日 植田龍男
この時間の目標 • JAX-WS 2.0 のアーキテクチャのまとめ • クライアント側のクラスの働き • SOAPメッセージとメッソッド呼び出し
復習:Webサービスの構築開始 import javax.jws.*; @WebService public class Hello { public String sayHello( String name ) { return “Hello,” + name; } }
Java SE 6:Javaの側から構築 • 実装クラスを「ごく普通の Java」のプログラムとして書く ( POJO = Plain Old Java Object ) • Webサービスのアノテーションを付ける (最低限なら @WebService のみ) • サーバに渡す • サーバ(Glassfish ver 2)の側で自動生成
自動生成(wsgenツール) javac hello/Hello.java wsgen -cp . hello.Hello hello.jaxws 以下に sayHello.java, sayHelloResponse.java sayHello.class sayHelloResponse.class (HelloService.wsdl, HelloServiceTypes.xsd)
サーバ側のまとめ • サービスの実装クラス( Hello ) • メソッド呼び出しの引数と返り値のクラス メソッド名(sayHello) プロパティ args0, args1,… メソッド名+Response(sayHelloResponse) プロパティ _return • WSDL– 公開のURL ( Schema定義は分離したファイルに格納)
クライアントプログラムの準備 • 自動生成ツール wsimport wsimport HelloService.wsdl または wsimport http://localhost/Service?wsdl • Hello.class, HelloService.class, ObjectFactory.class SayHello.class, SayHelloResponse.class
クライアント側の構成 • サービスのインタフェース(Hello ) • サービスのインスタンスを取り出す「サービス」のクラス ( HelloService ) • メソッドの引数と返り値のクラス ( sayHello, sayHelloResponse ) • JAXBでインスタンス生成に必要なクラス ObjectFactory ( XML => Java で必要)
生成されたクラスの正体は? • ツール javap (単純な逆アセンブラ) javap Hello interface Hello javap HelloService class extends javax.xml.ws.Service javap sayHello class sayHello javap sayHelloResponse class sayHelloResponse
WSDL のどこにクラスの情報? • sayHello, sayHelloResponse <definitions> <types> include schema</types> : • クラスの内容はJAXBによって完全に復元 • サーバ側と「同じクラス」がクライアント側にも存在すると考えてよい (データとしてやり取りされるクラスも同様)
WSDLのどこに情報が?(2) • Hello インタフェース <definitions> : <portType> <operation>メソッド定義</operation> </portType> • サーバ側の実装の情報は存在しない
WSDLのどこに情報が • HelloService クラス Helloインタフェースの情報 + javax.xml.ws.Service クラス • 拡張部分は 自身のコンストラクタ getHelloPort() メソッド -- Helloを実装したインスタンスを得る
クライアントプログラムの作成 public class HelloClient { public static void main ( String[] args ) { HelloService service = new HelloService(); Hello hello = service.getHelloPort(); String message =hello.sayHello( "Tatsuo" ); System.out.printf ( message ); }
Hello hello の謎 • hello は Helloを実装したクラス • 「代理オブジェクト」として振る舞うクライアント側のクラス hello.sayHello( “Tatsuo” ); // サービスを呼び出す • でも、どこに存在? (クラスファイルは生成されていない?) • 以前のWebサービスでは HelloStab.class
クラス名を強引に調べてみると Hello hello = service.getHelloPort(); System.out.println( hello.getClass().getName() ); • Proxy16 のような不思議な名前が出力 • 指定されたインタフェースを元に動的に生成されるクラス
SOAPとは? XMLの形式でメッセージを交換 中立なデータ形式(事実上の標準) システム、言語、アプリケーション非依存 ver 1.0 http://www.w3.org/2000/xp/Group/ ver 1.2 http://www.w3.org/TR/2003/REC-soap12-part1-20030624/ メッセージが「構造」を持つ データ構造の定義は XML Schema で
そもそも SOAP とは何の略? SOAP(Simple Object Access Protocol) 登場当時の認識 現在:広範囲の応用範囲を支える基礎技術 「SOAP は SOAP」
SOAP のメッセージの構造 <SOAP-ENV:Envelope xmlns:SOAP-ENV= “http://schemas.xmlsoap.org/soap/envelope/”> <SOAP-ENV:Header> </SOAP-ENV:Header> <SOAP-ENV:Body> <mymessage> Hello </mymessage> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAPMessageの例(Hello) <SOAP-ENV:Envelope xmlns:SOAP-ENV= "http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <sayHello> <arg0>Tomoharu</arg0> </sayHello> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAPMessageの例(Hello) <SOAP-ENV:Envelope xmlns:SOAP-ENV= "http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <sayHelloResponse> <return>Hello,Tomoharu</return> </sayHelloResponse> </SOAP-ENV:Body>
Java SE 6 : javax.xml.soap SOAPMessage クラス SOAPのメッセージを表す(送受信とも) getSOAPHeader(), getSOAPBody(), addAttachment(), getAttachment() など、メッセージ操作のメソッド群 SOAPConnection クラス 通信を実行 call() メソッド SOAPMessage response = sc.call( SOAPMessage request, Object url );
Java SE 6 : javax.xml.soap いずれもFactoryのパターンで利用 MessageFactory mf = MessageFactory.newInstance(); SOAPMessage request = mf.createMessage( new MimeHeaders(), new FileInputStream( source ) ); SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance() SOAPConnection connection = scf.createConnection();
サンプルソース(1) import java.io.*; import javax.xml.soap.*; public class SOAPTest { public static void main( String[] args ) { String url = "http://localhost:8080/HelloService/hello"; String source = "hello.xml";
サンプルソース(2) MessageFactory mf = MessageFactory.newInstance(); SOAPMessage request = mf.createMessage( new MimeHeaders(), new FileInputStream( source ) );
サンプルソース(3) SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); SOAPConnection connection = scf.createConnection(); SOAPMessage response = connection.call( request, url ); response.writeTo( System.out ); }