Name
Password

オブジェクトスコープ

  • 2008-10-30 23:44:11

Webアプリケーションを作成する場合は、オブジェクトの有効範囲(スコープ)を上手に扱うことが重要になってきます。

サーブレットの世界にはスコープとしてrequestスコープ、sessionスコープ、applicationスコープなどがあります。Ymirでもこれらのスコープにオブジェクトをバインドしたりスコープからオブジェクトを取り出したりすることができますが、サーブレットAPIを直接使わずにスコープに関する操作が行なえるようになっています。

スコープからのオブジェクトのインジェクション

スコープからオブジェクトを取り出すことをインジェクションと言います。

オブジェクトをインジェクトしたい場合はorg.seasar.ymir.scope.annotation.Inアノテーションを付与したSetterメソッドを用意します。

Setterメソッドに対応するプロパティの名前がオブジェクトをスコープにインジェクトする際のキーになります。違うキーを指定したい場合は@Inアノテーションのnameプロパティでキー文字列を指定して下さい。

以下の例は、sessionスコープに「value」というキーでバインドされているオブジェクトをインジェクトするためのコードです。

@In(SessionScope.class)
public void setValue(Object value)
{
    value_ = value;
}

対応するキーでバインドされているオブジェクトが存在しない場合は通常Setterメソッドは呼び出されません。オブジェクトが存在しない場合にもSetterメソッドを呼び出したい場合は@Inアノテーションに「injectWhereNull=true」というプロパティを追加して下さい。

インジェクション処理は制約チェックの前に行なわれます。

インジェクションはどのアクション呼び出しに関しても常に行なわれますが、@Inアノテーションに「actionName」プロパティを指定することで、特定のアクションの時だけ行なわせることもできます。

@In(scopeClass = SessionScope.class, actionName = { "_post", "_post_done" })
public void setValue(Object value)
{
    value_ = value;
}

上の例では、リクエストが_postアクションまたは_post_doneアクションを呼び出すケースのみセッションスコープからオブジェクトがインジェクトされます。

スコープへのオブジェクトのアウトジェクション

スコープにオブジェクトをバインドすることをアウトジェクションと言います。

オブジェクトをアウトジェクトしたい場合はorg.seasar.ymir.annotation.Outアノテーションを付与したGetterメソッドをPageクラスに用意します。

Getterメソッドに対応するプロパティの名前がオブジェクトをスコープからアウトジェクトする際のキーになります。違うキーを指定したい場合は@Outアノテーションのnameプロパティでキー文字列を指定して下さい。

以下の例は、sessionスコープに「value」という名前でGetterメソッドの返り値をアウトジェクトするためのコードです。

@Out(SessionScope.class)
public Object getValue()
{
    return value_;
}

オブジェクトをスコープからアンバインドしたい場合はGetterメソッドがnullを返すようにして下さい。Getterメソッドがnullを返す場合にオブジェクトをスコープからアンバインドしたくない場合は@Outアノテーションに「outjectWhereNull=false」というプロパティを追加して下さい。

アウトジェクション処理はアクションの呼び出しの後(_prerenderメソッドの呼び出しがあればその後)に行なわれます。

アウトジェクションはどのアクション呼び出しに関しても常に行なわれますが、@Outアノテーションに「actionName」プロパティを指定することで、特定のアクションの時だけ行なわせることもできます。

@Out(scopeClass = SessionScope.class, actionName = { "_post", "_post_done" })
public Object getValue()
{
    return value_;
}

上の例では、リクエストが_postアクションまたは_post_doneアクションを呼び出すケースのみgetValue()の値がセッションスコープにアウトジェクトされます。

定義済みのスコープ

定義済みのスコープには以下のものがあります。

request

現在のリクエストの間だけ有効なスコープです。

オブジェクトの操作はHttpServletRequest#getAttribute()、HttpServletRequest#setAttribute()によって行なわれます。

スコープを表すクラスはorg.seasar.ymir.scope.impl.RequestScopeです。

session

現在のHTTPセッションの間だけ有効なスコープです。

オブジェクトの操作はHttpSession#getAttribute()、HttpSession#setAttribute()によって行なわれます。

オブジェクトをバインドする際にセッションが存在しない場合はセッションを生成してからバインドします。オブジェクトを取り出す際にセッションが存在しない場合は取り出した結果はnullになります。

スコープを表すクラスはorg.seasar.ymir.scope.impl.SessionScopeです。

application

Webアプリケーションが起動している間有効なスコープです。

オブジェクトの操作はServletContext#getAttribute()、ServletContext#setAttribute()

スコープを表すクラスはorg.seasar.ymir.scope.impl.ApplicationScopeです。

cookie

HTTP Cookieに対応するスコープです。

スコープからのインジェクションはリクエストからCookieの値を取り出す操作に対応します。スコープへのアウトジェクションはレスポンスにCookieを設定する操作に対応します。

スコープを表すクラスはorg.seasar.ymir.scope.impl.CookieScopeです。

requestParameter

リクエストパラメータ及びURLパラメータを読み出すためのスコープです。

スコープを表すクラスはorg.seasar.ymir.scope.impl.RequestParameterScopeです。

extendedRequestParameter

拡張されたリクエストパラメータを読み出すためのスコープです。

例えばYmirのJSONモジュールを使ってJSON通信を行なう場合のJSONリクエストの内容といった、通常のリクエストパラメータとは別の拡張されたリクエストパラメータを読み出すためのスコープです。

ymir-coreモジュールだけを使用している場合はこのスコープの内容は空です。このスコープが保持するオブジェクトはYmirのモジュール毎に定義されます。

スコープを表すクラスはorg.seasar.ymir.scope.impl.ExtendedRequestParameterScopeです。

requestHeader

HTTPリクエストヘッダを読み出すためのスコープです。

スコープを表すクラスはorg.seasar.ymir.scope.impl.RequestHeaderScopeです。

responseHeader

HTTPレスポンスヘッダを設定するためのアウトジェクト専用のスコープです。

スコープを表すクラスはorg.seasar.ymir.scope.impl.ResponseHeaderScopeです。

component

DIコンテナからオブジェクトを取り出すためのスコープです。

スコープを表すクラスはorg.seasar.ymir.scope.impl.ComponentScopeです。

conversation

conversationスコープです。

conversationスコープについては「conversationスコープ」を参照して下さい。

スコープを表すクラスはorg.seasar.ymir.conversation.impl.ConversationScopeです。

redirection

リダイレクトをまたがって存在するスコープです。このスコープに保存されたオブジェクトは一度限りのリダイレクトをまたがって保持されます。

フレーム等を使った、一画面を表示するために複数リクエストを発行するタイプのアプリケーションや、複数ウィンドウを同時に開いたりするタイプのアプリケーションではこの機能が正しく働かないことがあります。その場合は以下の内容のymir-component+redirectionManager.diconファイルを作ってsrc/main/resourcesに置くようにして下さい:

<?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>

スコープを表すクラスはorg.seasar.ymir.redirection.impl.RedirectionScopeです。