WicketのURLをcoolにする

WicketのデフォルトのURL

WicketでPageを作ってもデフォルトの設定だと?wicket:bookmarkablePage=%3Arpage.HomePageとか?wicket:interface=:1:1:::みたいなURLになってしまいます。
このままだと全然カッコよくないので、以前「Wicket1.3でのURLマッピング - public static void main」でURLマッピングの方法を一度取り上げました。
その中では、以下のような感じでWebApplicationでURLのマッピングをしました。

import org.apache.wicket.protocol.http.WebApplication;
public class MyApplication extends WebApplication {
	public MyApplication() {
		super();
	}
	public void init() {
		mountBookmarkablePage("/index", IndexPage.class);
	}
	@Override
	public Class getHomePage() {
		return IndexPage.class;
	}
}

しかし、このmountBookmarkablePageを使う方法では、Pageのコンストラクタに引数を持つものやエラー時などではうまくいっていません。また、全部/home/id/1/のようになってしまうのが気に入らない人もいると思います。

mountBookmarkablePageメソッドは何をやっているか?

そこで、WebApplicationのソースを見てみたところ、以下のような処理をメソッド内で行っていました。

public final void mountBookmarkablePage(final String path, final Class bookmarkablePageClass)
{
	mount(new BookmarkablePageRequestTargetUrlCodingStrategy(path, bookmarkablePageClass, null));
}

ここで使われているmountメソッドは、このメソッドの引数に取るIRequestTargetUrlCodingStrategyインターフェースを実装したクラスのインスタンスの種類によって様々なURLの形でマッピングしてくれるようです。


ということで、IRequestTargetUrlCodingStrategyを実装しているクラスを8つ紹介します。
今回使ったWicketのバージョンは1.3.3です。

1. BookmarkablePageRequestTargetUrlCodingStrategy

mountBookmarkablePageの内部で使われているクラスです。
名前のとおりブックマーク可能な普遍のURLを持つので、HTTPのGETでしかアクセスしないページに使うとよいと思います。
引数を持つ場合は、/home/id/1/のような形になります。

2. HybridUrlCodingStrategy

/home.1のようなURLで、最後の数字の部分はアクセスするたびに変化します。
この数字で、セッションの状態を制御してるのかな?

mount(new HybridUrlCodingStrategy("login", LoginPage.class));

サブミットなどでPOSTでアクセスする可能性のあるページに使うことになると思います。
上記のように、URLが変化するのでブックマークされやすいトップページなどでは使わないほうがよいです。
また、サブクラスにIndexedHybridUrlCodingStrategyというものもあり、後述するIndexedParamUrlCodingStrategyの特性を持っています。

3. IndexedParamUrlCodingStrategy

/user/1/のように、パラメータの名前を省略したURLにすることが出来ます。

mount(new IndexedParamUrlCodingStrategy("/user", UserPage.class));

PageクラスのコンストラクタにPageParametersを持たせてやると、getString("0")やgetString("1")とすることでパラメータの値を順番に取得できます。
個人的には、/user/id/1/みたいなURLはダサいと思っているので、こういう指定が出来るのは好ましいですが、順番が重要になるので、間違えないように注意が要ります。

4. MixedParamUrlCodingStrategy

IndexedParamUrlCodingStrategyと似ており、/user/1/のようなURLにすることができます。
違う点は、第三引数で指定したものだけがパラメータ名を省略する対象になるということです。

mount(new MixedParamUrlCodingStrategy("/user", UserPage.class, new String[]{"id"}));

第三引数で指定されていないものは普通のGET時のようになります。
/user/1/?page=1のような形にしたい時に利用します。
個人的にはこれが一番気に入っているのですが、上記の設定時に/user/1/hoge/でアクセスするとエラーページが出てしまう点が気になっています。

5. PackageRequestTargetUrlCodingStrategy

パッケージを指定すると、その中のPageクラスに自動でURLマッピングしてくれます。
WebApplicationのメソッドに実装されており、以下のような感じで利用が出来ます。

mount("/base", PackageName.forPackage(Package.getPackage("example")));

/base/IndexPage/id/1のようにクラス名がURLに利用されます。
毎回設定するのが面倒だったら、これを使うと楽でいいかもしれません。

6. QueryStringUrlCodingStrategy

/search/?q=wicket&page=2のように、普通のGET時のURL表示になります。
検索部分とかではこういうURL表記のほうが好まれる気がします。

7. SharedResourceRequestTargetUrlCodingStrategy

リソースにURLを割り振ってくれるクラスです。
第二引数のResourceReferenceでリソースを指定するようです。

8. URIRequestTargetUrlCodingStrategy

これ自体では何もPageを指定できないようです。
decodeメソッドをオーバーライドして受け取ったパラメータによって適当なRequestTargetを返すという使い方をするようです。
HTMLページ以外のものを返すときに使うのかな?汎用性は高そうだけど、出番はあんまりなさそう?

終わりに

今回紹介したクラスを使えばかなり柔軟なURL設計をすることができます。
個人的にJava系のフレームワークで気になる点として.doとかついたりするところがあったのですが、WicketだとかっこいいURL設計をすることができてよいですね。
また、IRequestTargetUrlCodingStrategyを自分で実装すれば独自のURLパターンを扱うこともできますので、WicketでcoolなURL設計を目指しましょう。