0

メンテナンス画面に Autoconverter (forceSelection=false) を実装しました。既存のレコードを編集するには、ユーザーはオートコンプリート リストから ID を選択します。

新しいレコードを追加するには、ユーザーは同じボックスに新しい ID を入力します。

コンバーターでは、アプリケーションは ID を使用して DB 内のレコードを検索しようとします。
見つからない場合は、指定された ID で新しい空のオブジェクトが作成され、重複を避けるために、このオブジェクトが Converter に保持されている配列リストに追加されます。

これは、単一のブラウザ セッションで期待どおりに機能します。しかし、複数のブラウザーでテストしているときに、配列リストがすべてのインスタンスで共有されていることがわかりました。

私が取ったアプローチが正しいかどうかわかりませんか?そうでない場合は、別のアプローチを提案してください。

private List<SchoolMasterDetails> schoolMasterDetailsDB = new ArrayList<SchoolMasterDetails>();


@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
SchoolMasterDetails selectedObject = null;  

System.out.println("getAsObject ==> Entering.");
System.out.println("getAsObject ==> '" + submittedValue + "'");

if (!submittedValue.trim().equals("")) {
    selectedObject = (SchoolMasterDetails) getMasterService().getSchoolbyCode(submittedValue);

    if (selectedObject == null) {
        // search Object on localDB
        for (SchoolMasterDetails p : schoolMasterDetailsDB) {
            if (p.getSchoolCode().equalsIgnoreCase(submittedValue.trim())) {
                System.out.println("getAsObject from ArrayList ==> " + p);
                return p;   // return selectedObject from list of created objects
            }
        }

        System.out.println("getAsObject ==> selectedObject is null, Hence Creating new Object");
        selectedObject = new SchoolMasterDetails();
        selectedObject.setSchoolCode(submittedValue.trim());
        selectedObject.setSchoolName("TEST TEST TEST");
        schoolMasterDetailsDB.add(selectedObject);
    }
    else {
        System.out.println("getAsObject from Database ==> " + selectedObject);
    }
}
System.out.println("getAsObject ==> " + selectedObject);
}
System.out.println("getAsObject ==> Exiting.");     
return selectedObject;
}

よろしく、

シリッシュ

4

1 に答える 1

1

私がこれを理解している限り(まだ自分自身を学んでいます)、コンバーターはまさに1つの目的を果たします:ビューで使用されるカスタムオブジェクトを準備し(getAsString)、文字列をオブジェクトに変換します(getAsObject)。入力 (ラジオ リスト、テキスト フィールド、オートコンプリート) が、カスタム オブジェクトのタイプであるバッキング Bean の変数に関連付けられている場合は常に使用されます。オブジェクトを表すためにどの文字列を使用するか、およびオブジェクトを検索するためにこの文字列をどのように使用するかを自由に決定できます。

これを念頭に置いて、コンバーターを使用してオブジェクトのローカル リストを格納したり、コンバーターに作成プロセス自体を処理させたりしません。代わりに、データ オブジェクトを保持し、すべてのロジックを処理するバッキング Bean がどこかにあると仮定します。この Bean は、たとえば、含まれているオブジェクトを照会できる schoolMasters のリストを持つことができます (あなたがしていることと同様です)。次に、見つからないケースを処理し、常に有効なオブジェクト (新しいオブジェクトである可能性があります) を返す方法でルックアップを実装するか、コンバーターで見つからないケースをキャッチしてからトリガーすることができます。 acreateNew()を Bean から取得して、新しいインスタンスを取得します。

IMHOこれにより、インスタンスの管理がコンバーターの翻訳目的からより明確に分離されます。また、あなたのコードから、オブジェクトを検索する場所が 2 つあるようgetMasterService()ですArrayList。これはよくわかりません...


インスタンスを共有するブラウザーに関する問題については、スコープの問題のように聞こえます。データを保存および管理することになっているバッキング Bean がアプリケーション スコープ内にある場合、アプリケーションが実行されている限り、同じデータ セットを使用できます。このデータは、ブラウザ間およびユーザー間で利用できます。

一方、Bean をセッション スコープに配置すると、各セッションは Bean の独自のインスタンスを作成し、一意のデータを格納します。同様に、単一のビュー Bean とリクエスト Bean が破棄され、http リクエストごとに再生成される限り、ビュー スコープ Bean は有効です。ここで詳細を読むことができます:適切なスコープを選択する方法

そこにある答えは、Bean (データが通常存在する場所) について語っています。コンバーターについてはよくわかりません。コンバーターはアプリケーション全体で利用できるクラスと見なしているため、各セッションとビューで変換に使用できます。リストをそこに維持すると、グローバルに利用できる可能性があります。

于 2012-10-25T10:07:13.347 に答える