首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts 異常處理機制詳解:配置驅動、全局與局部、自定義處理器

     編輯:Java 相關知識

從手動 try/catch 到聲明式異常管理

早期 Struts 開發中,Action 內充斥 try/catch,將異常轉為 ActionError 放入請求,再在 JSP 顯示。Struts 1.1 引入聲明式異常處理,在 struts-config.xml 映射異常類型至轉發頁面與錯誤鍵值,實現業務邏輯與錯誤處理分離。

兩種配置範圍

1. 全局異常 (<global-exceptions>)

應用級通用異常映射,所有 Action 生效:

<global-exceptions>
  <exception
    key="expired.InvalidItemsCatalogName"
    type="com.shop.exception.InvalidItemsCatalogNameException"
    path="/error.jsp"
    scope="request"/>
</global-exceptions>
  • key:對應 ApplicationResources.properties 鍵值,如 expired.InvalidItemsCatalogName=該商品分類已存在,請重新輸入!
  • type:完全限定異常類名 (支援繼承匹配)。
  • path:轉發目標頁面 (相對上下文根)。
  • scope:request 或 session,決定錯誤信息存活範圍。

2. 局部異常 (Action 級 <exception>)

針對特定 Action 覆蓋或補充全局配置:

<action-mappings>
  <action path="/addItemsCatalogAction"
          type="com.shop.action.ItemsCatalogAction"
          name="itemsCatalogForm">
    <exception
      key="expired.InvalidItemsCatalogName"
      type="com.shop.exception.InvalidItemsCatalogNameException"
      path="/error.jsp"/>
    <forward name="success" path="/tiles.layout"/>
  </action>
</action-mappings>

優先級:局部 > 全局。同一異常類型在局部重新聲明可指定不同錯誤頁或信息鍵。

業務代碼簡化:拋出即忘

public class ItemsCatalogAction extends BaseAction {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response)
            throws Exception { // execute 拋出 Exception,滿足異常處理器要求
        String act = request.getParameter("act");
        ItemsCatalogMap map = new ItemsCatalogMap();
        ItemsCatalogForm f = (ItemsCatalogForm) form;

        if ("create".equals(act)) {
            map.validateNameOfCatalog(f); // 內部拋出 InvalidItemsCatalogNameException
            map.create(f);
            return mapping.findForward("success");
        }
        return mapping.findForward("error");
    }
}

關鍵點:

  • Action execute() 聲明 throws Exception (而非舊版 perform() 僅 IOException, ServletException),使容器能捕獲業務異常並交給異常處理器。
  • 業務邏輯層 validateNameOfCatalog() 直接拋出業務異常,無需 try/catch,代碼極度乾淨。

自定義異常處理器:擴展預設行為

默認 org.apache.struts.action.ExceptionHandler 僅設置錯誤信息並轉發。繼承它可實現:日誌記錄、郵件通知、審計追蹤、差異化響應 (AJAX 返回 JSON、頁面返回 HTML)。

實現步驟

  1. 繼承 ExceptionHandler 並覆寫 execute():
public class CustomExceptionHandler extends ExceptionHandler {
    private static final Log LOG = LogFactory.getLog(CustomExceptionHandler.class);

    @Override
    public ActionForward execute(Exception ex, ExceptionConfig cfg,
                                 ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response)
            throws ServletException {
        // 1. 記錄完整堆棧
        LOG.error("Business exception caught", ex);

        // 2. 區分 AJAX 請求
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            response.setContentType("application/json;charset=UTF-8");
            try {
                response.getWriter().write("{\"error\":\"" + getMessage(cfg, request) + "\"}");
            } catch (IOException e) { /* ignore */ }
            return null; // 已直接響應
        }

        // 3. 普通請求走默認流程 (設置錯誤信息、轉發)
        return super.execute(ex, cfg, mapping, form, request, response);
    }
}
  1. 在 struts-config.xml 註冊:
<global-exceptions>
  <exception
    handler="com.shop.struts.CustomExceptionHandler"
    key="global.error.message"
    path="/error.jsp"
    type="java.lang.Exception"/> <!-- 捕獲所有未處理異常 -->
</global-exceptions>

最佳實踐總結

場景建議配置
業務校驗失效 (重複、狀態非法)自定義業務異常 + 全局/局部映射 + 友好提示鍵值
系統級異常 (DB 連接失敗、NPE)全局捕獲 java.lang.Exception,統一錯誤頁,記錄日誌
AJAX 接口自定義 Handler 返回 JSON,避免返回整張錯誤頁 HTML
國際化key 對應多語言資源文件,scope="request" 避免污染 Session

遷移提示

Struts 2 以攔截器 (exception interceptor) 替代聲明式配置,功能更強 (結果類型、棧追蹤暴露控制)。但 Struts 1 專案仍廣泛存在,掌握其異常機制對維護遷移至關重要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved