ActionなどでExceptionが発生した際に、自動的にエラーページに遷移できるようにしておくと余計なエラー処理を内部で各必要がなくなるので便利かと思い作成しました。
今回の要件として、上記に加え、エラーの内容をメッセージコードで管理しているのでそれを利用し、さらに意図しないエラーの場合はデフォルトのメッセージコードを割り当てるというものです。
作成したのは、「com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor」を継承した自作例外インターセプタークラスだけです。実際、処理もほとんど変わっていません。
いつもの用に作成したソースは、下記に掲載しているので良ければ見てください。
作成したクラス以外の注意点として、インターセプタースタックにデフォルトの「defaultStack」を利用している場合、exceptionという通常の例外処理用インターセプターが存在するため、それを除外する必要があります。定義済みのスタックから除外する方法が見つからなかったので、defaultStackからexceptionを除いてstruts.xmlにて再定義しています。
広告
■JcExceptionInterceptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | package org.fukata.jc_common.interceptor; import java.util.List; import org.apache.commons.lang.StringUtils; import org.fukata.jc_common.exception.JcSystemException; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig; import com.opensymphony.xwork2.interceptor.ExceptionHolder; import com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor; public class JcExceptionInterceptor extends ExceptionMappingInterceptor { private static final long serialVersionUID = 1L; protected String defaultMessageCode; public String getDefaultMessageCode() { return defaultMessageCode; } public void setDefaultMessageCode(String defaultMessageCode) { this.defaultMessageCode = defaultMessageCode; } @Override public String intercept(ActionInvocation invocation) throws Exception { String result; try { result = invocation.invoke(); } catch (Exception e) { if (isLogEnabled()) { handleLogging(e); } List<exceptionmappingconfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); String mappedResult = this.findResultFromExceptions(exceptionMappings, e); if (mappedResult != null) { // メッセージコードの格納 Exception ex = e; if (isDefaultMessageCode(e)) { ex = new JcSystemException(getDefaultMessageCode()); } result = mappedResult; publishException(invocation, new ExceptionHolder(ex)); } else { throw e; } } return result; } /** * デフォルトのメッセージコードを適用するかどうか * @param e * @return */ private boolean isDefaultMessageCode(Exception e) { if (e instanceof JcSystemException) { if (StringUtils.isBlank(e.getMessage())) { return true; } } else { return true; } return false; } private String findResultFromExceptions(List</exceptionmappingconfig><exceptionmappingconfig> exceptionMappings, Throwable t) { String result = null; // Check for specific exception mappings. if (exceptionMappings != null) { int deepest = Integer.MAX_VALUE; for (Object exceptionMapping : exceptionMappings) { ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) exceptionMapping; int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t); if (depth >= 0 && depth < deepest) { deepest = depth; result = exceptionMappingConfig.getResult(); } } } return result; } } |
■applicationContext.xml
1 2 3 4 | <bean id="jcExceptionInterceptor" class="org.fukata.jc_common.interceptor.JcExceptionInterceptor" scope="prototype"> <property name="defaultMessageCode" value="exception.M00100"></property> </bean> |
■struts.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <!-- インターセプター --> <interceptors> <interceptor name="jcException" class="jcExceptionInterceptor"></interceptor> <interceptor name="login" class="loginInterceptor"></interceptor> <interceptor -stack name="myDefaultStack"> <interceptor -ref name="jcException"></interceptor> <interceptor -ref name="login"></interceptor> <interceptor -ref name="alias"></interceptor> <interceptor -ref name="servletConfig"></interceptor> <interceptor -ref name="i18n"></interceptor> <interceptor -ref name="prepare"></interceptor> <interceptor -ref name="chain"></interceptor> <interceptor -ref name="debugging"></interceptor> <interceptor -ref name="profiling"></interceptor> <interceptor -ref name="scopedModelDriven"></interceptor> <interceptor -ref name="modelDriven"></interceptor> <interceptor -ref name="fileUpload"></interceptor> <interceptor -ref name="checkbox"></interceptor> <interceptor -ref name="staticParams"></interceptor> <interceptor -ref name="actionMappingParams"></interceptor> </interceptor><interceptor -ref name="params"> <param name="excludeParams"/>dojo\..*,^struts\..* </interceptor> <interceptor -ref name="conversionError"></interceptor> <interceptor -ref name="validation"> <param name="excludeMethods"/>input,back,cancel,browse </interceptor> <interceptor -ref name="workflow"> <param name="excludeMethods"/>input,back,cancel,browse </interceptor> </interceptors> <default -interceptor-ref name="myDefaultStack"></default> <global -results> <result name="exception">/jsp/Error.jsp</result> </global> <global -exception-mappings> <exception -mapping result="exception" exception="java.lang.Exception"></exception> </global> |