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

Spring MVC 異常處理四大方案全解析

     編輯:Java 綜合教學

Spring MVC 異常處理四大方案全解析

企業級應用需統一處理控制層、服務層、資料層拋出的異常,避免重複 try-catch 污染業務代碼。Spring MVC 提供四種異常處理機制:SimpleMappingExceptionResolver(XML 配置)、繼承 SimpleMappingExceptionResolver 自定義、實作 HandlerExceptionResolver 介面、@ExceptionHandler 註解。本文以自定義業務異常體系為例,完整示範四種方案的配置與代碼。

業務異常體系設計

// 基礎業務異常
public class UserException extends Exception { ... }

// 具體異常
public class NameException extends UserException { ... }
public class AgeException  extends UserException { ... }

方案一:SimpleMappingExceptionResolver(零代碼,純 XML)

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="error.jsp" />          <!-- 預設錯誤頁 -->
    <property name="exceptionAttribute" value="ex" />               <!-- 頁面取異常 ${ex.message} -->
    <property name="exceptionMappings">                             <!-- 指定異常對應頁面 -->
        <props>
            <prop key="cn.zhang.exception.AgeException">error/ageerrors.jsp</prop>
            <prop key="cn.zhang.exception.NameException">error/nameerrors.jsp</prop>
        </props>
    </property>
</bean>

Controller 拋出異常即自動跳轉對應頁面。

方案二:繼承 SimpleMappingExceptionResolver 自定義

若需在解析過程中記錄日誌、發送告警,可繼承並覆寫 doResolveException:

public class CustomExceptionResolver extends SimpleMappingExceptionResolver {
    @Override
    protected ModelAndView doResolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
        log.error("業務異常", ex);
        // 可在此動態決定視圖
        return super.doResolveException(req, resp, handler, ex);
    }
}

XML 註冊:<bean class="cn.zhang.resolvers.CustomExceptionResolver" />

方案三:實作 HandlerExceptionResolver 介面(完全控制)

public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex", ex);
        mv.setViewName("/errors.jsp"); // 預設

        if (ex instanceof NameException) mv.setViewName("/error/nameerrors.jsp");
        if (ex instanceof AgeException)  mv.setViewName("/error/ageerrors.jsp");
        return mv;
    }
}

XML 註冊:<bean class="cn.zhang.resolvers.MyHandlerExceptionResolver" />

方案四:@ExceptionHandler 註解(推薦,貼近業務)

@Controller
public class MyHandlerExceptionResolver {
    @ExceptionHandler
    public ModelAndView resolveException(Exception ex) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex", ex);
        mv.setViewName("/errors.jsp");
        if (ex instanceof NameException) mv.setViewName("/error/nameerrors.jsp");
        if (ex instanceof AgeException)  mv.setViewName("/error/ageerrors.jsp");
        return mv;
    }
}

Controller 繼承該類或掃描到同包即可生效。優勢:可直接在 Controller 類內定義處理方法,支援多方法處理不同異常,程式碼內聚性高。

四種方案對比

方案優點缺點適用場景
SimpleMappingExceptionResolver零代碼、集中配置無法執行自定義邏輯(日誌、告警)簡單專案、快速原型
繼承 SimpleMappingExceptionResolver擴充點清晰、復用 XML 映射仍受限於父類流程需在解析前後加邏輯
實作 HandlerExceptionResolver完全控制解析流程樣板代碼多、需手動判斷異常型別複雜異常處理邏輯
@ExceptionHandler程式碼內聚、支援多方法、可注入 Spring Bean分散在各 Controller/Advice 類現代 Spring MVC 首選

最佳實踐建議

  1. 定義統一錯誤碼枚舉,異常攜帶錯誤碼,前端依碼顯示國際化訊息。
  2. 使用 @ControllerAdvice 定義全域異常處理類,集中管理所有 @ExceptionHandler 方法。
  3. 區分業務異常(預期內,如參數校驗失敗)與系統異常(預期外,如 NPE、DB 宕機),前者回傳友好提示,後者記錄完整堆疊並回傳通用錯誤頁。
  4. REST API 回傳 JSON 統一格式:{code, message, data},配合 @ResponseBody + ResponseEntity 控制 HTTP 狀態碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved