Name
Password

リクエストパスとPageクラスのマッピング

  • 2008-10-21 15:42:01

Ymirではリクエストされたパスの正規表現パターンと処理コンポーネント(Javaクラス)名の対応(パスマッピング)が定義されており、リクエストパスについてパターンにマッチするようなパスマッピングからコンポーネント名やアクション名が組み立てられて処理メソッドの呼び出しが行なわれます。

標準のパスマッピング

標準のパスマッピングはmapping.diconで次のように定義されています。

パターン Pageコンポーネント名テンプレート
(空文字列) _RootPage
/([a-zA-Z][a-zA-Z0-9]*)\\.html ${1}Page
/([a-zA-Z][a-zA-Z0-9]*) ${1}__RootPage
/([a-zA-Z][a-zA-Z0-9]*)/([a-zA-Z][a-zA-Z0-9]*).html ${1}_${2}Page

「パターン」は、リクエストパス(コンテキストパス相対)の正規表現です(パターンのマッチングはYmir-0.9.xではパスの一部に対して行なわれていましたが、Ymir-1.0.xではパス全体に対して行なわれますのでパターンの前後に「^」「$」は不要です)。マッチングの際には末尾の「/」は無視されます。

例えば空文字列や「/」は1番目のパターンにマッチします。「/path.html」は2番目のパターンにマッチします。「/path」「/path/」は3番目のパターンにマッチします。「/path/sub.html」は4番目のパターンにマッチします。

指定できる正規表現パターンについてはJ2SEリファレンスを参照して下さい。

「Pageコンポーネント名テンプレート」は、処理メソッドを持つPageコンポーネントの名前を構築するためのテンプレートです。テンプレートには${...}形式で変数の値を埋め込むことができます。

