Webアプリケーションの例外について言及した特定の処理は、JAX-RSコンテナのコンテキスト内でのみ定義されます。これは、サーブレットコンテナと同じものではありません。
Webフィルタは、サーブレットコンテナによって処理されます。サーブレットコンテナは、JAX-RSコンテナが同じアプリケーションサーバー内に存在することを認識または認識しません。また、Webアプリケーションの例外を認識または気にしません。したがって、フィルター内からWAEをスローすると、他の例外とまったく同じように扱われます(スタックトレースを使用したサーバーエラー、またはWebアプリケーションで設定した場合は事前構成されたエラーページ)。
クライアントにエラーを示している場合は、応答ストリームに直接書き込むことで、フィルターから簡単にそれを行うことができるように思われます。ただし、既存のJAX-RSロジックを活用しようとしている場合、(RESTEasy固有の)ソリューションは、フィルターでエラーとしてリクエストにフラグを立て、プロバイダークラスを使用してJAX-RSでWAEを生成することです。例:
@WebFilter(urlPatterns = "*")
public class ForwardingFilter implements Filter {
@Override
public void destroy() {
return;
}
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
// Add an error response to be processed by the JAX-RS container.
// This would obviously be based on some condition.
request.setAttribute("errorResponse",
Response.status(500).entity("Didn't work out!").build());
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
return;
}
}
@Provider
@ServerInterceptor
@HeaderDecoratorPrecedence
@RequestScoped
public class ForwardingHandlerProvider implements PreProcessInterceptor {
@Override
public ServerResponse preProcess(final HttpRequest request,
final ResourceMethod method) throws Failure,
WebApplicationException {
final Response errorResponse = (Response) request
.getAttribute("errorResponse");
if (errorResponse != null)
throw new WebApplicationException(errorResponse);
return null;
}
}
プロバイダーはJAX-RSランドに存在するため、Webアプリケーションの例外はJAX-RS仕様のセクション3.3.4のルールに従って処理され、クライアント側で目的の応答を取得します。
* 編集:*
要するに、JAX-RSで利用可能なものと同様に、サーブレットの例外を一元的に処理するための標準のJava EE規定の方法は(現在)ありません。ただし、JBoss / RestEASYを使用しているので、JBossSeamCatchライブラリを利用してかなり近づけることができます。
@HandlesExceptions
public class ExceptionHandler {
public void handleServletException(
final @Handles @WebRequest CaughtException<ServletException> caught,
@Context final HttpServletResponse response) {
try {
response.sendError(500, "An error occured");
} catch (final IOException ioe) {
System.err.println("Dumb IO Exception: " + ioe);
}
}
}
上記は、SeamCatchのドキュメントで説明されている例外ハンドラーを示しています。現在、ライブラリは非常に流動的であるため、最後の手段としてのみ利用することをお勧めします。