1

私たちのアプリケーションは Wicket フロントエンドを使用し、Spring インジェクションを使用して DOA をロードし、トランザクションを管理します。

何人かのユーザーがリンク/ボタンをダブルクリックしており、これが何らかの形で Spring インジェクションを妨害していることを発見しました。そのため、その後のwhateverDao.doStuff(obj) への呼び出しで NPE がスローされます。このアプリケーションは、クライアントの内部ネットワークで実行され、今のところ、ワンクリックですべての機能が機能することをチーム内で広めるよう、クライアントに丁寧に依頼しました。しかし、これが彼らにとって問題になりつつあることは明らかです。

一般的なユースケースには、現在システム内にあるすべての Foo オブジェクトのリストを表示する「検索」画面が含まれます。これは、必要に応じて検索パラメーターを使用してフィルター処理できます。アイテムをクリックすると、ユーザーはその特定の Foo の詳細ページに移動します。 、最初は読み取り専用モードです。次に、ユーザーは隅にある「編集」ボタンをクリックして、編集モードに切り替えることができます。次に、ユーザーはいくつかの変更を加えて [保存] をクリックします (または、[削除] をクリックしてアイテムを削除することもできます)。

このシナリオには、最大 3 つのステップでの DAO 呼び出しが含まれます。 1. 検索ページで、アイテムがクリックされたときに、そのアイテムの基本的な詳細をロードします。2. 読み取り専用モードの詳細ページで、[編集] をクリックすると、そのアイテムの完全な詳細が読み込まれます。3a. 編集モードの詳細ページで、[保存] をクリックすると、変更が保持されます。3b. 編集モードの詳細ページで、削除をクリックすると削除されます。

これらのいずれの場合でも、ユーザーがのステップをダブルクリックすると、次のステップでエラーが発生します。再現性は、ブラウザや OS によって多少のばらつきがありますが、約 33% です。

これを防ぐための洞察はありますか?


以下のサンプルでは、​​BasePage はメニューやその他の一般的なページ要素を含む Wicket の WebPage のカスタム拡張であり、PageType は CREATE、EDIT、および READ_ONLY の詳細の列挙です。

検索ページのサンプル コード (Java が表示されています。HTML は想定どおりです):

import org.apache.wicket.spring.injection.annot.SpringBean;
// and other imports

public class FooManagerPage extends BasePage {

    @SpringBean
    private transient FooDao fooDao;

    public FooManagerPage() {
        SortableDataProvider<Foo> provider = new SortableDataProvider<Foo>(fooDao);

        add(new FeedbackPanel("feedback");

        final Form<Foo> searchFooForm = new Form<Foo>("searchFooForm",
            new CompoundPropertyModel<Foo>(new Foo()));

        // the form's search parameter's go here
        // with a 'search' button that filters table below

        add(searchFooForm)

        List<IColumn<Foo>> columns = new ArrayList<IColumn<Foo>>();
        columns.add(new PropertyColumn<Foo>(Model.of("Name"), "name", "name"));
        // a couple other columns here

        DataTable fooTable = new AjaxFallbackDefaultDataTable<Foo>("fooTable", columns, provider, 10){
            @Override
            protected Item<Foo> newRowItem(String id, int index, final IModel<Foo> model){
                Item<Foo> item = super.newRowItem(id, index, model);
                item.add(new AjaxEventBehavior ("onclick") {
                    @Override
                    protected void onEvent(AjaxRequestTarget target) {
                        Foo foo = fooDao.load(model.getObject().getId());
                        setResponsePage(new FooViewPage(foo, PageType.READ_ONLY));
                    }
                }); 
                return item;
            }
        };

        add(fooTable);
    }
}

ビュー ページのサンプル コード (Java が示されています。HTML は想定どおりです)::

// several imports, including Spring Bean
public class FooFormPage extends BasePage {

    @SpringBean
    private transient fooDao fooDao;

    public FooFormPage(final Foo foo, PageType type) {
        Form<Foo> fooForm = new Form<Foo>("fooForm",
            new CompoundPropertyModel<Foo>(foo));

        // all of Foo's input elements go here
        // are enabled or disabled and sometimes invisible based on PageType

        add(fooForm);

        SubmitLink submitButton = new SubmitLink("save", fooForm){
            @Override
            public void onSubmit() {
                super.onSubmit();
                //***** A double click on the Edit button can cause fooDao to be N.P.E. here *****
                fooDao.save(createInitiativeForm.getModelObject().getId());
                changePageType(PageType.VIEW, createFooForm.getModelObject());
            }
        };
        add(submitButton);

        AjaxLink<Void> editButton = new AjaxLink<Void>("edit"){
            @Override
            public void onClick(AjaxRequestTarget target) {
                // reload the item from DB
                //***** A double click on Search Page item will cause fooDao to be N.P.E. here *****
                Foo foo = fooDao.load(fooForm.getModelObject().getId());
                setResponsePage(new FooPage(foo, PageType.EDIT));
            }
        };
        add(editButton);

        // some stuff here that makes save button invisible in READ_ONLY, and Edit visible only in READ_ONLY
        // delete button is similar (visible only in CREATE)
    }
}
4

1 に答える 1

7

依存関係フィールドは としてマークするべきではなくtransient、ページに沿ってシリアル化する必要があります。このwicket-springモジュールは、コンポーネント/ページの作成時にシリアライズ可能なプロキシを@SpringBeanアノテーション付きフィールドに挿入するため、依存関係自体のシリアライズを心配することなく、安全にシリアライズできます。

于 2012-06-11T19:06:02.577 に答える