/** * Handle the Exception. Return the ActionForward instance (if any) returned by the called * ExceptionHandler. * * @param ex The exception to handle * @param ae The ExceptionConfig corresponding to the exception * @param mapping The ActionMapping we are processing * @param formInstance The ActionForm we are processing * @param request The servlet request we are processing * @param response The servlet response we are creating * @return The <code>ActionForward</code> instance (if any) returned by the called <code> * ExceptionHandler</code>. * @throws ServletException if a servlet exception occurs * @since Struts 1.1 */ public ActionForward execute( Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { LOG.debug("ExceptionHandler executing for exception " + ex); ActionForward forward; ActionMessage error; String property; // Build the forward from the exception mapping if it exists // or from the form input if (ae.getPath() != null) { forward = new ActionForward(ae.getPath()); } else { forward = mapping.getInputForward(); } // Figure out the error if (ex instanceof ModuleException) { error = ((ModuleException) ex).getActionMessage(); property = ((ModuleException) ex).getProperty(); } else { error = new ActionMessage(ae.getKey(), ex.getMessage()); property = error.getKey(); } this.logException(ex); // Store the exception request.setAttribute(Globals.EXCEPTION_KEY, ex); this.storeException(request, property, error, forward, ae.getScope()); if (!response.isCommitted()) { return forward; } LOG.debug( "Response is already committed, so forwarding will not work." + " Attempt alternate handling."); if (!silent(ae)) { handleCommittedResponse(ex, ae, mapping, formInstance, request, response, forward); } else { LOG.warn( "ExceptionHandler configured with " + SILENT_IF_COMMITTED + " and response is committed.", ex); } return null; }
/** * SystemException例外ハンドラのエントリポイント。 * * @param ex 例外 * @param eConfig 例外コンフィグ * @param mapping アクションマッピング * @param formInstance アクションフォーム * @param request HTTPリクエスト * @param response HTTPレスポンス * @return 遷移情報 * @throws ServletException サーブレット例外 * @see jp.terasoluna.fw.web.struts.action.DefaultExceptionHandler#execute( java.lang.Exception, * org.apache.struts.config.ExceptionConfig, org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse ) */ @Override public ActionForward execute( Exception ex, ExceptionConfig eConfig, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { // 【フォワード先を設定する】 // pathによるフォワード先が指定されない場合は、 // アクションマッピングのinput属性をデフォルトとする。 String path = null; if (eConfig.getPath() != null) { path = eConfig.getPath(); } else { path = mapping.getInput(); } ActionForward forward = new ActionForward(path); String logLevel = null; // 【遷移先を設定する】 if (eConfig instanceof ExceptionConfigEx) { // 遷移先モジュールが設定されているとき、モジュール名を設定する forward.setModule(((ExceptionConfigEx) eConfig).getModule()); // ログレベルを取得する logLevel = ((ExceptionConfigEx) eConfig).getLogLevel(); } // 【SystemExceptionの場合、エラーキーとエラーメッセージの置換を行う】 if (ex instanceof SystemException) { SystemException se = (SystemException) ex; // 【リクエストからメッセージリソースを取得する。】 MessageResources resources = null; // スコープからメッセージリソースを取得する際のバンドルキーを取得する。 String bundle = eConfig.getBundle(); if (bundle == null) { // struts-config.xmlのmessage-resourcesで // bundle属性が指定されていない場合、 // デフォルトのバンドルキーを設定する bundle = Globals.MESSAGES_KEY; } // リクエスト属性からの取得を試みる。 resources = (MessageResources) request.getAttribute(bundle); if (resources == null) { // リクエスト属性になければアプリケーション属性からの取得を試みる。 resources = (MessageResources) RequestUtil.getServletContext(request).getAttribute(bundle); } // 【エラーキーとエラーメッセージの置換を行う】 // SystemExceptionのエラーキーをエラーメッセージに置換する。 String message = null; if (resources == null) { // リソース取得できない場合はエラーキーをメッセージとする message = se.getErrorCode(); } else { message = getErrorMessage(request, se, resources); } se.setMessage(message); // 【画面表示用にActionMessageを設定する】 String key = eConfig.getKey(); ActionMessage error = null; if (resources != null) { // エラーメッセージの置換文字列を取得する String[] options = se.getOptions(); if (options != null && options.length > 0) { error = new ActionMessage(key, options); } else { error = new ActionMessage(key); } } else { // 画面であってもメッセージリソースが無い場合はエラーキーをメッセージにする error = new ActionMessage(key, false); } super.storeException(request, key, error, forward, eConfig.getScope()); // 変換された例外メッセージ、スタックトレースと // セッションハッシュ値をログに出力 String sessionHash = RequestUtil.getSessionHash(request); logException(logLevel, "sessionHash = " + sessionHash); logException(logLevel, ExceptionUtil.getStackTrace(se)); // 【置換済のSystemExceptionを設定する】 // システム例外をJSPエラーページで exception として // 取得できるように request に設定する request.setAttribute(PageContext.EXCEPTION, se); } // システムエラー時は、アクションマッピングの設定に沿って遷移する。 return forward; }