最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC的異常處理和攔截器處理思路解析

 更新時間:2025年09月05日 14:42:29   作者:期待のcode  
這篇文章介紹了SpringMVC的異常處理和攔截器功能,在異常處理部分,詳細說明了如何通過DispatcherServlet捕獲并處理異常,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

SpringMVC的異常處理

異常處理思路:Controller 調(diào)用 service,service 調(diào)用 dao,異常都是向上拋出的,此時 DispatcherServlet 會暫停正常的請求處理流程,轉(zhuǎn)而進入異常處理流程,并將異常交給異常解析器處理。

controller代碼

package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/exception")
public class ExController {
    /**
     * try-catch 處理異常
     */
    @RequestMapping("/findAll.do")
     public String findAll1(){
        try {
            System.out.println("執(zhí)行了...");
            // 模擬異常
            int a = 10 / 0;
        } catch (Exception e) {
            e.printStackTrace();
            //跳轉(zhuǎn)到友好提示頁面
        }
        return "suc";
    }
    /**
     * 使用異常處理器方式
     */
    @RequestMapping("/findAl2.do")
    public String findAll2(){
        System.out.println("執(zhí)行了...");
        // 模擬異常
        int a = 10/0;
        return "suc";
    }
}

自定義異常類(與業(yè)務(wù)相關(guān)的異常),需要遵循JDK異常規(guī)范,繼承 Exception

package com.qcby.model;
public class SysException extends Exception {
    private String message;
    @Override
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public SysException(String message) {
        this.message = message;
    }
}

message 是一個用于存儲異常信息的成員變量,作用是描述當(dāng)前異常發(fā)生的具體原因或詳細信息。當(dāng)創(chuàng)建 SysException 實例時,會將具體的異常描述字符串傳入并賦值給 message,之后可以通過 getMessage() 方法獲取這個信息,用于調(diào)試或向用戶展示錯誤原因。

自定義異常處理器,SpringMVC 提供了 HandlerExceptionResolver 異常處理的核心接口,定義了處理異常的規(guī)范

package com.qcby.util;
import com.qcby.model.SysException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SysExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        // 在控制臺打印異常的信息
        e.printStackTrace();
        // 聲明變量
        SysException exception = null;
        // 如果是自定義的SysException直接強轉(zhuǎn)使用
        if(e instanceof SysException){
            exception = (SysException)e;
        }else {
            // 如果是其他異常,則包裝成一個新的SysException,并設(shè)置默認提示信息
            exception = new SysException("系統(tǒng)正在維護,請聯(lián)系管理員");
        }
        // 存入異常提示信息
        ModelAndView mv = new ModelAndView();
        //Throwable定義了getMessage()方法,用于返回異常/錯誤的詳細描述信息
        mv.addObject("errorMsg",e.getMessage());
        // 設(shè)置跳轉(zhuǎn)的頁面
        mv.setViewName("error");
        return mv;
    }
}

如果捕獲的異常 e 是 SysException 類型,直接強轉(zhuǎn)使用;如果是其他異常,則包裝成一個新的SysException,并設(shè)置默認提示信息 “系統(tǒng)正在維護,請聯(lián)系管理員”,目的是將所有異常統(tǒng)一轉(zhuǎn)為SysException類型,便于后續(xù)統(tǒng)一處理,避免對不同異常類型寫重復(fù)代碼。通過 e.getMessage() 獲取異常的消息文本,將其存入模型中,指定異常發(fā)生時要跳轉(zhuǎn)的視圖名稱為error,最終返回ModelAndView,Spring 會根據(jù)該對象渲染對應(yīng)的錯誤頁面并響應(yīng)給客戶端。

SpringMVC 基于組件式開發(fā),在 springmvc.xml 配置文件中配置異常處理器

    <!--配置異常處理器-->
    <bean id="sysExceptionResolver" class="com.qcby.util.SysExceptionResolver" />

jsp頁面代碼

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>錯誤提示頁面</title>
</head>
<body>
?
	<h3>錯誤的友好提示頁面</h3>
?
	${errorMsg}
?
</body>
</html>

效果展示:

SpringMVC框架中的攔截器

在 SpringMVC 中,攔截器是一種基于 AOP 思想的組件,主要用于對處理器進行預(yù)處理和后處理技術(shù)

攔截器(Filter)和過濾器(Interceptor)的功能比較類似,但有區(qū)別

  • 技術(shù)歸屬與依賴
    過濾器屬于Servlet 規(guī)范的一部分(定義在javax.servlet包中),不依賴任何框架,只要是 Servlet 容器(如Tomcat)就能運行,可以通過web.xml或@WebFilter注解配置過濾器;
    攔截器是 Spring 框架提供的組件(定義在org.springframework.web.servlet包中),依賴于 Spring 容器,僅在 Spring 環(huán)境中生效,其運行需要 Spring 的 DispatcherServlet 調(diào)度,本質(zhì)是 Spring 對請求處理流程的增強。
  • 作用范圍與處理對象
    過濾器處理的是 ServletRequest 和 ServletResponse 對象,關(guān)注的是請求數(shù)據(jù)響應(yīng)數(shù)據(jù)本身,作用于整個請求、響應(yīng)周期,可以處理所有進入 Servlet 容器的請求,覆蓋范圍更廣;
    攔截器只攔截通過 DispatcherServlet 分發(fā)的請求,即處理的是 HandlerMethod(SpringMVC 的 Controller 方法),關(guān)注的是業(yè)務(wù)方法調(diào)用,范圍更窄。
  • 執(zhí)行時機與生命周期
    過濾器的生命周期由 Servlet 容器管理,隨容器啟動而初始化,隨容器關(guān)閉而銷毀;
    攔截器的生命周期由 Spring 容器管理,隨 Spring 上下文初始化而創(chuàng)建,隨上下文銷毀而銷毀。

