JAX-WS 2.0(その3)

Download Report

Transcript JAX-WS 2.0(その3)

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定義は分離したファイルに格納)

管理画面でのWSDLの確認
管理画面でサービスの確認(3)
管理画面でサービスの確認(4)
クライアントプログラムの準備


自動生成ツール 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 のような不思議な名前が出力
指定されたインタフェースを元に動的に生
成されるクラス
XMLの形式でメッセージを交換
 中立なデータ形式(事実上の標準)
システム、言語、アプリケーション非依存
ver 1.0 http://www.w3.org/2000/xp/Group/
ver 1.2 http://www.w3.org/TR/2003/RECsoap12-part1-20030624/
 メッセージが「構造」を持つ
データ構造の定義は XML Schema で

SOAP(Simple Object Access Protocol)
登場当時の認識
 現在:広範囲の応用範囲を支える基礎技術
「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>


SOAPMessage クラス
SOAPのメッセージを表す(送受信とも)
getSOAPHeader(), getSOAPBody(),
addAttachment(), getAttachment()
など、メッセージ操作のメソッド群
SOAPConnection クラス
通信を実行 call() メソッド
SOAPMessage response
= sc.call( SOAPMessage request, Object url );

いずれも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 );
}