Spring MVC、“ add”用の1つのコントローラーおよび“更新” setDisallowedFieldsを使用する場合
-
05-07-2019 - |
質問
それで、「追加」または「追加」できるシンプルなフォームができました。新しいもの、または「更新」既存のもの。
私が望むのは、追加と更新の両方を処理できる1つのコントローラーを持つことです。 InitBinderでsetDisallowedFieldsを使用して「id」が新しいものを追加する場合、フィールドは許可されません。
現在、InitBinderメソッドを除いて同一のコードになる可能性のある2つのコントローラーがあります。
提案やアドバイスはありますか? (正当な理由を教えていただければ、2つのコントローラーも維持したいという議論を受け入れます)
解決
実際には、" 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アノテーションが必要です。
他のヒント
initBinder
へのメソッドシグネチャは、 HttpServletRequest
を受け取ります:
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder)
したがって、おそらく initBinder()
でリクエストパラメータをチェックして、条件付きで setDisallowedFields
を設定する必要があるかどうかを判断できますか?
(これで解決しない場合は、問題を正しく理解していない可能性があります...)
単一のコントローラーでこれを行う方法は、コマンドオブジェクトにブール値を付けて、それが新しいオブジェクトかどうかを示すことです。 onSubmitでは、ブール値をチェックして、追加アクションまたは更新アクションを実行する必要があるかどうかを確認できます。