自定義攔截器步驟

首先需要定義一個controller層的方法用于測試

@Controller
@RequestMapping("/dept")
public class DeptController {
    /**
     * 測試方法
     * @return
     */
    @RequestMapping("/findAll.do")
    public String findAll() {
        System.out.println("controller方法執(zhí)行了...");
        return "suc";
    }
}

創(chuàng)建一個自定義攔截器類,需要實現(xiàn)HandlerInterceptor接口,重寫接口內(nèi)需要的方法

package com.qcby.util;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
    /**
     * 攔截controller中方法
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor的preHandle方法執(zhí)行了...");
        // 手動跳轉(zhuǎn)頁面
        // request.getRequestDispatcher("/WEB-INF/pages/suc.jsp").forward(request,response);
        // 攔截,不放行
        //return false;
        // 放行,執(zhí)行controller中方法
        return true;
    }
}

需要在 springmvc.xml 配置文件中配置攔截器,并指定攔截 / 排除的路徑

    <!--配置攔截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--該攔截器攔截哪些資源-->
            <mvc:mapping path="/dept/**"/>
            <!--哪些資源不攔截
            <mvc:exclude-mapping path="" />
            -->
            <!--攔截器對象-->
            <bean class="com.qcby.util.MyInterceptor1" />
        </mvc:interceptor>
    </mvc:interceptors>

請求路徑:http://localhost:8080/dept/findAll.do
打印結(jié)果如圖:

即 MyInterceptor 攔截器生效了

請求處理的大致流程為:客戶端請求 → 過濾器 → Servlet容器 → DispatcherServlet → 攔截器 → Controller → 攔截器 → DispatcherServlet → 過濾器 → 客戶端響應(yīng)

攔截器圍繞 Controller 方法的調(diào)用,在 HandlerInterceptor 接口中的有三個核心方法:

  • preHandle:是在 Controller 方法執(zhí)行前攔截的方法,可以使用request或者response跳轉(zhuǎn)到指定的頁面;
  • return true 放行,執(zhí)行下一個攔截器,如果沒有攔截器,則執(zhí)行controller中的方法;return false 不放行,會終止后續(xù)流程,包括controller中的方法與后續(xù)攔截器;
  • postHandle:是在 Controller 方法執(zhí)行之后、視圖渲染之前攔截的方法,可以使用request、response的方式或者通過 return "xxx"指定了要跳轉(zhuǎn)的視圖,若指定了跳轉(zhuǎn)的頁面那么跳轉(zhuǎn)操作會覆蓋 Controller 原本指定的頁面,Controller 方法所要跳轉(zhuǎn)的頁面將不會顯示;
  • afterCompletion:是在整個請求處理完成(視圖渲染后)攔截的方法,request或者response不能再跳轉(zhuǎn)頁面了。
package com.qcby.util;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor1 implements HandlerInterceptor {
    /**
     * 攔截controller中的方法
     */
    //controller方法執(zhí)行前攔截的方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
        System.out.println("MyInterceptor1的preHandler方法執(zhí)行了");
        // 手動跳轉(zhuǎn)頁面
        // request.getRequestDispatcher("/WEB-INF/pages/suc.jsp").forward(request,response);
        // 攔截,不放行
        //return false;
        // 放行,執(zhí)行方法
        return true;
    }
    //controller方法執(zhí)行后攔截的方法
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception{
        System.out.println("MyInterceptor1的postHandle方法執(zhí)行了...");
        // 也是可以進行頁面的跳轉(zhuǎn)
        request.getRequestDispatcher("/WEB-INF/pages/suc.jsp").forward(request,response);
        return;
    }
    //controller跳轉(zhuǎn)的jsp頁面都執(zhí)行完成了,最后執(zhí)行該方法
    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex)throws Exception{
        System.out.println("MyInterceptor1的afterCompletion方法執(zhí)行了...");
    }
}

配置多個攔截器

可以定義攔截器鏈,攔截器鏈就是將攔截器按著一定的順序結(jié)成一條鏈,在訪問被攔截的方法時,攔截器鏈中的攔截器會按著定義的順序執(zhí)行

我們再定義一個攔截器

