40.6. リモートサービスから返された例外をキャッチする
概要
非同期リクエストを行うコンシューマーは、同期リクエストを行うときに返されるのと同じ例外を受け取りません。非同期でコンシューマーに返される例外はすべて、ExecutionException 例外にラップされます。サービスによって出力される実際の例外は、ExecutionException 例外の cause
フィールドに保存されます。
例外をキャッチする
リモートサービスによって生成された例外は、コンシューマーのビジネスロジックに応答を渡すメソッドによってローカルに出力されます。コンシューマーが同期要求を行うと、リモート呼び出しを行うメソッドが例外を出力します。コンシューマーが非同期リクエストを行う場合、Response<T> オブジェクトの get()
メソッドが例外を出力します。コンシューマーは、応答メッセージを取得しようとするまで、要求の処理中にエラーが発生したことを検出しません。
JAX-WS フレームワークによって生成されるメソッドとは異なり、Response<T> オブジェクトの get()
メソッドは、ユーザーがモデル化した例外や汎用 JAX-WS 例外を出力しません。代わりに、java.util.concurrent.ExecutionException 例外を出力します。
例外の詳細を取得する
フレームワークは、リモートサービスから返された例外を ExecutionException 例外の cause
フィールドに保存します。リモート例外の詳細は、cause
フィールドの値を取得し、保存した例外を調べて抽出されます。保存される例外は、任意のユーザー定義の例外または一般的な JAX-WS 例外の 1 つです。
例
例40.11「ポーリングアプローチを使用して例外をキャッチする」 は、ポーリングアプローチを使用して例外をキャッチする例を示しています。
例40.11 ポーリングアプローチを使用して例外をキャッチする
package demo.hw.client; import java.io.File; import java.util.concurrent.Future; import javax.xml.namespace.QName; import javax.xml.ws.Response; import org.apache.hello_world_async_soap_http.*; public final class Client { private static final QName SERVICE_NAME = new QName("http://apache.org/hello_world_async_soap_http", "SOAPService"); private Client() {} public static void main(String args[]) throws Exception { ... // port is a previously established proxy object. Response<GreetMeSometimeResponse> resp = port.greetMeSometimeAsync(System.getProperty("user.name")); while (!resp.isDone()) { // client does some work } try { GreetMeSometimeResponse reply = greetMeSomeTimeResp.get(); // process the response } catch (ExecutionException ee) { Throwable cause = ee.getCause(); System.out.println("Exception "+cause.getClass().getName()+" thrown by the remote service."); } } }
例40.11「ポーリングアプローチを使用して例外をキャッチする」 のコードは、以下を行います。
Response<T> オブジェクトの get()
メソッドへの呼び出しを try/catch ブロックにラップする。
ExecutionException 例外をキャッチします。
例外から cause
フィールドを抽出する。
コンシューマーがコールバックアプローチを使用している場合、例外をキャッチするために使用されるコードは、サービスの応答が抽出されるコールバックオブジェクトに配置されます。