これは Tomcat に固有のものではありません。これはサーブレット API に固有のものです。エラーページの決定方法は、サーブレット API 仕様 2.5の 9.9.2 章で指定されています。関連性の抜粋を次に示します。
SRV.9.9.2 エラーページ
クラス階層を使用した一致をerror-page
含む宣言がなく、スローされた例外がそのクラスまたはそのサブクラスである場合、コンテナーは、メソッドで定義されているように、ラップされた例外を抽出します。2 番目のパスはエラー ページ宣言に対して行われ、エラー ページ宣言との照合が再度試みられますが、代わりにラップされた例外が使用されます。exception-type
ServletException
ServletException.getRootCause
したがって、あなたSpecificExceptionA
は a でラップされている可能性が高いServletException
ため、java.lang.Throwable
最初のパスで最も近い一致です。このエントリを削除すると、ラップされた例外で 2 番目のパスが作成されるSpecificExceptionA
ため、一致が得られます。
error-code
一般的な HTTP 500 エラー ページを定義する正しい方法は、次の代わりにマップすることですexception-type
。
<error-page>
<exception-type>org.SpecificExceptionA</exception-type>
<location>/WEB-INF/views/error/timedout.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/error/error.jsp</location>
</error-page>
何らかの理由でこれがオプションでない場合、これを回避する方法の 1 つは、ofFilter
をリッスンし、基本的に次のことを行う を作成することです。url-pattern
/*
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
try {
chain.doFilter(request, response);
} catch (ServletException e) {
Throwable rootCause = e.getRootCause();
if (rootCause instanceof SpecificExceptionA) {
throw (SpecificExceptionA) rootCause;
} else {
throw e;
}
}
}
それを機能させるには、から拡張するだけRuntimeException
です。