読者です 読者をやめる 読者になる 読者になる

Red > Green > Refactor > Red

cycle is based on desire

struts.xml の global-exception-mappings とは何か

struts2-core v2.3.28

global-exception-mappings とは

はじめに、Struts2 には Exception mappings という機能がある

これは Action 内で throw された例外を自動的に catch

あらかじめ用意された resultマッピングする機能である

この Exception mappings

どの resultマッピングするかを定義する xml 属性が

global-exception-mappings である

2 点注意が必要

1(X)

ローカルのマッピング(action.exception-mapping)を定義できるが

これを有効化した時、グローバルのマッピング(global-exception-mappings)は無効化される

2(Y)

あくまで action#classexecute 内で発生した例外をマッピングするもので

action#classコンストラクタ内で throw された例外はマッピングされない

具体的に

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
  <constant name="struts.devMode" value="true" />
  <constant name="struts.ui.theme" value="simple" />
  <package name="top" extends="struts-default">
    <global-results>
      <result name="myException">/Exception.jsp</result>
    </global-results>
    <global-exception-mappings>
      <exception-mapping exception="java.lang.Exception" result="myException" />
    </global-exception-mappings>
    <action name="index" class="jp.ymatsukawa.top.Index">
      <result name="success">/index.jsp</result>
    </action>
  </package>
</struts>

/top/index.action へ GET リクエストされたとする

action#class=jp.ymatsukawa.top.IndexExceptionthrow された場合

global-exception-mappingsException を捕捉する

この時 exception-mapping#result に対応する result を実行する

上の場合だと resultmyException なので

global-results.result#name="myException" が実行される

(/Exception.jspdispatch される)

(X)

(動作確認より)

global-exception-mappings.exception-mapping を定義後

action.exceptoin-mapping を用いて

個々の actionexception-mapping を定義することができる

ただし、その場合は global-exception-mapping の設定は無効になる

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
  <constant name="struts.devMode" value="true" />
  <constant name="struts.ui.theme" value="simple" />
  <package name="top" extends="struts-default">
    <global-results>
      <result name="myException">/Exception.jsp</result>
    </global-results>
    <global-exception-mappings>
      <exception-mapping exception="java.sql.SQLException" result="myException" />
    </global-exception-mappings>
    <action name="index" class="jp.ymatsukawa.top.Index">
      <exception-mapping exception="java.lang.RuntimeException" result="error" />
      <result name="success">/index.jsp</result>
      <result name="error">/myError.jsp></result>
    </action>
  </package>
</struts>

もし jp.ymatsukawa.top.Index

java.sql.SQLExceptionthrow されても

/Exception.jspdispatch されず

/myError.jspdispatch される

(global-exception-mappings.exception-mapping#exception=java.lang.Exception

でハンドリングをまとめておき、個々の action

Exception 以外の例外捕捉を必要に応じて追加するのが良いか...)

(Y)

jp.ymatsukawa.top.Indexコンストラクタが 例外を throw し得る場合

global-exception-mappings はこの例外をマッピングしない

極端な例

package jp.ymatsukawa.top.Index;
import com.opensymphony.xwork2.ActionSupport;

public class Index extends ActionSupport {
  public Index() throws Exception {
    throw new Exception;
  }

  @Override
  public String execute() {
    return SUCCESS;
  }
}

この場合、Struts2 は例外マッピング、例外ハンドリングすることなく、エラー処理を実行する

[参考元]

https://struts.apache.org/docs/exception-configuration.html