Tomcatのデフォルトのエラーページにはスタックトレースがドサっと表示されてしまうので、一般のユーザにはほとんど意味が分かりません。そこで次のような定義をweb.xmlに書いて、ユーザが見て分かりやすい独自のエラーページを作成するという方法があります。次の設定ではjavax.servlet.ServletExceptionがスローされると/common/Error.jspが表示されます。スローする際に例外オブジェクトにメッセージを書きこんで、エラーページの方でこれを取り出すことができるのでとても便利です。
if(error){
throw new AppException("編集中に別のブラウザからデータが更新されました。");
}
こうすることでサーブレット側のプログラムでAppExceptionをスローしたときに、指定したエラーページに飛んでくれるようになりました。飛び先では、次のようなコードでメッセージを表示できます。
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/common/Error.jsp</location>
</error-page>
ただ、この設定では、想定されたアプリケーションの例外(例えば排他制御や存在しないデータへのアクセスなど)なのか、想定外のエラー(プログラムのバグや設定ミス)なのかが区別できません。そこで、次のように設定を変更してアプリケーションの例外だけを捕捉して独自のエラーページを表示しようと考えました。<exception-type>javax.servlet.ServletException</exception-type>
<location>/common/Error.jsp</location>
</error-page>
<error-page>
<exception-type>jp.veltec.AppException</exception-type>
<location>/common/Error.jsp</location>
</error-page>
こうしておけば、プログラム中で jp.veltec.AppException をスローすれば/common/Error.jspのページが表示されるはずです。ところがこれがなかなかうまくいきません。いろいろ調べてやっと分かったことは、jp.veltec.AppExceptionをプログラムする際にjava.lang.Excetionではなく、javax.servlet.ServletExceptionを継承する必要があるということです。こんな感じです。<exception-type>jp.veltec.AppException</exception-type>
<location>/common/Error.jsp</location>
</error-page>
package jp.veltec;
import javax.servlet.ServletException;
public class AppException extends ServletException{
public AppException(String aMessage){
super(aMessage);
}
}
スローするときはこんな感じです。import javax.servlet.ServletException;
public class AppException extends ServletException{
public AppException(String aMessage){
super(aMessage);
}
}
if(error){
throw new AppException("編集中に別のブラウザからデータが更新されました。");
}
<%=exception.getMessage()%>
Tomcatの以前のバージョンでは普通にExceptionを継承すれば良かったように思うのですが、記憶が定かではありません。原因が分かるまでにだいぶ時間を潰しました。やれやれ。
投稿:竹形 誠司[takegata]/2011年 05月 18日 14時 01分
/更新:2011年 05月 18日 22時 40分