Apache Shale ExceptionHandler

Shale 1.0.3からExceptionHandlerが用意されました.

例外が発生した場合に,任意の画面に遷移させることが可能になりました.今回はその方法を紹介します.

web.xml

<!-- ApplicationExceptionHandler -->
<context-param>
    <param-name>
        org.apache.shale.view.EXCEPTION_DISPATCH_PATH
    </param-name>
    <param-value>/error.jsp</param-value>
</context-param>

このように設定すると,例外が発生した場合に,error.jspに遷移します.

error.jsp

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>エラー</title>
</head>
<body>
エラーが発生しました.<br />
<%
javax.faces.context.FacesContext context = javax.faces.context.FacesContext.getCurrentInstance();
javax.faces.context.ExternalContext eContext = context.getExternalContext();
java.util.Map requestMap = eContext.getRequestMap();
%>

<h2>FacesContext</h2>
<table border="1">
    <tr>
        <th>Status Code</th>
        <td><%=requestMap.get("javax.servlet.error.status_code") %></td>
    </tr>
    <tr>
        <th>Exception Type</th>
        <td><%=requestMap.get("javax.servlet.error.exception_type") %></td>
    </tr>
    <tr>
        <th>Message</th>
        <td><%=requestMap.get("javax.servlet.error.message") %></td>
    </tr>
    <tr>
        <th>Exception</th>
        <td><%=requestMap.get("javax.servlet.error.exception") %></td>
    </tr>
    <tr>
        <th>Request URI</th>
        <td><%=requestMap.get("javax.servlet.error.request_uri") %></td>
    </tr>
    <tr>
        <th>Servlet Name</th>
        <td><%=requestMap.get("javax.servlet.error.servlet_name") %></td>
    </tr>
</table>
</body>
</html>

JSPで指定しているキーは,現在のところViewPhaseListenerクラスに直書きされており,とても美しいとはいえない作りになっています.しかも,ResponseCompleteされていないため,裏でさらにExceptionがぶっとんでいます...

Shale内部ではさまざまなところで,ExceptionHandlerを使用しています.ディフォルトでは,
org.apache.shale.view.impl.DefaultExceptionHandlerクラスが使用されます.

ExceptionHandlerを作成する

ExceptionHandlerの動きを変えたい場合は,自分でExceptionHandlerを作成します.

ExceptionHandlerを作成する場合は,org.apache.shale.view.ExceptionHandler.ExceptionHandlerを実装します.

次に,MyExceptionHandlerを登録します.

faces-config.xml

<!-- MyExceptionHandler -->
<managed-bean>
    <managed-bean-name>
        org$apache$shale$view$EXCEPTION_HANDLER
    </managed-bean-name>
    <managed-bean-class>
        org.blackeyes.shale.sample.view.custom.MyExceptionHandler
    </managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

これで,自作のExceptionHandlerを登録することができました.

感想

ExceptionHandlerが作成されたのは,非常にうれしいことです.しかし,現時点ではあまりにも貧弱で使い勝手が悪すぎます.
使用方法もなかなか難しい作りになっています.

最終的にExceptionを処理しているクラスがViewPhaseListenerなんですが,ここでの処理もやはり雑な作りになっています.

Apache Conを目指しているせいなのかわかりませんが,最近のShaleは作りに粗さが目立ちます.(それだけでなく,一切の多言語対応が考慮されていない・・・)

JSFベースのFrameworkのトップを目指すなら,もう少し洗練させる必要があるのでは?このままでは,JBoss Seamには勝てませんよ...
(Seam自体触ったことがありませんが・・・Shaleに競合するFrameworkかと思いまして・・・)