天天看點

springmvc 攔截器_SSM架構(二十三):SpringMVC(5)異常處理器和攔截器

異常處理

異常處理器需要實作HandlerExceptionResolver接口,重寫resolveException方法

異常處理在服務端代碼産生異常後,用于在頁面友好提示,而不是顯示大堆異常資訊

自定義異常類

/**
 * @Author Figo
 * @Date 2019/12/5 23:03
 * 自定義異常類
 */
public class SysException extends Exception{

    // 存儲提示資訊的
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SysException(String message) {
        this.message = message;
    }

}
           
/**
 * @Author Figo
 * @Date 2019/12/5 23:05
 * 異常處理器
 */
public class SysExceptionResolver implements HandlerExceptionResolver {

    /**
     * 處理異常業務邏輯,當控制器抛出異常後,會進入異常處理類執行
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @return
     */
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                         Object handler, Exception ex) {
        // 擷取到異常對象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException)ex;
        }else{
            e = new SysException("系統正在維護....");
        }
        // 建立ModelAndView對象
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        mv.setViewName("error");
        return mv;
    }
}
           

在springmvc.xml中配置異常處理器

<!--配置異常處理器-->
    <bean id="sysExceptionResolver" class="cn.figo.exception.SysExceptionResolver"/>
           

在控制器中抛出異常

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/testException")
    public String testException() throws SysException {
        System.out.println("testException執行了...");
        try {
            // 模拟異常
            int a = 10/0;
        } catch (Exception e) {
            // 列印異常資訊
            e.printStackTrace();
            // 抛出自定義異常資訊
            throw new SysException("查詢所有使用者出現錯誤了...");
        }
        return "success";
    }
}
           

當自造異常時,由于配置了異常處理器,将跳轉到error頁面,而不顯示異常資訊

springmvc 攔截器_SSM架構(二十三):SpringMVC(5)異常處理器和攔截器

同時這個例子由于配置了攔截器,是以在執行控制器方法之前執行了攔截器中的方法

springmvc 攔截器_SSM架構(二十三):SpringMVC(5)異常處理器和攔截器

攔截器

Spring MVC 的處理器攔截器類似于 Servlet 開發中的過濾器 Filter,用于對處理器進行預處理和後處理。

使用者可以自己定義一些攔截器來實作特定的功能。

攔截器鍊(Interceptor Chain),攔截器鍊就是将攔截器按一定的順序聯結成一條鍊。

在通路被攔截的方法或字段時,攔截器鍊中的攔截器就會按其之前定義的順序被調用。

過濾器和攔截器的差別:

過濾器是 servlet 規範中的一部分, 任何 java web 工程都可以使用。

攔截器是 SpringMVC 架構自己的,隻有使用了 SpringMVC 架構的工程才能用。

過濾器在 url-pattern 中配置了/*之後,可以對所有要通路的資源攔截。

攔截器它是隻會攔截通路的控制器方法,如果通路的是 jsp, html,css,image 或者 js 是不會進行攔截的。

攔截器是 AOP 思想的具體應用。

在定義攔截器,需要實作HandlerInterceptor接口,重寫preHandle、postHandle、afterCompletion方法。

preHandle:預處理,在controller方法執行前執行。

此方法的執行時機是在控制器方法執行之前,是以我們通常是使用此方法對請求部分進行增強。 同時由于結果視圖還沒有建立生成,是以此時我們可以指定響應的視圖。

傳回值true放行,執行下一個攔截器,如果沒有,執行controller中的方法。

傳回值false不放行

postHandle:後處理方法,在controller方法執行後,success.jsp執行之前執行

此方法的執行時機是在控制器方法執行之後, 結果視圖建立生成之前。是以通常是使用此方法對響應部分進行增強。因為結果視圖沒有生成,是以我們此時仍然可以控制響應結果。

afterCompletion:success.jsp頁面執行後,該方法會執行。

此方法的執行時機是在結果視圖建立生成之後,展示到浏覽器之前。是以此方法執行時,本次請求要準備的資料具已生成完畢,且結果視圖也已建立完成,是以我們可以利用此方法進行清理操作。同時,我們也無法控制響應結果集内容。

自定義攔截器,要求必須實作: HandlerInterceptor 接口。
/**
 * 自定義攔截器
 */
public class MyInterceptor1 implements HandlerInterceptor {

    /**
     * 預處理,controller方法執行前
     * return true 放行,執行下一個攔截器,如果沒有,執行controller中的方法
     * return false不放行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor1執行了...前1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return true;
    }

    /**
     * 後處理方法,controller方法執行後,success.jsp執行之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor1執行了...後1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
    }

    /**
     * success.jsp頁面執行後,該方法會執行
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor1執行了...最後1111");
    }

}
           

在springmvc.xml中配置攔截器

<!--配置攔截器-->
    <mvc:interceptors>
        <!--配置攔截器-->
        <mvc:interceptor>
            <!--要攔截的具體的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要攔截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置攔截器對象-->
            <bean class="cn.figo.interceptor.MyInterceptor1" />
        </mvc:interceptor>
    </mvc:interceptors>
           

在定義了攔截器之後,我們可以看到執行順序

springmvc 攔截器_SSM架構(二十三):SpringMVC(5)異常處理器和攔截器

如果再配置一個攔截器形成攔截器鍊

<!--配置第二個攔截器-->
        <mvc:interceptor>
            <!--要攔截的具體的方法-->
            <mvc:mapping path="/**"/>
            <!--不要攔截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置攔截器對象-->
            <bean class="cn.figo.interceptor.MyInterceptor2" />
        </mvc:interceptor>
           

輸出如下,道理就是,先進者後出

springmvc 攔截器_SSM架構(二十三):SpringMVC(5)異常處理器和攔截器

繼續閱讀