Spring MVC整合異常解析器和攔截器

使用Spring MVC讓我們的開發變的更加方便,今天的內容介紹有關異常解析器和攔截器的相關內容

異常解析器:Controller中的Handler中可能會有要處理的異常,而且有時是重複的異常,我們定義異常解析器之後就可以在每個Handler只需拋出異常,然後異常解析器會幫我們執行,並重定向到要提示的錯誤頁面

攔截器:Controller中的Handler中可能會有冗餘的功能(代碼),比如:有多個Handler中都要判斷登錄的狀態,只有登錄之後才能進行下一步的操作,使用攔截器中將冗餘的功能分離出來,即可以減少代碼量,也可以讓維護變的簡單

異常解析器

現有方案,分散處理

controller中的每個Handler自己處理異常

此種處理方案,異常處理邏輯,分散在各個handler中,不利於集中管理,而且可能多個handler中處理的異常時相同的處理邏輯,導致代碼冗餘

public String xxx(){
    try{
        ...
    }catch(Exception1 e){
        e.printStackTrace();
        return "redirect:xxx/error1.jsp";
    }atch(Exception2 e){
        e.printStackTrace();
        return "redirect:xxx/error2.jsp";
    }
    return "success";
}

異常解析器,統一處理

Controller中每個Handler不再自己處理異常,而是直接throws所有異常

定義一個"異常解析器"集中捕獲處理所有的異常

此種方案,在集中管理異常方面,更有優勢

  • 執行時機:任何一個handler拋出異常時

定義了一個異常解析器

/**
 * 異常解析器
 * 執行時機:任何一個handler拋出異常時
 */
public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        if (e instanceof MyException1){
            modelAndView.setViewName("redirect:/error1.jsp");
        }else if (e instanceof MyException2){
            modelAndView.setViewName("redirect:/error2.jsp");
        }else if (e instanceof MyException3){
            modelAndView.setViewName("redirect:/error3.jsp");
        }
        return modelAndView;
    }
}

在Spring中對該異常解析器進行註冊就可以使用

這樣我們之後在handler中發生異常時,只需要將異常拋出

模擬在handler中異常的拋出

@RequestMapping("test1")
public String xxx(Integer id){
	if(id==1){
        throws new MyExcetion1("test ex1");
    }
    return "success";
}

在定義了異常解析器時,我們的handler如果發生我們拋出的異常,那麼就會由異常解析器將其轉到我們定義要轉跳的錯誤頁面.

總結:

以後在我們的項目中只需要定義一個異常解析器,那麼所有handler都不需要自己直接處理異常,只需要拋出由異常解析器處理即可.

攔截器

作用:抽取handler冗餘功能

定義攔截器

執行順序是:

perHandler-postHandler-afterHandler

舉例:

比如在一個Controller中有登錄,查詢所有用戶,刪除一個用戶三個Handler,er查詢所有用戶和刪除一個用戶都是需要判斷在登錄的條件下才能操作

那麼在這兩個Handler中就有大量的重複的功能(代碼)

package per.leiyu.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author 雷雨
 * @date 2020/6/27 16:34
 */
public class MyInterceptor  implements HandlerInterceptor {
    /**
     * 在Handler在前執行
     * 在其中定義Handler中冗餘的功能
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //我們可以在這做關於登錄狀態
        HttpSession session=  httpServletRequest.getSession();
        if (session!=null){
            return true;
        }else{
            //中斷請求之前,響應請求,把它重定向到登錄頁面
            httpServletResponse.sendRedirect("login.jsp");
            return false;
        }

    }

    /**
     * 在Handler之後執行,但是在響應之前執行
     * 可以改動請求中的數據
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 在視圖渲染完畢之後執行,也就是在響應之後執行
     * 一般用來做資源的回收
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

配置攔截器

定義了攔截器,要配置攔截器,告訴Spring工廠,也要告訴我們攔截器要攔截的路徑是什麼

<!-- 攔截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="要攔截的handler的路徑"/>
        <!-- 支持的寫法 -->
        <!--<mvc:mapping path="/inter/test1"/> -->
        <!--<mvc:mapping path="/inter/test2"/> -->
        <!--<mvc:mapping path="/inter/*"/> -->
        <!--<mvc:mapping path="/inter/test*"/> -->
        <!--<mvc:mapping path="/inter/**"/> 包含inter中的所有子路徑的handler  -->
        <!--<mvc:exclude-mapping path="/inter/test1"/>  表示不包含(不攔截)的handler的路徑 -->
        <bean class="攔截器的路徑"/>
    </mvc:interceptor>
</mvc:interceptors>
    

我是雷雨,一個普本科的學生,主要專注於Java後端和大數據開發

如果這篇文章有幫助到你,希望你給我一個大大的贊
如果有什麼問題,希望你能留言和我一起研究,學習靠自覺,分享靠自願

轉載註明出處
https://blog.csdn.net/qq_40742223

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章