package com.qcby.util;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor2 implements HandlerInterceptor {
    /**
     * 攔截controller中方法
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2的preHandle方法執(zhí)行了...");
        // 放行,執(zhí)行controller中方法
        return true;
    }
    /**
     * controller方法執(zhí)行后,要攔截的方法
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor2的postHandle方法執(zhí)行了...");
    }
    /**
     * controller跳轉(zhuǎn)的jsp頁面都執(zhí)行完成了,最后執(zhí)行該方法
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor2的afterCompletion方法執(zhí)行了...");
    }
}

配置兩個攔截器

    <mvc:interceptors>
        <!--配置攔截器-->
        <mvc:interceptor>
            <!--該攔截器攔截哪些資源-->
            <mvc:mapping path="/dept/**"/>
            <!--哪些資源不想攔截
            <mvc:exclude-mapping path="" />
            -->
            <!--攔截器對象-->
            <bean class="com.qcby.util.MyInterceptor1" />
        </mvc:interceptor>
        <!--配置攔截器-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.qcby.util.MyInterceptor2" />
        </mvc:interceptor>
    </mvc:interceptors>

總結(jié)執(zhí)行順序:

  1. 請求前階段(preHandle):按攔截器注冊順序執(zhí)行(MyInterceptor1→MyInterceptor2);
  2. 目標業(yè)務(wù)(Controller):僅在所有攔截器的 preHandle 都返回 true 后才執(zhí)行;
  3. 響應(yīng)后階段(postHandle、afterCompletion):按注冊逆序執(zhí)行(MyInterceptor2→MyInterceptor1)。

到此這篇關(guān)于SpringMVC的異常處理和攔截器的文章就介紹到這了,更多相關(guān)SpringMVC異常處理和攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于@RequestParam和@RequestBody的用法及說明

    關(guān)于@RequestParam和@RequestBody的用法及說明

    本文主要介紹了Spring框架中參數(shù)綁定相關(guān)的三個注解:@RequestParam、@ModelAttribute和@RequestBody的使用場景和區(qū)別,通過比較它們的使用場景和注意事項,幫助讀者快速理解并正確使用這些注解,避免在項目開發(fā)中出現(xiàn)常見問題
    2026-03-03
  • Spring配置文件中parent與abstract的使用

    Spring配置文件中parent與abstract的使用

    這篇文章主要介紹了Spring配置文件中parent與abstract的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java外部類與內(nèi)部類的關(guān)系詳解

    java外部類與內(nèi)部類的關(guān)系詳解

    本文詳細講解了java外部類與內(nèi)部類的關(guān)系,用代碼演示了外部類調(diào)用內(nèi)部類的方法。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 實例解析Json反序列化之ObjectMapper(自定義實現(xiàn)反序列化方法)

    實例解析Json反序列化之ObjectMapper(自定義實現(xiàn)反序列化方法)

    這篇文章主要介紹了實例解析Json反序列化之ObjectMapper,json自定義序列化的方法,需要的朋友可以了解下。
    2017-09-09
  • SpringBoot調(diào)用公共模塊的自定義注解失效的解決

    SpringBoot調(diào)用公共模塊的自定義注解失效的解決

    這篇文章主要介紹了SpringBoot調(diào)用公共模塊的自定義注解失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java8?lambda表達式的10個實例講解

    Java8?lambda表達式的10個實例講解

    這篇文章主要介紹了Java8?lambda表達式的10個實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java分支循環(huán)與數(shù)組核心知識點總結(jié)

    Java分支循環(huán)與數(shù)組核心知識點總結(jié)

    這篇文章主要介紹了Java分支循環(huán)與數(shù)組核心知識點總結(jié)的相關(guān)資料,理解循環(huán)與分支結(jié)構(gòu)是掌握編程的基礎(chǔ),重復(fù)執(zhí)行操作的循環(huán)和基于條件的執(zhí)行路徑分支有助于構(gòu)建復(fù)雜的程序邏輯,需要的朋友可以參考下
    2026-01-01
  • Java 基于TCP Socket 實現(xiàn)文件上傳

    Java 基于TCP Socket 實現(xiàn)文件上傳

    這篇文章主要介紹了Java 基于TCP Socket 實現(xiàn)文件上傳的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • 詳解Java的Spring框架中bean的注入集合

    詳解Java的Spring框架中bean的注入集合

    這篇文章主要介紹了詳解Java的Spring框架中bean的注入集合,Spring是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • Spring深入刨析聲明式事務(wù)注解的源碼

    Spring深入刨析聲明式事務(wù)注解的源碼

    在spring注解中,使用聲明式事務(wù),需要用到兩個核心的注解:@Transactional注解和@EnableTransactionManagement注解。將@Transactional注解加在方法上,@EnableTransactionManagement注解加在配置類上
    2022-07-07

最新評論

邵东县| 沙田区| 佛山市| 翼城县| 雷州市| 彝良县| 宜川县| 东城区| 左贡县| 邵阳市| 平和县| 化德县| 从江县| 许昌县| 武平县| 新营市| 乐昌市| 海兴县| 兴义市| 武陟县| 连南| 蓬安县| 南溪县| 修水县| 永善县| 临澧县| 秀山| 龙海市| 纳雍县| 余干县| 双流县| 长沙县| 霸州市| 磐安县| 慈利县| 蒙山县| 兰坪| 稷山县| 哈尔滨市| 红原县| 阳东县|