2

私は最近、スレッドを実装するために内部クラスを多用するいくつかのレガシー コードを継承しました。これらの内部クラスは現在のJFrameコードをモノリシックにするため、クラスを利用するためにコードをリファクタリングしている最中ですSwingWorker

SwingWorkerのクラスは、Web サービスに対して多数の API 呼び出しを行い、結果を返します。これは非同期であるため、明らかにスレッド内で実行するのが最適です。現在、Web サービスが機能する方法では、リクエストを検証するためにいくつかの認証呼び出しが必要です。これらの呼び出しは明らかにエラーを返す可能性があります。私がやりたいことはSwingWorker、これらの Web サービス呼び出しが認証されない場合に、内部からカスタム例外をスローすることです。標準Futureパターンを使用すると、次のようなコードになります。

SwingWorker (バックグラウンド スレッド)

@Override
protected String doInBackground() throws Exception {
    if (!authenticationClient.authenticate(userid)) {
        throw new PlaceOrderException("Failed to authenticate client");
    }

    return orderClient.placeOrder( ... );
}

メイン GUI (EDT スレッド)

// On the EDT
PlaceOrderWorker placeOrderWorker = new PlaceOrderWorker( ... ) {
    // This method is invoked when the worker is finished its task
    @Override
    protected void done(){
        try {
            String orderID = get();

            // Update some GUI elements using the orderID

        } catch(PlaceOrderException e) {
            JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
        } catch (Exception e) {
            LOGGER.error("Error placing order", e);
        }
    }
}

エラーは次の行で発生します。

catch(PlaceOrderException e) {
    JOptionPane.showMessageDialog(this, "Please review your order", e.getMessage(), JOptionPane.ERROR_MESSAGE, null);
} 

Java は、この例外がスローされないと主張しているためです。

exception PlaceOrderException is never thrown in body of corresponding try statement

getこれで、呼び出しによって例外がスレッドから再スローされることがわかりましたPlaceOrderException。この特定の例外をキャッチするにはどうすればよいですか? コードをそのように構成した理由は、バックグラウンド スレッドでスローされる可能性のある例外が多数あるためJDialogです。doneメイン GUI クラス内でメソッドを宣言している理由はJDialog、EDT スレッド内から s をインスタンス化する必要があるためです。これにより、適切なデカップリングが可能になります。

を使用してこの特定の例外をキャプチャする方法を知っている人はいinstanceofますか? または、使用するより良いパターンを提案できますか? もしかしてSwingWorker選択ミス?

4

1 に答える 1

6

その原因をキャッチExecutionExceptionして調査します。

    try {
        String orderID = get();

        // Update some GUI elements using the orderID

    } catch(ExecutionException e) {
        Throwable cause = e.getCause( );
        if ( cause instanceof PlaceOrderException )
        {
            JOptionPane.showMessageDialog(
              this,
              "Please review your order",
              cause.getMessage(),
              JOptionPane.ERROR_MESSAGE,
              null
            );
        }
        else
        {
          LOGGER.error("Error placing order", e);
        }
    } catch (Exception e) {
        LOGGER.error("Error placing order", e);
    }
于 2012-11-29T23:16:49.297 に答える