|
|
WebOTX Manual V12.1 (第3版) 目次を表示 |
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 のロケーションを外部環境プロパティに設定し、切り替え可能にする場合にはチェックします。 指定したソース・フォルダーに外部環境プロパティが設定されており、なおかつ、 ウィザードの他の項目が正しく設定されている場合にチェック可能になります。 外部環境プロパティは、[開発環境の構築(WebOTX Developer) > 外部環境プロパティ]を参照してください。 詳細は、外部環境プロパティの利用 で説明します。 |
設定が完了したら、完了 ボタンをクリックします。
処理が完了すると、プロジェクトは以下の構成になります。

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 サービス参照 ノードは プロジェクト・エクスプローラー でのみ表示されます。
J2EE パースペクティブに切り替えて、プロジェクト・エクスプローラーを表示してお使いください。
呼び出したいオペレーションの下の 同期呼び出しノード、 非同期呼び出し(コールバック)ノード、 非同期呼び出し(ポーリング)ノードのいずれかを、 エディタの呼び出しコードを挿入したい場所にドラッグ&ドロップします。

ドラッグ&ドロップが完了すると、そのオペレーションを指定した方式で呼び出すのに必要なコードが生成されます。
同期呼び出しの場合:
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();
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
jakarta.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();
sample.hello.HelloService port = service.getHelloServicePort();
// TODO initialize arguments
java.lang.String arg0 = "";
jakarta.xml.ws.AsyncHandler<sample.hello.SayHelloResponse> handler = new jakarta.xml.ws.AsyncHandler<sample.hello.SayHelloResponse>() {
public void handleResponse(
jakarta.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 サービス参照に関するファイルである以下のファイルが削除されます。
ドラッグ&ドロップで生成されたサービスの呼び出しコードは削除されませんので、手動で削除してください。
いいえ をクリックした場合には、キャンセルされます。
Caution
Webサービスアプリケーションを作成する場合は環境変数に以下も追加が必要です。
・JAVA_TOOL_OPTIONS=-Dcom.nec.webotx.webservice.tools.ws.Invoker.noSystemProxies=true
Memo
<WebOTX_DIR>はWebOTXのインストールディレクトリに読み替えてください。
| ディレクトリ | ファイル |
|---|---|
| src/main/java/sample | HelloClient.java |
src> wsimport -d ../classes -s main/java -keep http://localhost/hellows/hello?wsdlwsimportコマンドの詳細に関しては、 [ コマンドリファレンス > wsimport ] を参照してください。
| ディレクトリ | ファイル |
|---|---|
| src/main/java/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 -cp %CLASSPATH%;../classes main/java/sample/HelloClient.java最後に、クライアントクラスを実行します。srcディレクトリの上のディレクトリで実行してください。
> java -cp %CLASSPATH%;classes sample.HelloClient正常に実行が完了すれば、次のような結果が出力されます。
Hello WebOTX!
| Service.Modeの値 | 説明 |
|---|---|
| MESSAGE | SOAPメッセージ全体を扱います。SourceおよびSOAPMessageを利用する場合に指定できます。 |
| PAYLOAD | SOAPメッセージの本体のみを扱います。SourceおよびJAXBを利用する場合に指定できます。 |
package sample; import java.io.StringReader; import jakarta.xml.ws.Dispatch; import jakarta.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 jakarta.xml.ws.Dispatch;
import jakarta.xml.ws.Service;
import javax.xml.namespace.QName;
import jakarta.xml.bind.JAXBContext;
import jakarta.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 jakarta.xml.soap.*;
import java.io.StringReader;
import jakarta.xml.ws.Dispatch;
import jakarta.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 = ((jakarta.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 を利用する |
Caution
Webサービスアプリケーションを作成する場合は環境変数に以下も追加が必要です。
・JAVA_TOOL_OPTIONS=-Dcom.nec.webotx.webservice.tools.ws.Invoker.noSystemProxies=true
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.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;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.Name;
import jakarta.xml.soap.SOAPBody;
import jakarta.xml.soap.SOAPBodyElement;
import jakarta.xml.soap.SOAPConnection;
import jakarta.xml.soap.SOAPConnectionFactory;
import jakarta.xml.soap.SOAPEnvelope;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage;
public class SAAJClient {
//サービスのURLです。
private static final String URL = "http://localhost/saaj_service/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"; //要素名
/**
* メインメソッド
*
* @param args
* @throws Exception
*/
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がリクエストメッセージに
* なります。
*
* @param message
* @param out
*/
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プログラミングにより作成します。
*
* @return
* @throws SOAPException
*/
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メッセージを作成します。
*
* @param filelocation
* @return
* @throws Exception
*/
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;
}
}