[CUBBY-93] バリデーションのタイミング指定 Created: 2008-02-20  Updated: 2009-07-05  Resolved: 2008-03-24

Status: Closed
Project: Cubby
Component/s: Core
Affects Version/s: None
Fix Version/s: 1.1.0-rc1

Type: New Feature Priority: Major
Reporter: baba Assignee: baba
Resolution: Fixed Votes: 0
Labels: None


 Description   

いまのバリデーションはアクションメソッドの呼出しをフックしてバリデーションをかけていますが、これを「バインド前」と「バインド後」に分けて、指定した方でバリデーションするようにしたいです。

たとえば、TODOアプリのLoginActionのバリデーションは

  • リクエストパラメータのバインド
  • リクエストパラメータ(userIdとpassword)のバリデーションとユーザーの存在チェック、エラーならエラーページへ
    という動きになっています。
    エラーの出方を考えると、まず
  • userIdとpasswordのバリデーション、エラーならエラーページへ
    というリクエストパラメータのバリデーションがあって、そこでエラーがなければ
  • リクエストパラメータのバインド
  • 指定されたユーザーの存在チェック、エラーならエラーページへ
    という順番で動くのが妥当かと思います。

以下のような方法で指定できるといいかと思っています。
DefaultValidationRulesの

  • addメソッド(引数 Validator)
    • リクエストパラメータのバリデーションなので、タイミングは「バインド前」だけでよさそう。
  • addメソッド(引数 ValidationRules)
    • 引数を追加して、「バインド前」か「バインド後」かを指定できるようにする。
    • デフォルトは「バインド後」

独自のValidationRuleを使うアプリに適用すると、従来の動きとすこし異なってしまうのが気になります。



 Comments   
Comment by baba [ 2008-03-24 ]

ドキュメントに反映しました。

Comment by baba [ 2008-03-21 ]

バリデーションコピーはgetRules()を使う方法だとフェーズごとのバリデーションをうまく表現できないので、DefaultValidationrules#addAll(ValidationRules)を追加して、#getRules()はdeprecatedに指定しました。

Comment by baba [ 2008-03-20 ]

あとはドキュメントに反映させる

Comment by baba [ 2008-03-20 ]

cubby r882
cubby-examples r883
で対応しました。
URIに埋め込まれたパラメータなどは、バリデーションの成否に関わらずフォームオブジェクトにバインドされていて欲しいです。(JSPの表示や画面遷移で使う場合があります)
なので、シーケンスは1.0と変えずに

  • リクエストパラメータのバインド
  • フェーズごとのバリデーション
  • アクションメソッドの実行
    としました。

サンプルとして、cubby-examplesのtodo/action/LoginActionを参照してください。

フェーズごとのバリデーション
ValidationRule登録時に指定されたフェーズ(ValidationPhaseのインスタンス)ごとにバリデーションを順次実行し、そのフェーズ内でエラーがあった場合は次のフェーズのバリデーションは実行せずにエラーページへと遷移します。

定義済みのフェーズとして、以下の2つを DefaultValidationRules に追加しました。

  • データ型を検証するフェーズ (DATA_TYPE)
  • データ上の制約を検証するフェーズ (DATA_CONSTRAINT)
    RequiredValidatorなどは DATA_TYPE、ユーザーが定義する相関チェックやテーブルを参照するようなバリデーションは DATA_CONSTRAINT を想定しています。

フェーズはValidationRules#getValidationPhases() をオーバーライドすることでカスタマイズできます。

また、ValidationExceptionを追加しました。
アクションメソッド中でこの例外がスローされるとエラーページへ遷移します。

Comment by baba [ 2008-02-21 ]

>これ素朴な疑問なんですが、バインドの動きをオーバーライドしたい場面ってありますかね?
バインドのとことRequestParserでパースしてるところ、そのあたりをオーバーライドできるとRESTでapplication/atom+xmlみたいなブラウザ以外からのリクエストに対応しやすくなるかもなー、っていうくらいですね。
RESTについて詳しくないんでなんとも言えないんですが、どうなんでしょうか?

それと、バリデーションを途中でやめたい場合もあると思うので、ある例外が投げられたらバリデーションを中断してエラーページへ遷移する、っていう動きもつけたいですね。

Comment by agata [ 2008-02-20 ]

検証の2回に分けてやるのは賛成です。本来そういう動きが正しいと思いますので。

>1.のほうが、Actionのサブクラスでバインドの動きをオーバーライドできたりするのでよいかなー

2が普通ありそうな実装方法ですよねー。
これ素朴な疑問なんですが、バインドの動きをオーバーライドしたい場面ってありますかね?

Comment by baba [ 2008-02-20 ]

実装する方法は2つを考えました。

  1. リクエストパラメータからフォームオブジェクトへバインドする部分をAction抽象クラスに移動してメソッドを作成し、そこをValidationInterceptorでフックしてバインドメソッド実行の前後でバリデーションを実行する。
  2. Interceptorを増やす
    • アクションの初期化Interceptor
    • バインド前バリデーションInterceptor
    • リクエストパラメータをフォームオブジェクトにバインドするInterceptor
    • バインド後バリデーションInterceptor
    • アクションメソッドを実行するInterceptor

2.のほうはフレームワークとしては柔軟な気がしますが、1.のほうが、Actionのサブクラスでバインドの動きをオーバーライドできたりするのでよいかなー、と思ってます。

みなさん、ご意見をください。

Generated at Thu Apr 25 05:03:50 JST 2024 using Jira 9.15.0#9150000-sha1:9ead8528714127d8cfabf2446010d7e62c0a195c.