コンテンツへスキップ

SAStrutsの例外処理を実装する

SAStrutsの例外処理

やりたいこと

  • Exceptionしたらログを吐いて自作のエラーページに飛ばす
  • 自作のエラーページにはExceptionごとのエラーメッセージを表示する

実装

いろいろな方法がありますが、今回はカスタムExceptionを作成しつつ

throwしとけばException毎のメッセージが出せるような仕組みを構築します。

まずカスタムExceptionを作ります。

public class AuthException extends RuntimeException {

  private static final long serialVersionUID = 1L;

  public AuthException(String message) {
    super(message);
  }

}

Exceptionを起こすとき(=エラーページに飛ばすとき)はこんな感じにします。

throw new AuthException("testdes");

このままではtomcatのエラー画面に飛んでしまうし、ログも出力されません。

まずログを吐くにはExceptionが起こった後、エラー画面を出す前に呼ばれるクラス(ハンドラー)を

作る必要があります。

その中でログを吐いて、エラー画面に飛ばすということをしてやります。

まずハンドラーです。

public class ExceptionForwardHandler extends ExceptionHandler{
  Logger logger = Logger.getLogger("error");

  @Override
  public ActionForward execute(Exception ex,
      ExceptionConfig ae,
      ActionMapping mapping,
      ActionForm formInstance,
      HttpServletRequest request,
      HttpServletResponse response) throws ServletException {

    // logger出力
    logger.error(ex.getLocalizedMessage(), ex);

    // struts-configで設定したException処理を実行
    super.execute(ex, ae, mapping, formInstance, request, response);
    return (ae.getPath() != null ? ((S2ActionMapping) mapping).createForward(ae.getPath()) : mapping.getInputForward());
  }
}

さっぱりわかりませんね。

なんだかいろいろ受け取って何かを返しています。

ポイントは途中のlogger出力の部分だけです。これを処理に追加したかっただけです。

後はstrutsそのものの動作になります。

 

つぎに作成したハンドラーを経由してくれるように設定を変えます。

これはstruts-config.xmlに書きます。

      <!--
        key: application.propertiesのメッセージに対応するキー名
        path: エラー発生後の遷移先JSP
        handler: 固定で"net.hoge.exception.ExceptionForwardHandler"
      -->

      <exception key="exceptions.auth"
        type="net.hoge.exception.AuthException"
        path="/errors/error.jsp"
        handler="net.hoge.exception.ExceptionForwardHandler"
      />

      <!-- その他例外 -->
      <exception key="exceptions.other"
        type="java.lang.Exception"
        path="/errors/error.jsp"
        handler="net.hoge.exception.ExceptionForwardHandler"
      />

作成したカスタムExceptionはここにどんどこ追加していきます。

typeの部分にカスタムExceptionのクラス名、pathにはこのExceptionが起こった後の遷移先JSPを記載します。

handlerはさっき作ったExceptionForwardHandlerですね。

 

この設定により、

  • AuthExceptionがthrowされた
  • ExceptionForwardHandlerが呼ばれる→ログを吐く
  • error.jspが呼ばれる

という一連の流れができることになります。

 

次にエラーメッセージを用意します。AuthExceptionがthrowされたら

「認証エラーが発生しました」

とでも出しましょうか。

application_ja.propertiesに以下のように追加します。

exceptions.auth=認証エラーが発生しました。

ここで指定するキー名はstruts-config.xmlで指定したkey名と連動してます。

struts-config.xmlはkeyに指定された文字でapplication*.propertiesを読み

後続のjspにメッセージを渡す仕組みとなっています。

 

最後にエラーページのjspサンプルです。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@page import="org.apache.struts.Globals"%>
<html:html xhtml="true" lang="true">
<head>
<title>エラーハンドラのサンプル</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<html:base />
</head>
<body>

<ul>
<html:messages id="message">
  <li><bean:write name="message" /></li>
</html:messages>
</ul>

<hr />


<logic:present name="<%=Globals.EXCEPTION_KEY %>" >
  <bean:write name="<%=Globals.EXCEPTION_KEY %>"/>
</logic:present>

</body>
</html:html>

messageの部分で取得したエラーメッセージを表示してます。

またGlobals.EXCEPTION_KEYにはExceptionクラス名がセットされます

 

こんな感じで実装しておけば

例外処理も簡単になるのではないでしょうか。

 

参考サイト

参考サイト

参考サイト

コメントを残す

メールアドレスが公開されることはありません。