ヘッダーをスキップ

Oracle® Fusion Middleware Oracle Mobile Application Frameworkでのモバイル・アプリケーションの開発 2.0.1 E57592-01 |
| 目次

前 | 次 |

# 18 MAFアプリケーションでのエラー処理

この章では、`AdfException`クラスを使用してエラーを処理する方法とエラー・メッセージをローカライズする方法について説明します。

この章の内容は次のとおりです。

- 第18.1項「MAFのエラー処理について」

- 第18.3項「エラー・メッセージのローカライズ」

- 第18.2項「エラー・メッセージの表示およびバックグラウンド・スレッドの停止」

## 18.1 MAFのエラー処理について

モバイル・アプリケーションから発生するエラーは、リモート・サーバーへの接続の失敗のように予期しないものである場合と、アプリケーション・ビジネス・ルールの違反のように予期されるものである場合があります。エラーまたは例外は、プライマリ・リクエスト・スレッド内またはバックグラウンド・タスクで実行されるセカンダリ・スレッド内で発生する可能性があります。アプリケーションで複数言語がサポートされている場合、エラー・メッセージはユーザーの言語で表示される必要があります。

モバイル・アプリケーションから例外をスローできるようにするには、`oracle.adfmf.framework.exception.AdfException`クラスを使用します。詳細は、Oracle Fusion Middleware Oracle Mobile Application Framework Java APIリファレンスを参照してください。

次のコードにより、MAFで例外を正常に処理できるようになります。図18-1に示すようなポップアップ・メッセージがアプリケーション内に表示され、メッセージの重大度と説明テキストが示されます。

    throw new AdfException("My error message",AdfException.ERROR);

図18-1 エラー・メッセージ

注意: マネージドBeanまたはデータ・コントロールBean内で例外がスローされると、アプリケーション内に類似のエラー・メッセージが表示されます。

## 18.2 エラー・メッセージの表示およびバックグラウンド・スレッドの停止

例18-1に示す`MessageUtils`クラスを使用すると、アプリケーションで、まずJavaScriptコール(`invokeContainerJavaScriptFunction`)を呼び出してから例外をスローすることで、スレッドを停止してエラーを表示できるようになります。`addMessage`メソッドは、エラーを表示できるようにします。詳細は、第18.2.1項「アプリケーションによるバックグラウンド・スレッド例外のエラー・メッセージの表示方法」を参照してください。また、第B.2.14項「invokeContainerJavaScriptFunction」も参照してください。

`MessageUtils`クラスは`BundleFactory`および`Utility`メソッドを使用してリソース・バンドルおよびエラー・メッセージを取得し、バックグラウンドでスレッドが実行されているかどうかを動的にチェックします。このクラスを使用すると、メイン・スレッドからバックグラウンド・スレッドにコードを移動できます。

例18-1 MessageUtilsクラス

    package oracle.errorhandling.demo.mobile;

    import java.util.ResourceBundle;

    import oracle.adfmf.framework.api.AdfmfContainerUtilities;
    import oracle.adfmf.framework.api.AdfmfJavaUtilities;
    import oracle.adfmf.framework.exception.AdfException;
    import oracle.adfmf.util.BundleFactory;
    import oracle.adfmf.util.Utility;

    public class MessageUtils {

       public static void handleError(AdfException ex) {
          handleMessage(ex.getSeverity(), ex.getMessage());
       }

       public static void handleError(String message) {
          handleMessage(AdfException.ERROR, message);
       }
       public static void handleError(Exception ex) {
          handleMessage(AdfException.ERROR, ex.getLocalizedMessage());
       }

       public static void handleMessage(String severity, String message) {
          if (AdfmfJavaUtilities.isBackgroundThread()) {
             AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                                                       getFeatureName(),
                                                                       "adf.mf.api.amx.addMessage",
                                                                       new Object[] {severity,
                                                                                     null,
                                                                                     null});
             if (AdfException.ERROR.equals(severity)) {
                // we still need to throw execption to stop background thread processing
                throw new AdfException(message,severity);
             }
          }
          else {
             throw new AdfException(message,severity);
          }
       }

       public static void addJavaScriptMessage(String severity, String message) {
          AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                                                    getFeatureName(),
                                                                    "adf.mf.api.amx.addMessage",
                                                                    new Object[] {severity,
                                                                                  message,
                                                                                  null,
                                                                                  null });
       }

    }

### 18.2.1 アプリケーションによるバックグラウンド・スレッド例外のエラー・メッセージの表示方法