変数 意味
${数値} パス文字列のうちパターン中で括弧で囲われている部分にマッチした部分の数値番目のもの
${数値u} ${数値}を全て大文字にしたもの
${数値l} ${数値}を全て小文字にしたもの
${`} パス文字列のうちパターンにマッチした部分よりも前の部分
${&} パス文字列のうちパターンにマッチした部分
${'} パス文字列のうちパターンにマッチした部分よりも後ろの部分
${method} HTTPメソッド名(全て小文字)
${Method} HTTPメソッド名(先頭だけ大文字)
${METHOD} HTTPメソッド名(全て大文字)

例えばリクエストパスが「/path.html」である場合は実際のコンポーネント名は「pathPage」となり、Ymirはこの名前を持つコンポーネントをS2Containerから取り出してメソッド呼び出しを行ないます。

PageコンポーネントはS2Containerによって自動登録されます。例えばアプリケーションのルートパッケージ名がcom.example.appである場合はcom.example.app.web.XyzPageというクラスのインスタンスがxyzPageという名前でコンポーネント登録されます。従って、pathPageコンポーネントであればcom.example.app.web.PathPageクラスということになります。

リクエストパスが空文字列や「/」の場合はコンポーネント名は「_RootPage」で、この名前はcom.example.app._RootPageと対応します。

リクエストパスが「/path」「/path/」の場合はコンポーネント名は「path__RootPage」で、この名前はcom.example.app.path._RootPage``と対応します。

リクエストパスが「/path/sub.html」の場合はコンポーネント名は「path_subPage」で、この名前はcom.example.app.path.SubPage``と対応します。

パスマッピングの変更

パスマッピングを変更するには、アプリケーションプロジェクトのsrc/main/resourcesにmapping+.diconというファイルを作成してパスマッピング定義を記述して下さい。mapping+.diconは標準のmapping.diconよりも優先して使用されます。

diconファイルの中でパスマッピングを定義するための標準クラスであるorg.seasar.ymir.impl.YmirPathMappingImplのコンストラクタでは、パターンとPageコンポーネント名テンプレート以外に「直接アクセスの禁止」「アクション名テンプレート」「pathInfoテンプレート」「パラメータテンプレート」「デフォルト返り値テンプレート」を指定することもできます。

「直接アクセスの禁止」とは、直接のリクエストを禁止するかどうかです。例えばあるPageからforwardによって遷移するテンプレートは外部から直接アクセスされたくないかもしれません。その場合は「直接アクセスの禁止」をtrueにして下さい。デフォルトは「false」です。

「アクション名テンプレート」は、呼び出すメソッド(アクション)の名前を構築するためのテンプレートです。例えばリクエストパスが「/path.html」でPOSTメソッドでリクエストがあった場合は実際のアクション名は「_post」となり、YmirはpathPageコンポーネントの_postメソッドの呼び出しを行ないます。デフォルトは「${method}」です。

「pathInfoテンプレート」は、リクエストパスの一部をpathInfo情報として取り出すためのテンプレートです。詳しくは後述します。デフォルトは「null」です。

「パラメータテンプレート」は、パスからパラメータを取り出すためのルールです。詳しくは後述します。デフォルトは「null」です。

「デフォルト返り値テンプレート」は、アクションの返り値から構築したレスポンスオブジェクトのタイプがPASSTHROUGHであった場合に返り値として使われる文字列のテンプレートです。具体的には、このテンプレートから構築された文字列がアクションの返り値であるとみなされます。例えばリクエストパスが「/path/sub.html」でアクションの返り値がPASSTHROUGHタイプのレスポンスであった場合、"redirect:/path.html"が返り値とみなされます。なおデフォルトの返り値がnullである場合はそのままPASSTHROUGHがレスポンスとして使われます。デフォルトは「null」です。

pathInfo

パスマッピングのpathInfoTemplateプロパティにpathInfoテンプレートを指定することで、パスの一部をpathInfo情報として取り出すことができます。

pathInfoテンプレートは他のテンプレートと同様、${...}形式の変数が埋め込まれた文字列です。例えばパスのパターンとして「/([^/]+).*」、pathInfoテンプレートとして「${'}」が指定されているケースで、リクエストパスが「/download/file.pdf」である場合、pathInfoは「file.pdf」となります。

pathInfo情報はRequestオブジェクトから取り出したorg.seasar.ymir.DispatchオブジェクトからDispatch#getPathInfo()で取り出すことができます。

パスからのパラメータの取り出し

パスマッピングにパラメータテンプレートを指定することで、パス中の任意の部分文字列をパラメータとして取り出すことができます。このパラメータをURIパラメータと呼びます。

パラメータテンプレートは「パラメータ名=${...}」形式の文字列です。パラメータ名を複数並べる場合は「;」で区切ります。同名のパラメータ名を並べることもできます。その場合はパラメータの値が複数になります。

例えばパスのパターンとして「^/article/([^/]+)/([^/]+).html」、パラメータテンプレートとして「category=${1};id=${2}」が指定されているケースで、リクエストパスが「/article/computer/15.html」である場合、パラメータ「category」の値として「computer」、「id」の値として「15」が取り出されます。

URIパラメータは通常のリクエストパラメータとマージされてRequestオブジェクトにセットされます。従って、例えば/index.html?param=aaaというパスにアクセスした場合でURIパラメータとしてparam=bbbが取り出された場合、Request#getParameterValues("param")の返り値は"aaa"と"bbb"になります(順序は不定です)。

URIパラメータはリクエストパラメータとマージされますので、リクエストパラメータと同様Pageオブジェクトに自動的にインジェクトされます。

ボタンとアクションの関連付け

複数submitボタンを持つようなフォームで、押されたボタン毎に呼び出すアクションを変えたい場合があります。そういうケースをうまく扱えるように、標準のマッピングではアクション名の末尾に「_」+「ボタン名」をつけた名前のメソッドが存在する場合はそのメソッドが呼び出されるようになっています。該当するボタンが複数ある場合はフレームワークが最初に発見した方が呼び出されます。

ボタンが押された際にパラメータを渡すこともできます。例えばPOSTリクエストでボタン名を「search[1][cond]」のように「[]」でパラメータをつけた形にしておくと、パラメータが適宜型変換されてアクションメソッド「_post_search」の引数として渡されます。