Ymirでは、Pageコンポーネントのアクションを呼び出す際に満たしておく必要がある条件のことを「制約」と呼びます。
制約には次のものがあります。
- リクエストパラメータに関する制約
- アクセス権限(permission)に関する制約
Ymirでは前者をチェックすることを「バリデーション」、後者をチェックすることを「権限チェック」と呼びます。
制約の指定
制約はアノテーションとして指定することができます。
指定できる箇所はクラス宣言、リクエストパラメータをセットするためのSetterメソッド、アクションメソッドです。なお、権限チェックのためのアノテーションは通常クラスまたはアクションに指定して下さい。
アクションの種類に関わらずいつでも行ないたい制約チェックについては、クラス宣言にアノテーションを付与して下さい。
アクションの種類に関わらずいつでも制約チェックを行ないたいリクエストパラメータがあれば、そのリクエストパラメータをセットするためのSetterメソッドにアノテーションを付与して下さい。
あるアクション呼び出しの時にだけ行ないたい制約チェックについては、対応するアクションメソッドにアノテーションを付与して下さい。
複数のページに関して一括して行ないたい制約チェックについては、後述するConstraintBundleを使って指定して下さい。
複数のアノテーションを指定した場合は次の順序で制約チェックが行なわれます。
- ConstraintBundleを使って指定されたアノテーション
- クラスに付与されたアノテーション
- Setterに付与されたアノテーション
- アクションメソッドに付与されたアノテーション
SuppressConstraintsアノテーション
あるアクションの呼び出しの時だけはある制約種別に関するチェックを抑制したい場合はorg.seasar.ymir.constraint.annotaion.SuppressConstraintsアノテーションをアクションメソッドに付与して下さい。
SuppressConstraintアノテーションには制約種別を表すorg.seasar.ymir.constraint.ConstraintTypeの値を1つまたは複数指定することができます。抑制したい制約種別に対応するConstraintType値を指定して下さい。指定された制約種別の制約に関するチェックは全て抑制されるようになります。
例外として、ConstraintBundleで指定された制約は自動的には抑制されません。ConstraintBundleで指定された制約をSuppressConstraintsアノテーションで抑制したい場合は、ConstraintBundle#isConfirmed()の中で明示的に行なうようにして下さい。以下はSuppressConstraintsアノテーションに従って抑制するisConfirmedメソッドの例です:
public boolean isConfirmed(Object page, Request request, ConstraintType type, Set<ConstraintType> suppressTypeSet) { if (suppressTypeSet.contains(type)) { return false; } .... }
処理の詳細
制約のチェックはPageコンポーネントへの依存コンポーネントやリクエストパラメータがセットされた後、アクション呼び出しの前に行なわれます。制約のチェックに失敗すると、アクションを呼び出す代わりに制約の種別ごとの処理が行なわれます。それぞれの制約種別における処理の詳細は各制約種別のドキュメントを参照して下さい。
なお、権限チェックはバリデーションよりも優先されます。すなわち権限チェックに失敗した時点でバリデーションチェックはそれ以上行なわれず、今まで行なったバリデーションチェックに関する情報は破棄されます。
ページ横断的な制約チェック
例えば全てのページのPOST系アクションについて、トランザクショントークンの存在チェックをしたい場合など、複数のページに関して一括して制約チェックを行ないたい場合は、ConstraintBundleを使います。
具体的には、org.seasar.ymir.constraint.ConstraintBundleインタフェースの実装クラスを作成し、それのコンポーネント定義をapp.diconに追加します。
ConstraintBundle実装クラスのisConfirmedメソッドがtrueを返す場合、ConstraintBundle実装クラスに付与されているアノテーションが有効になり、制約チェックが行なわれます。
以下は、全てのページのPOST系アクションについて、トランザクショントークンの存在チェックを行なうためのConstraintBundleの例です:
@TokenRequired public class TokenRequiredConstraintBundle implements ConstraintBundle { public boolean isConfirmed(Object page, Request request, ConstraintType type, Set<ConstraintType> suppressTypeSet) { return request.getMethod() == HttpMethod.POST; } }