アプリケーションは、バックグラウンド・スレッドに対して例外がスローされたときにエラー・メッセージを表示しません。このような状況でエラー・メッセージを表示できるようにするために、アプリケーションは`addMessage`メソッドをコールします。`addMessage`メソッドは次のパラメータを取ります。

- エラーの重大度

- サマリー・メッセージ

- 詳細メッセージ

- `clientComponentId`

例18-2は、`addMessage`メソッドを使用して、バックグラウンドでエラーが発生したときにアプリケーションがユーザーにアラートを出せるようにする方法を示しています。

例18-2 バックグラウンド・スレッドのエラー・メッセージの表示の許可

    Runnable runnable = new Runnable()
    {
      public void run() {
        AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.getFeatureName(),
          "adf.mf.api.amx.addMessage", new Object[] {AdfException.ERROR,
                                                     "My error message for background thread",
                                                     null,
                                                     null });
      }
    };
    Thread thread = new Thread(runnable);
    thread.start();

`adf.mf.api.amx.addMessage` JavaScript関数は、アプリケーションがプライマリ・リクエスト・スレッドで`AdfException`をスローするときに使用されるメソッドと同じであるため、エラー・メッセージがメイン・スレッドの例外またはバックグラウンド・スレッドからの例外のいずれを参照しているかにかかわらず、ユーザーは同じポップアップ・エラー・メッセージを受け取ります。

注意: 例18-2に示すとおり、詳細メッセージおよび`clientComponentId`は`Null`値にすることができます。詳細メッセージは、サマリー・メッセージと同じフォント・サイズで、新しい行に表示されます。

ただし、例18-3に示されているように、バックグラウンド・スレッドで実行されるJavaロジック内にコードを配置すると、エラー・メッセージを表示しないようにできます。例18-4に示すメソッドを使用すると、ユーザーに通知せずにバックグラウンド・スレッドをサイレントに停止できます。

例18-3 エラー・メッセージの表示の防止

    Runnable runnable = new Runnable()
    {
      public void run()
      {
        // this exception will be lost because no popup error message will display in the mobile application
        throw new AdfException("My (lost) error message in background",AdfException.ERROR);
      }
    };
    Thread thread = new Thread(runnable);
    thread.start();

## 18.3 エラー・メッセージのローカライズ

MAFは標準Javaリソース・バンドルを使用して、アプリケーション・ユーザーの言語で例外エラー・メッセージを表示します。例18-4に示すとおり、リソース・バンドル名(`.xlf`ファイル)およびバンドル・メッセージ・キーが`AdfException`コンストラクタ・メソッドに渡され、リソース・バンドルからエラー・メッセージを読み取ることができるようになります。

例18-4 リソース・バンドル名およびメッセージ・キーのAdfExceptionコンストラクタ・メソッドへの引渡し

    private static final String XLF_BUNDLE_NAME="oracle.errorhandling..mobile.ViewControllerBundle";
       throw new AdfException(AdfException.ERROR, XLF_BUNDLE_NAME,
                                                 "MY_ERROR_MESSAGE",
                                                  null);

アプリケーションが`MissingResourceException`エラーをスローしないようにするには、`oracle.adfmf.util.BundleFactory`メソッドを使用してリソース・バンドルを取得してから、`oracle.adfmf.util.Utility`メソッドを使用してエラー・メッセージを取得します(例18-5を参照)。

例18-5 BundleFactoryおよびUtilityメソッドを使用したリソース・バンドルおよびエラー・メッセージの取得

    ResourceBundle bundle = BundleFactory.getBundle(XLF_BUNDLE_NAME);
    String message = Utility.getResourceString(bundle, "MY_ERROR_MESSAGE",null);
    throw new AdfException(message,AdfException.ERROR);

例18-6は、`adf.mf.api.amx.addMessage` JavaScript関数を使用して、バックグラウンド・スレッドから例外がスローされたときにローカライズされたエラー・メッセージを表示する方法を示しています。

例18-6 バックグラウンド例外のローカライズ済エラー・メソッドの表示

    ResourceBundle bundle = BundleFactory.getBundle(XLF_BUNDLE_NAME);
    String message = Utility.getResourceString(bundle, "MY_ERROR_MESSAGE_BG",null);
    AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                                              getFeatureName(),
                                                              "adf.mf.api.amx.addMessage",
                                                               new Object[] {AdfException.ERROR,
                                                                                          message,
                                                                                          null,
                                                                                          null });