3

これで、新しい Thing を「追加」するか、既存の Thing を「更新」できる単純なフォームができました。

私が望むのは、追加と更新の両方を処理できる 1 つのコントローラーを持つことです。新しいモノを追加するときに「id」フィールドが許可されないように、InitBinder で setDisallowedFields を使用する問題を検討するまでは、これは最初は簡単に思えます。

現在、InitBinder メソッドを除いて同一のコードである可能性のある 2 つのコントローラーがあります。

提案やアドバイスはありますか?(正当な理由を教えていただければ、2つのコントローラーも維持したいという議論にオープンです)

4

3 に答える 3

4

実際には、追加時と更新時の両方で「id」フィールドを禁止する必要があります。そうしないと、悪意のあるユーザーが更新リクエストの「id」リクエスト パラメータの値を改ざんし、フォームに示されているレコードとは異なるレコードを更新する可能性があります (ACL やその他のドメイン レベルのセキュリティがない場合)。

ただし、単に「id」フィールドを許可しない場合、コントローラーは ID を null として扱います。これは、挿入時には機能しますが、更新時には機能しません (たとえば、どの永続化メカニズムに応じて、更新ではなく新しいレコードを挿入しようとする場合があります)。使用しています)。そのため、コントローラーがドメイン オブジェクトの編集不可能な値 (ID だけでなく、許可されていないすべてのフィールド) をリクエスト間で記憶して、すべての正しい値をサービス レイヤーまたは他のビジネス ロジックに送信できるようにする必要があります。これは、次のように型レベルの @SessionAttributes アノテーションを使用して行われます (明確にするために他のアノテーションは省略されています)。

@SessionAttributes("thing") // the name of your domain object in the model
public class ThingController {

    public void setDisallowedFields(WebDataBinder binder) {
        binder.setDisallowedFields("id", "someOtherUneditableField");
    }

    // request handling methods go here as before
}

セキュリティをさらに強化するには、許可されていないフィールドではなく許可されたフィールドを設定します。いずれにせよ、リクエストから無視される既存のフィールド値を埋めるために @SessionAttributes アノテーションが必要です。

于 2010-02-11T01:29:31.480 に答える
2

へのメソッド シグネチャinitBinderは、次のものを受け取りますHttpServletRequest

protected void initBinder(HttpServletRequest request, 
    ServletRequestDataBinder binder)

おそらくinitBinder()、リクエストパラメータをチェックして、条件付きで設定する必要があるかどうかを判断できますsetDisallowedFieldsか?

(これで解決しない場合は、問題を正しく理解していない可能性があります...)

于 2009-05-05T18:59:36.533 に答える
1

単一のコントローラーでこれを行う方法は、コマンド オブジェクトにブール値を設定して、それが新しいオブジェクトかどうかを示すことです。onSubmit では、ブール値をチェックして、追加または更新アクションを実行する必要があるかどうかを確認できます。

于 2009-05-06T07:35:57.527 に答える