pages.xmlでのリダイレクト無限ループ回避

Seamのpages.xmlは下手に書くとうまく機能しなかったりしますが、以前ちょっとはまったのがリダイレクト無限ループの罠。

例えば、パスワード有効期限切れの場合はログイン成功直後にパスワード変更画面にリダイレクトさせる、というよくある機能をpages.xmlで定義する場合を考えてみます。

<page view-id="/*">
	<navigation>
		<rule if="#{
			identity.isLoggedIn(false)
			and loginSessionObject.pwdExpiredFlag
		}">
			<redirect view-id="/password/change.xhtml"/>
		</rule>
	</navigation>
</page>

上記のように書くとリダイレクトが無限ループします。パスワード変更画面にリダイレクトされた先でまた上記の判定が評価され、再度パスワード変更画面へリダイレクトされてしまうからです。

このように書き換えるとうまくいきます。

<page view-id="/*">
	<navigation>
		<rule if="#{
			redirect.viewId != "/password/change.xhtml"
			and identity.isLoggedIn(false)
			and loginSessionObject.pwdExpiredFlag
		}">
			<redirect view-id="/password/change.xhtml"/>
		</rule>
	</navigation>
</page>