アプリケーションによってキャッチされていない Exception が発生した場合に 専用のエラー画面を出すためには Global Exception の設定を行います。 blank.war には以下のようなハンドラが設定されていますのでこれを用います。
<global-exceptions>
<!-- sample exception handler
<exception
key="expired.password"
type="app.ExpiredPasswordException"
path="/changePassword.jsp"/>
end sample -->
</global-exceptions>
以下のように書き換えます
<global-exceptions>
<exception
handler="org.flnet.tantau.lab.ExceptionHandler"
key="exception.message"
type="java.lang.Exception"
path="/pages/Exception.jsp"/>
</global-exceptions>
これはキャッチされない Exception が発生した場合は org.flnet.tantau.lab.ExceptionHandler を実行されて /Exception.jsp にフォワードされます。key の exception.message はリソースファイルに記述してメッセージに使用します。
ExceptionHandler を継承して作成します。
ポイント
業務アプリケーションではすべて「xx分後に再度行ってください」などの統一 メッセージにすることもあります。ちゃんとメッセージを出したほうが ユーザフレンドリさには欠けるかもしれませんが問題が発生したときの解決は早 いです。許されるならログに記録するとともにエラーメッセージをユーザの画面 にもだしてあげることをお勧めします。もちろんめったにこの画面は表示されな いという前提がありますが。
Exception ハンドラは ActionError になっている Tips もありましたがそれは 1.1 の作法で 1.2 では ActionMessage を使うことになっています。
ActionForward af = super.execute(ex, config, mapping, form, request, response);
// SQLException の場合はすべての Exception のログをとる
if(ex instanceof SQLException) {
SQLException sqle = (SQLException)ex;
while(sqle != null) {
log.error(LabUtils.toString(sqle));
sqle = sqle.getNextException();
}
} else {
// 文字列として Exception の StackTrace をとる
log.error(LabUtils.toString(ex));
}
ActionMessage error = new ActionMessage("exception.message", ex.getMessage());
storeException(request, null, error, af, config.getScope());
return af;
Eclipse を使用して MessageResource.properties に以下を追加します。
# -- exceptions
exception.title=システム例外
exception.message={0}
画面には {0} が ex.getMessages() が表示され、ログにはスタックトレース が記録されるようにします。
exception.message タグには ExceptionHandler でセットしたメッセージが表示されます。
これはちょっと難問です。プログラムに不具合があるか、なんらかの不具合があった ときにしかこのルーチンは使われません。つまりわざと不具合のあるコードをうめこま なければテストできないのですがそれを struts-config.xml に書いてしまうとテスト 用のコードを分離できなくなってしまいます。
Action Mapping をない場合に例外をなげてくれるかとおもいましたが、HTTP Response 404 になってしまい、Global Exception は呼ばれませんでした。
今回はしょうがないので struts-config.xml に Exception を投げる Action を 作成しておきましたがもっとうまい解決方法があるような気がします。
TestExceptionHandler.java TestExceptionAction.java