Webアプリケーションを作成する場合は、オブジェクトの有効範囲(スコープ)を上手に扱うことが重要になってきます。
サーブレットの世界にはスコープとしてrequestスコープ、sessionスコープ、applicationスコープなどがあります。Ymirでもこれらのスコープにオブジェクトをバインドしたりスコープからオブジェクトを取り出したりすることができますが、サーブレットAPIを直接使わずにスコープに関する操作が行なえるようになっています。
具体的には、スコープからオブジェクトを取り出したい場合はorg.seasar.ymir.annotation.Inアノテーションを付与したsetterメソッドを用意します。以下の例は、sessionスコープに「value」というキーでバインドされているオブジェクトを取得するためのコードです。
@In(SessionScope.class)
public void setValue(Object value)
{
value_ = value;
}
なお、対応するキーでバインドされているオブジェクトが存在しない場合は通常setterメソッドは呼び出されません。オブジェクトが存在しない場合にもsetterメソッドを呼び出したい場合は@Inアノテーションに「injectWhereNull=true」というプロパティを追加して下さい。
オブジェクトをスコープにバインドしたい場合はorg.seasar.ymir.annotation.Outアノテーションを付与したgetterメソッドをPageクラスに用意します。以下の例は、sessionスコープに「value」という名前でgetterメソッドの返り値をバインドするためのコードです。
@Out(SessionScope.class)
public Object getValue()
{
return value_;
}
オブジェクトをスコープからアンバインドしたい場合はgetterメソッドがnullを返すようにして下さい。getterメソッドがnullを返す場合にオブジェクトをスコープからアンバインドしたくない場合は@Outアノテーションに「outjectWhereNull=false」というプロパティを追加して下さい。
@Inアノテーションに従ったオブジェクトの取り出しはPageオブジェクトへのリクエストパラメータのインジェクトの後、制約チェックの前に行なわれます。@Outアノテーションに従ったオブジェクトのバインディングはアクションの呼び出しの後(_renderメソッドの呼び出しがあればその後)に行なわれます。
オブジェクトスコープからのオブジェクトの取り出しとオブジェクトスコープへのオブジェクトのバインディングはどのアクション呼び出しに関しても常に行なわれますが、@Inアノテーションや@Outアノテーションに「actionName」プロパティを指定することで、特定のアクションの時だけ行なわせることもできます。
@Out(scopeClass = SessionScope.class, actionName = { "_post", "_post_done" })
public Object getValue()
{
return value_;
}
上の例では、リクエストが_postアクションまたは_post_doneアクションを呼び出すケースのみgetValue()の値がセッションスコープにバインドされます。
利用できるScopeクラスには以下のものがあります。
- org.seasar.ymir.scope.impl.RequestScope
- requestスコープ。オブジェクトの操作はHttpServletRequest#getAttribute()、HttpServletRequest#setAttribute()、HttpServletRequest#removeAttribute()によって行なわれます。
- org.seasar.ymir.scope.impl.SessionScope
- sessionスコープ。オブジェクトの操作はHttpSession#getAttribute()、HttpSession#setAttribute()、HttpSession#removeAttribute()によって行なわれます。オブジェクトをバインドする際にセッションが存在しない場合はセッションを生成してからバインドします。オブジェクトを取り出す際にセッションが存在しない場合は取り出した結果はnullになります。
- org.seasar.ymir.scope.impl.ApplicationScope
- applicationスコープ。オブジェクトの操作はServletContext#getAttribute()、ServletContext#setAttribute()、ServletContext#removeAttribute()によって行なわれます。
- org.seasar.ymir.redirection.impl.RedirectionScope
-
redirectionスコープ。このスコープに保存されたオブジェクトは一度限りのリダイレクトをまたがって保持されます。
フレーム等を使った、一画面を表示するために複数リクエストを発行するタイプのアプリケーションや、複数ウィンドウを同時に開いたりするタイプのアプリケーションではこの機能が正しく働かないことがあります。その場合は以下の内容のymir-component+redirectionManager.diconファイルを作ってクラスパスに置くようにして下さい:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <component name="redirectionManager" class="org.seasar.ymir.redirection.impl.RedirectionManagerImpl"> <property name="addScopeIdAsRequestParameter">true</property> </component> </components>
オブジェクトをスコープにバインドする際のキーはgetter/setterメソッドが対応するプロパティ名になります。違うキーを指定したい場合はアノテーションのnameプロパティでキー文字列を指定して下さい。