|
|
WebOTX Manual V10.1 (第7版) 目次を表示 |
Webサービス参照ウィザードを使うと、JAX-WS 準拠の Web サービスクライアントを作成することができます。
Webサービスの作成 の 「Webサービス作成ウィザードを使用する前に」をご覧ください。
Web サービス参照ウィザードの起動方法は二つあります。
WebOTX Developer (with Developer's Studio) のメニューから ファイル > 新規 > その他 を選択すると、 新規ダイアログが起動します。
Web サービス参照ウィザードを開始するには、 Web サービス > Web サービス参照 を選択し、次へをクリックします。

プロジェクトを選択し、WebOTX Developer (with Developer's Studio) の右クリックメニューから Web サービス > Web サービス参照 を選択すると、 Web サービス参照 ダイアログが起動します。

Web サービス参照ウィザードを使用して、JAX-WS 準拠の Web サービスクライアントを作成する方法を説明し図です。 アプリケーションは、自動生成されるクライアントコードを用いて Web サービスと通信します。 クライアントコードを利用する呼び出しコードも自動生成することができます。 外部環境プロパティを利用して、WSDL の参照先を切り替えることにより、利用する Web サービスを 例えば本番環境とテスト環境で、切り替えることもできます。

Web サービス参照ウィザードを使用して、Web サービス参照をプロジェクトに追加すると、 以下のことができるようになります。
以下では、SOAP Webサービスの作成 で作成した Web サービスを呼び出す例を用いて、説明を行います。

Web サービス参照ウィザードを下記の説明を参考に設定します。
| 項目 | 説明 |
|---|---|
| ソース・フォルダー | クライアントコードを生成するプロジェクトとソース・フォルダーを指定します |
| WSDL の URL を指定して作成 | 利用する Web サービスの WSDL の URL を指定します。file:// プロトコルも指定できます。 |
| ワークスペース内の WSDL から作成 | 利用する Web サービスの WSDL がワークスペース内にある場合にはこちらで指定します。 |
| 生成するクライアントのパッケージを指定 | 「WSDLから作成」にチェックをした場合は、Web サービスのネームスペースからパッケージ名を作成します。 「生成するクライアントのパッケージを指定」にチェックした場合には、任意のパッケージ名を指定できます。 |
| 非同期呼び出しを行う | クライアントコードを非同期呼び出し対応にする場合にはチェックします。 詳細は、呼び出しコードの生成 で説明します。 |
| WSDL のロケーションを外部環境プロパティに設定する | WSDL のロケーションを外部環境プロパティに設定し、切り替え可能にする場合にはチェックします。 指定したソース・フォルダーに外部環境プロパティが設定されており、なおかつ、 ウィザードの他の項目が正しく設定されている場合にチェック可能になります。 外部環境プロパティは、アプリケーション開発ガイド(共通)9. 外部環境プロパティ のマニュアルを 参照してください。。 詳細は、外部環境プロパティの利用 で説明します。 |
設定が完了したら、完了 ボタンをクリックします。
処理が完了すると、プロジェクトは以下の構成になります。

sample.hello パッケージが生成されたクライアントコードです (1)。 Web サービス参照ノード は、設定した Web サービスがサービス名、WSDL、サービス、ポート、オペレーション、 呼び出し方式の順にツリーが生成されます (2)。 references ディレクトリは、読み込んだ WSDL や XSD がコピーされます (3)。
すでに Web サービス参照が登録されている場合で、新規作成しようとしている Web サービス参照が 以下の条件を満たす場合は、同一 Web サービスとしてみなし、新規作成ではなく更新処理になります。
Memo
Web サービス参照 は SOAP 1.1 のみに対応しています。
SOAP 1.2 には対応していませんので、ご注意ください。
Caution
WSDLのURLにlocalhostを指定した場合、特定の環境では、プロキシー除外設定がうまくいかず、
wsimportコマンドの実行に失敗した旨のエラーが表示されることがあります。
この場合は、localhostではなく、作業マシンのIPアドレスを指定してください。
Web サービスの呼び出しコードを生成する方法について説明します。 Web サービスの呼び出しコードを生成するには、プロジェクト・エクスプローラーの Web サービス参照 ノードを利用します。
Memo
Web サービス参照 ノードは プロジェクト・エクスプローラー でのみ表示されます。
Java EE パースペクティブに切り替えて、プロジェクト・エクスプローラーを表示してお使いください。
呼び出したいオペレーションの下の 同期呼び出しノード、 非同期呼び出し(コールバック)ノード、 非同期呼び出し(ポーリング)ノードのいずれかを、 エディタの呼び出しコードを挿入したい場所にドラッグ&ドロップします。

ドラッグ&ドロップが完了すると、そのオペレーションを指定した方式で呼び出すのに必要なコードが生成されます。
同期呼び出しの場合:
package main;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try { // web service reference for HelloService();
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
java.lang.String result = port.sayHello(arg0);
// TODO process result
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // web service reference for HelloService
}
}
非同期呼び出し(ポーリング)の場合:
package main;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try { // web service reference for HelloService
final int WAIT_TIME = 500;
sample.hello.HelloService_Service service = new sample.hello.HelloService_Service(
webotx.ds.ExternalEnvironment.getURL("HelloService"),
webotx.ds.ExternalEnvironment.getService("HelloService"));
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
javax.xml.ws.Response<sample.hello.SayHelloResponse> res = port
.sayHelloAsync(arg0);
while (!res.isDone()) {
Thread.sleep(WAIT_TIME);
}
// TODO process response
System.out.println(res.get().getReturn());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // web service reference for HelloService
}
}
Caution
生成したコード[res.get()]の後に、に手動で[.getXXX()]を追加する必要があります。この例では、[.getReturn()]です。
追加前:
System.out.println(res.get());
追加後:
System.out.println(res.get().getReturn());
非同期呼び出し(コールバック)の場合:
package main;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try { // web service reference for HelloService
final int WAIT_TIME = 500;
sample.hello.HelloService_Service service = new sample.hello.HelloService_Service(
webotx.ds.ExternalEnvironment.getURL("HelloService"),
webotx.ds.ExternalEnvironment.getService("HelloService"));
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
javax.xml.ws.AsyncHandler<sample.hello.SayHelloResponse> handler = new javax.xml.ws.AsyncHandler<sample.hello.SayHelloResponse>() {
public void handleResponse(
javax.xml.ws.Response<sample.hello.SayHelloResponse> res) {
try {
// TODO process result
System.out.println(res.get().getReturn());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
java.util.concurrent.Future<?> result = port.sayHelloAsync(arg0,
handler);
while (!result.isDone()) {
Thread.sleep(WAIT_TIME);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // web service reference for HelloService
}
}
Caution
生成したコード[res.get()]の後に、に手動で[.getXXX()]を追加する必要があります。この例では、[.getReturn()]です。
追加前:
System.out.println(res.get());
追加後:
System.out.println(res.get().getReturn());
生成された呼び出しコードのインデントを整えたい場合には、整形したい部分を選択して、 Ctrl + Shift + F を押してください。
生成された呼び出しコードは、引数の部分が設定されていないため、引数を設定します。
下記の例では、同期呼び出しの呼び出しコード上の arg0 に Bob を設定しています。
package main;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try { // web service reference for HelloService();
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "Bob";
java.lang.String result = port.sayHello(arg0);
// TODO process result
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // web service reference for HelloService
}
}
ここまで設定を行った後で、main.Main クラスを実行すると Web サービスの呼び出しが行われます。

Web サービス参照ウィザードでは、以下の3つの呼び出し方式をサポートしています。
ここでは、それぞれの呼び出し方式について説明します。
Web サービスの呼び出しを同期的に行います。Web サービスの呼び出しが完了するまで待つため、 他の処理ができませんが、記述がシンプルになります。
Web サービスの呼び出しを非同期的に行います。Web サービスの呼び出しの完了を待たずに 処理を続けることができます。Web サービスの呼び出しの完了は、作成したスレッドの上のイベントハンドラが受け取ります。 記述は複雑になりますが、非同期呼び出し(ポーリング)のようにサーバに Web サービスの呼び出しの完了確認を定期的に 行う処理の記述をする必要がありません。
Web サービスの呼び出しを非同期的に行います。Web サービスの呼び出しの完了を待たずに 処理を続けることができます。Web サービスの呼び出しの完了を確認するために、定期的にサーバに問い合わせを行います。 問い合わせ間隔が長くなれば、それだけWeb サービスの呼び出しの完了のタイミングが遅くなりますが、 任意のタイミングで Web サービスの呼び出し結果を取得することができます。
外部環境プロパティを利用して、WSDL のロケーションを変更する方法について説明します。 この機能は、例えば、参照する WSDL の内容が同じで、デプロイ先がテスト環境から本番環境に切り替わった場合に、 Web サービス参照を作り直すことなく、設定を切り替えるだけで対応を可能にすることができます。
Web サービス参照ウィザードで WSDL のロケーションを外部環境プロパティに設定する が有効だった場合、 WSDL のロケーションは外部環境プロパティに設定されます。 下記の例では、ExternalEnvironment.java と otx-env.properties が外部環境プロパティに関するファイルです。 外部環境プロパティが設定されたソース・フォルダーに Web サービス参照を設定した場合、 外部環境プロパティに関するファイルは 上書きされ、Web サービス参照に対応したファイルに変更されます。

Web サービスの呼び出しコードを生成すると、以下のようなコードが挿入されます。
同期呼び出しの場合:
package main;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try { // web service reference for HelloService
sample.hello.HelloService_Service service = new sample.hello.HelloService_Service(
webotx.ds.ExternalEnvironment.getURL("HelloService"),
webotx.ds.ExternalEnvironment.getService("HelloService"));
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
java.lang.String result = port.sayHello(arg0);
// TODO process result
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // web service reference for HelloService
}
}
WSDL のロケーションを変更する場合には、プロジェクトの右クリックメニューから 構成 > 外部環境プロパティの設定 をクリックし、 該当するプロパティの値を変更します。

この例では、開発中に切り替えていますが、パッケージを作って後の運用時に外部環境プロパティを変更することもできます。 詳細については、 [ 開発環境の構築(WebOTX Developer) > 外部環境プロパティ ] を参照してください。
Web サービス参照の追加機能について説明します。プロジェクト・エクスプローラーの Web サービス参照 ノードの右クリックメニューから Web サービス参照の追加 をクリックすると、Web サービス参照ウィザードが表示されます。 機能は、メニューや、プロジェクトの右クリックメニューから呼び出した場合と違いはありません。

Web サービス参照の全削除機能について説明します。プロジェクト・エクスプローラーの Web サービス参照 ノードの右クリックメニューから Web サービス参照の全削除 をクリックすると、確認ダイアログが表示されます。


はい をクリックした場合には、Web サービス参照に関するファイルである以下のファイルが削除されます。
いいえ をクリックした場合には、キャンセルされます。
Web サービス参照の更新機能について説明します。プロジェクト・エクスプローラーの サービス名 ノードの右クリックメニューから Web サービス参照の更新 をクリックすると、確認ダイアログが表示されます。


はい をクリックした場合には、Web サービス参照に関するファイルである以下のファイルが更新されます。
ドラッグ&ドロップで生成されたサービスの呼び出しコードは更新されませんので、手動で更新してください。
いいえ をクリックした場合には、キャンセルされます。
Web サービス参照の削除機能について説明します。プロジェクト・エクスプローラーの サービス名 ノードの右クリックメニューから Web サービス参照の削除 をクリックすると、確認ダイアログが表示されます。


はい をクリックした場合には、Web サービス参照に関するファイルである以下のファイルが削除されます。
ドラッグ&ドロップで生成されたサービスの呼び出しコードは削除されませんので、手動で削除してください。
いいえ をクリックした場合には、キャンセルされます。
-Djava.endorsed.dirs=<WebOTX_DIR>/lib/endorsed
Memo
<WebOTX_DIR>はWebOTXのインストールディレクトリに読み替えてください。
| ディレクトリ | ファイル |
|---|---|
| src/sample | HelloClient.java |
src> wsimport -d ../classes -s . -keep http://localhost/hellows/hello?wsdlwsimportコマンドの詳細に関しては、 [ コマンドリファレンス > wsimport ] を参照してください。
| ディレクトリ | ファイル |
|---|---|
| src/sample/ | Hello.java Hello_Service.java SayHello.java SayHelloResponse.java ObjectFactory.java package-info.java |
| classes/sample/ | Hello.class Hello_Service.class SayHello.class SayHelloResponse.class ObjectFactory.class package-info.class |
package sample;
public class HelloClient {
public static void main(String[] args) {
Hello_Service service = new Hello_Service();
Hello port = service.getHelloPort();
HelloClient client = new HelloClient();
client.hello(port);
}
private void hello(Hello port){
try {
System.out.println(port.sayHello("WebOTX"));
} catch( java.lang.Exception e) {
e.printStackTrace();
}
}
}
上記コードのように、サービスクラスのgetHelloPort()メソッドで、プロキシ(スタブ)を取得することができます。src> javac -d ../classes sample/HelloClient.java最後に、クライアントクラスを実行します。classesディレクトリで実行してください。
classes> java sample.HelloClient正常に実行が完了すれば、次のような結果が出力されます。
Hello WebOTX!
| Service.Modeの値 | 説明 |
|---|---|
| MESSAGE | SOAPメッセージ全体を扱います。SourceおよびSOAPMessageを利用する場合に指定できます。 |
| PAYLOAD | SOAPメッセージの本体のみを扱います。SourceおよびJAXBを利用する場合に指定できます。 |
package sample; import java.io.StringReader; import javax.xml.ws.Dispatch; import javax.xml.ws.Service; import javax.xml.namespace.QName; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.Source;
public class HelloClientSource {
public static void main(String[] args) { Service service = new Hello_Service(); QName portQName = new QName("http://sample","HelloPort"); String request = "<ns1:sayHello xmlns:ns1=\"http://sample\">" +"<arg0>WebOTX</arg0></ns1:sayHello>"; try { Dispatch<Source> sourceDispatch = service.createDispatch( portQName,Source.class, Service.Mode.PAYLOAD); Source result = sourceDispatch.invoke( new StreamSource(new StringReader(request))); } catch (Exception e) { e.printStackTrace(); } } }
package sample;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.namespace.QName;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
public class HelloClientJAXBContext {
public static void main(String[] args) {
Service service = new Hello_Service();
QName portQName = new QName("http://sample","HelloPort");
try {
JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
Dispatch jaxbDispatch = service.createDispatch(portQName,jaxbContext, Service.Mode.PAYLOAD);
ObjectFactory factory = new ObjectFactory();
SayHello msg = new SayHello();
msg.setArg0("WebOTX");
JAXBElement<SayHello> sayHello = factory.createSayHello(msg);
JAXBElement<SayHelloResponse> response = (JAXBElement<SayHelloResponse>) jaxbDispatch.invoke(sayHello);
SayHelloResponse result = response.getValue();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package sample;
import javax.xml.soap.*;
import java.io.StringReader;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.Source;
public class HelloClientSOAPMessage {
public static void main(String[] args) {
Service service = new Hello_Service();
QName portQName = new QName("http://sample","HelloPort");
String request = "<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<S:Body><ns1:sayHello xmlns:ns1=\"http://sample\"><arg0>WebOTX</arg0>" + "</ns1:sayHello></S:Body></S:Envelope>";
try {
SOAPMessage message = null;
MessageFactory factory = MessageFactory.newInstance();
message = factory.createMessage();
message.getSOAPPart().setContent( (Source) new StreamSource(new StringReader(request)));
message.saveChanges();
Dispatch<SOAPMessage> dispatch = service.createDispatch( portQName,SOAPMessage.class, Service.Mode.MESSAGE);
SOAPMessage response = dispatch.invoke(message);
Source result = response.getSOAPPart().getContent();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Service service = new Service(?); ServiceEndpointInterface proxy = service.get?(); java.util.Map<String, Object> ctxt = ((javax.xml.ws.BindingProvider)proxy).getRequestContext(); ctxt.put(com.nec.webotx.webservice.xml.ws.developer. JAXWSProperties.CONTENT_NEGOTIATION_PROPERTY, "***value***");[ソースコードの説明]
java -Dcom.nec.webotx.webservice.xml.ws.client.ContentNegotiation=***value*** クライアントクラスなお、「***value***」には次のうちいずれかの値を指定します。
| 値 | 意味 |
|---|---|
| none | Fast Infoset を使用しない |
| pessimistic | レスポンスメッセージのみFast Infoset を利用する |
| optimistic | リクエストメッセージ・レスポンスメッセージの両方でFast Infoset を利用する |
Memo
JAX-RPCは旧互換のための機能です。
Memo
<WebOTX_DIR>はWebOTXのインストールルートディレクトリ、<J2SE_DIR>はJ2SE
SDKのインストールルートディレクトリのことです。
<?xml version="1.0" encoding="UTF-8"?> <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location="Hello.wsdl" packageName="com.nec.webotx.webservice.sample"/> </configuration>wsdl要素にコンパイル対象のWSDLの情報を指定します。 location属性は、プロジェクトのルートに置いたWSDLのファイル名を指定します。 packageName属性は、WSDLコンパイラが生成するクラスが属するパッケージの名前を指定します。
public class HelloClient {
private javax.xml.rpc.Stub stub; //スタブを定義しておきます。
//wscompileコマンドが生成したクラスの中でjava.rmi.Remoteを継承したインタフェースが
//サービスエンドポイントインタフェースです。Webサービスがクライアントに提供している
//インタフェースを記述したものです。
private Hello_PortType binding; //サービスエンドポイントインタフェースを定義しておきます。
public HelloClient() throws Exception {
//javax.xml.rpc.Serviceを継承したインタフェースは、クライアントが
//Webサービスを仮想化するために使用するインタフェースです。
//このインタフェースを実装したクラスからポートを取得し、
//スタブにキャストしています。
stub = (javax.xml.rpc.Stub) new Hello_Service_Impl().getHelloPort();
//スタブをさらにサービスエンドポイントインタフェースでキャストします。
//これでWebサービスを呼び出す準備は整いました。
binding = (Hello_PortType)stub;
}
//引数でアクセス先のサービスエンドポイントのURLを変更する場合のコンストラクタです。
public HelloClient(java.lang.String url) throws Exception {
stub = (javax.xml.rpc.Stub) new Hello_Service_Impl().getHelloPort();
//スタブのプロパティをセットしてURLを変更します。
stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,url);
binding = (Hello_PortType)stub;
}
//Webサービスを実行するメソッドです。
public java.lang.String say_hello_Hello(java.lang.String in0) throws java.rmi.RemoteException {
//実行したいオペレーションを呼び出します。
return binding.say_hello_Hello(in0);
}
//クライアントを実行するmainメソッドです。
public static void main(String[] args) throws Exception {
HelloClient client;
if(args.length > 0) {
client =new HelloClient(args[0]);
} else {
client =new HelloClient();
}
//Webサービスを実行し、結果を表示します。
System.out.println(client.say_hello_Hello("webotx"));
}
}
_setProperty(com.nec.webotx.webservice.xml.rpc.client.StubPropertyConstants.CONTENT_NEGOTIATION_PROPERTY, "***value***");※クライアントで作成したStubインスタンスに対してこのメソッドを実行する方法もあります。
[設定例]
[foo@webotx ~]$ java -Dcom.nec.webotx.webservice.xml.rpc.client.ContentNegotiation=***value*** クライアントクラスなお、「***value***」には次のうちいずれかの値を指定します。
| 値 | 意味 |
|---|---|
| none | Fast Infoset を使用しない |
| pessimistic | レスポンスメッセージのみFast Infoset を利用する |
| optimistic | リクエストメッセージ・レスポンスメッセージの両方でFast Infoset を利用する |
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
public class DynamicProxyHelloClient {
public static void main(String[] args) {
try {
/*以下の4つの変数の値は、すべてWSDLから取得することができます。*/
//(1)definitions要素のtargetNamespace属性の値です。
String nameSpaceUri = "http://sample/Hello";
//(2)service要素のname属性の値です。
String serviceName = "Hello";
//(3)port要素のname属性の値です。
String portName = "HelloPort";
//(4)公開されているWSDLのURLの文字列です。この文字列は、最後に?wsdlが
//ついているJAX-RPC仕様で定めた形式でなければなりません。
String urlString= "http://localhost:8080/HelloService/Hello?wsdl";
/*WSDLから取得できる変数、ここまで*/
//Webサービスを仮想オブジェクト化します。この部分は汎用的に使えます。
URL wsdlUrl= new URL(urlString);
ServiceFactory serviceFactory = ServiceFactory.newInstance();
Service service=
serviceFactory.createService(wsdlUrl,new QName(nameSpaceUri,serviceName));
//Webサービスの仮想オブジェクトからポートを取得し、プロキシを生成します。
//「Hello_PortType」クラスはサービスエンドポイントインタフェースです。
Hello_PortType proxy =
(Hello_PortType) service.getPort(new QName(nameSpaceUri,portName),Hello_PortType.class);
//Webサービスにアクセスし、結果を出力します。
System.out.println(proxy.say_hello_Hello("hello"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Memo
「DynamicProxy」サンプルは、チュートリアルで作成したWebサービスにアクセスするダイナミックプロキシ方式で作成したクライアントです。
Memo
<WebOTX_DIR>はWebOTXのインストールルートディレクトリ、<J2SE_DIR>はJ2SE
SDKのインストールルートディレクトリのことです。
Memo
クライアントコード中で使っているサービスエンドポイントインタフェースは、JNDIなどを使用して取得するか、wscompileコマンドを使用して生成してください。wscompileコマンドについてはスタティックスタブ方式を参照してください。
[設定例]
[foo@webotx ~]$ java -Dcom.nec.webotx.webservice.xml.rpc.client.ContentNegotiation=***value*** クライアントクラスなお、「***value***」には次のうちいずれかの値を指定します。
| 値 | 意味 |
|---|---|
| none | Fast Infoset を使用しない |
| pessimistic | レスポンスメッセージのみFast Infoset を利用する |
| optimistic | リクエストメッセージ・レスポンスメッセージの両方でFast Infoset を利用する |
Memo
<WebOTX_DIR>はWebOTXのインストールルートディレクトリのことです。
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
public class DIIHelloClient {
//Webサービス名です。
private static String qnameService = "Hello";
//ポート名です。
private static String qnamePort = "HelloPort";
//Webサービスの名前空間URIです。
private static String BODY_NAMESPACE_VALUE ="http://sample/Hello";
//固定値の定義です。
private static String ENCODING_STYLE_PROPERTY =
"javax.xml.rpc.encodingstyle.namespace.uri";
private static String NS_XSD = "http://www.w3.org/2001/XMLSchema";
private static String URI_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
public static void main(String[] args) {
try {
//サービスのインスタンスを作成します。
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(new QName(qnameService));
//ポートからCallオブジェクトを作成します。
QName port = new QName(qnamePort);
Call call = service.createCall(port);
//Callオブジェクトに各種設定を行います。
call.setTargetEndpointAddress("http://localhost:8080/HelloService/Hello");
call.setProperty(Call.SOAPACTION_USE_PROPERTY,new Boolean(true));
call.setProperty(Call.SOAPACTION_URI_PROPERTY,"");
call.setProperty(ENCODING_STYLE_PROPERTY,URI_ENCODING);
QName QNAME_TYPE_STRING = new QName(NS_XSD,"string");
call.setReturnType(QNAME_TYPE_STRING);
call.setOperationName(new QName(BODY_NAMESPACE_VALUE,"say_hello_Hello"));
call.addParameter("String_1",QNAME_TYPE_STRING,ParameterMode.IN);
//Webサービスを実行します。
System.out.println((String)call.invoke(new String[]{"hello"}));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Memo
「DII」サンプルは、チュートリアルで作成したWebサービスにアクセスするDII方式で作成したクライアントです。
call.setProperty(com.nec.webotx.webservice.xml.rpc.client.dii.CallPropertyConstants.CONTENT_NEGOTIATION_PROPERTY, "***value***");(2)クライアント実行時にJava VMプロパティを追加する
[設定例]
[foo@webotx ~]$ java -Dcom.nec.webotx.webservice.xml.rpc.client.ContentNegotiation=***value*** クライアントクラスなお、「***value***」には次のうちいずれかの値を指定します。
| 値 | 意味 |
|---|---|
| none | Fast Infoset を使用しない |
| pessimistic | レスポンスメッセージのみFast Infoset を利用する |
| optimistic | リクエストメッセージ・レスポンスメッセージの両方でFast Infoset を利用する |
JAX-RPCクライアントはサーバへの接続に関するタイムアウト時間を設定できます。 この機能を利用することで、一定時間応答のないサーバなどから強制的に切断して、次の処理に移行することができます。
タイムアウトの設定方法は3種類あります。
Memo
通常、接続タイムアウトはサーバ側の設定により制御されます。
Memo
3.の設定についてはWebOTX V8.1以前のJAX-RPCエンジンでも利用できます。
複数の設定を行った場合、以下の優先順位で設定が採用されます。複数の設定を行った場合、優先度の高いものが使用されます。優先度は高いものから以下の順になります。
java実行時にシステムプロパティとして以下を設定することで、HTTPタイムアウトの制御ができます。3.JDK標準のシステムプロパティと違い、接続するセッションで設定を行っているため他のプログラムへの影響はありません。
| システムプロパティ名 | 内容 |
|---|---|
| com.nec.webotx.webservice.http.connect.timeout | Webサービスとの接続までの待ち時間です。 |
| com.nec.webotx.webservice.http.read.timeout | Webサービスに接続してから応答を待っている時間です。 |
引数に含める単位はミリ秒です。0を設定した場合、接続を維持してサーバからの応答を待ち続けます。負の値は設定できません。負の値を設定したときは設定が無視されます。
com.nec.webotx.webservice.http.connect.timeoutはクライアントがサーバに接続してコネクションを確立するまでのタイムアウト時間です。 例えばサーバが停止している時など、接続に反応しない場合に何秒でタイムアウトするかを設定できます。
com.nec.webotx.webservice.http.read.timeoutはcom.nec.webotx.webservice.http.connect.timeoutと異なり、接続・リクエスト送信後にレスポンスが返却されるまでの待ち時間を設定できます。 リクエストを送ってもサーバの負荷が高すぎて反応がない場合、強制的に接続を切断したい場合などに利用できます。
[実行例]
[foo@webotx ~]$ java -Dcom.nec.webotx.webservice.http.connect.timeout=10000 -Dcom.nec.webotx.webservice.http.read.timeout=30000 test.Main
この例の場合、サーバへの接続待ち合わせが10秒、接続してからレスポンスメッセージを受信するまで30秒待ちます。
WebOTX Developerのウィザード、またはwscompileコマンドで生成されるStubインスタンスに対して、以下のメソッドを実行することでタイムアウト値を設定できます。
| メソッド名 | 内容 |
|---|---|
| _setConnectTimeout(int timeOut) | Webサービスとの接続までの待ち時間です。 |
| _setReadTimeout(int setReadout) | Webサービスに接続してから応答を待っている時間です。 |
引数に含めるintの単位はミリ秒です。0を設定した場合接続を維持してサーバからの応答を待ち続けます。 負の値は設定できません。負の値を設定したときは設定が無視されます。
setConnectTimeoutはクライアントがサーバに接続してコネクションを確立するまでのタイムアウト時間です。 例えばサーバが停止している時など、接続に反応しない場合に何秒でタイムアウトするかを設定できます。
setReadTimeoutはsetConnectTimeoutと異なり、接続・リクエスト送信後にレスポンスが返却されるまでの待ち時間を設定できます。リクエストを送ってもサーバの負荷が高すぎて反応がない場合、強制的に接続を切断したい場合などに利用できます。
[設定例]
MessageTest_PortType_Stub stub = (MessageTest_PortType_Stub) new MessageTest_Service_Impl().getMessageTestPort(); stub._setConnectTimeout(10000);←追記 stub._setReadTimeout(10000);←追記 stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, url); binding = (MessageTest_PortType)stub;
Caution
WebOTX V8.1以前のバージョンのWebOTX Developerで作成したソースコードを流用している場合、内容が異なるためStubインスタンスにメソッドを記述できません。設定例を参考にStubインスタンスを書きかえるか、プロジェクトを再作成してください。
java実行時にシステムプロパティとして以下を設定することで、HTTPタイムアウトの制御ができます。
| システムプロパティ名 | 内容 |
|---|---|
| sun.net.client.defaultConnectTimeout | Webサービスとの接続までの待ち時間です。 |
| sun.net.client.defaultReadTimeout | Webサービスに接続してから応答を待っている時間です。 |
引数に含める単位はミリ秒です。初期値は-1(設定なし)です。0を設定した場合接続を維持してサーバからの応答を待ち続けます。
この値の詳細はSun JDKに記載されています。「JDK 5.0
ドキュメント」-「ネットワーク機能」-「ネットワークプロパティ」
[実行例]
[foo@webotx ~]$ java -Dsun.net.client.defaultConnectTimeout=15000 -Dsun.net.client.defaultReadTimeout=20000 test.Main
この例の場合、サーバへの接続待ち合わせが15秒、接続してからレスポンスメッセージを受信するまで20秒待ちます。
Caution
これらの設定はJAX-RPCクライアントが実行されるJVM全体へ設定されます。他にHTTPプロトコルで接続するプログラムがある場合、影響を受ける場合がありますので注意してください。
例えば、JAX-RPCクライアントをServlet上で動作せる時、動作するWebOTXドメインのプロパティに設定した場合にHTTPクライアントとして動作するプログラム(Servlet, EJBなど)全体に反映されます。
Memo
<WebOTX_DIR>はWebOTXのインストールルートディレクトリのことです。
import java.io.OutputStream;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class SAAJClient {
//サービスのURLです。
private static final String URL = "http://localhost/saaj/sample";
//SOAPメッセージの作成に使用する値です。
private static final String NS = "http://sample/WebOTX"; //名前空間
private static final String PREFIX = "n"; //プレフィックス
private static final String ELEMENT1 = "data"; //要素名
private static final String ELEMENT2 = "No"; //要素名
//メインメソッド
public static void main(String[] args) throws Exception {
SAAJClient client = new SAAJClient();
//Webサービスを実行し、結果をコンソールに表示します。
//リクエストメッセージはプログラミングにより、1要素ずつ作成します。
client.invoke(client.createMessage(),System.out);
//結果表示にあたり、空白行を挿入します。
System.out.println();
System.out.println();
//Webサービスを実行し、結果をコンソールに表示します。リクエストメッセージ
//は、あらかじめSOAPBodyが記述されているXMLファイルを読み込み、作成します。
client.invoke(client.createMessage("sample.xml"),System.out);
}
//Webサービスを実行します。引数で渡されたSOAPMessageがリクエストメッセージに
//なります。
private void invoke(SOAPMessage message, OutputStream out) {
try {
//コネクションを張ります。
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection con = scf.createConnection();
//Webサービスを実行して、サービスから返されたレスポンスメッセージ
//を受け取ります。
SOAPMessage reply = con.call(message, URL);
//SOAPBodyを取り出します。
SOAPBody body = reply.getSOAPBody();
//SOAPBodyのエレメントを取り出します。
Iterator ite = body.getChildElements();
//SOAPBodyから取り出したノードをXML形式に整形して
//出力します。
while(ite.hasNext()) {
Node node = (Node) ite.next();
Source source = new DOMSource(node);
TransformerFactory factory =
TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Result output = new StreamResult(out);
transformer.transform(source, output);
}
//コネクションを閉じます。
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//SOAPMessageをSAAJプログラミングにより作成します。
private SOAPMessage createMessage() throws SOAPException {
//SOAPMessageを作成します。
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage();
//SOAPMessageからSOAPPartを取り出し、さらにSOAPEnvelopeを
//取り出します。
SOAPEnvelope env = message.getSOAPPart().getEnvelope();
//SOAPEnvelopeからSOAPBodyを取り出す
SOAPBody body = env.getBody();
//SOAPBodyに各要素を追加します。
Name name = env.createName(ELEMENT1, PREFIX, NS);
SOAPBodyElement bodyElement = body.addBodyElement(name);
name= env.createName(ELEMENT2, PREFIX, NS);
bodyElement.addChildElement(name).addTextNode("001");
//作成したSOAPMessageを返します。
return message;
}
//XMLを読み込み、SOAPメッセージを作成します。
private SOAPMessage createMessage(String filelocation) throws Exception {
//SOAPMessageを作成します。
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage();
//SOAPMessageからSOAPPartを取り出し、さらにSOAPEnvelopeを
//取り出します。
SOAPEnvelope env = message.getSOAPPart().getEnvelope();
//SOAPEnvelopeからSOAPBodyを取り出します。
SOAPBody body = env.getBody();
//DOMを使用して、SOAPBodyが記述されているXMLファイルを読み
//込み、SOAPBodyに追加します。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(filelocation);
//SOAPBodyに追加します。
body.addDocument(doc);
//作成したSOAPMessageを返します。
return message;
}
}