Spring Boot 攔截器

來源:互聯網
上載者:User

Spring Boot 攔截器

上一篇對過濾器的定義做了說明,也比較簡單。過濾器屬於Servlet範疇的API,與Spring 沒什麼關係。
Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。

HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之後、視圖渲染之前以及request全部結束之後。我們不能通過攔截器修改request內容,但是可以通過拋出異常(或者返回false)來暫停request的執行。

實現 UserRoleAuthorizationInterceptor 的攔截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor

其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比較常用。

配置攔截器也很簡單,Spring 為什麼提供了基礎類WebMvcConfigurerAdapter ,我們只需要重寫 addInterceptors 方法添加註冊攔截器。

實現自訂攔截器只需要3步:
1、建立我們自己的攔截器類並實現 HandlerInterceptor 介面。
2、建立一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。
2、執行個體化我們自訂的攔截器,然後將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。
PS:本文重點在如何在Spring-Boot中使用攔截器,關於攔截器的原理請大家查閱資料瞭解。

程式碼範例:

MyInterceptor1.java

package org.springboot.sample.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;/** * 自訂攔截器1 * * @author   單紅宇(365384722) * @myblog  http://blog.csdn.net/catoop/ * @create    2016年1月7日 */public class MyInterceptor1 implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        System.out.println(">>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");        return true;// 只有返回true才會繼續向下執行,返回false取消當前請求    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,            ModelAndView modelAndView) throws Exception {        System.out.println(">>>MyInterceptor1>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)            throws Exception {        System.out.println(">>>MyInterceptor1>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet 渲染了對應的視圖之後執行(主要是用於進行資源清理工作)");    }}

MyInterceptor2.java

package org.springboot.sample.interceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;/** * 自訂攔截器2 * * @author   單紅宇(365384722) * @myblog  http://blog.csdn.net/catoop/ * @create    2016年1月7日 */public class MyInterceptor2 implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        System.out.println(">>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");        return true;// 只有返回true才會繼續向下執行,返回false取消當前請求    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,            ModelAndView modelAndView) throws Exception {        System.out.println(">>>MyInterceptor2>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)            throws Exception {        System.out.println(">>>MyInterceptor2>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet 渲染了對應的視圖之後執行(主要是用於進行資源清理工作)");    }}

MyWebAppConfigurer.java

package org.springboot.sample.config;import org.springboot.sample.interceptor.MyInterceptor1;import org.springboot.sample.interceptor.MyInterceptor2;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class MyWebAppConfigurer         extends WebMvcConfigurerAdapter {    @Override    public void addInterceptors(InterceptorRegistry registry) {        // 多個攔截器組成一個攔截器鏈        // addPathPatterns 用於添加攔截規則        // excludePathPatterns 使用者排除攔截        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");        super.addInterceptors(registry);    }}

然後在瀏覽器輸入地址: http://localhost:8080/index 後,控制台的輸出為:

>>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)>>>MyInterceptor2>>>>>>>在請求處理之前進行調用(Controller方法調用之前)>>>MyInterceptor2>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)>>>MyInterceptor1>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)>>>MyInterceptor2>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet 渲染了對應的視圖之後執行(主要是用於進行資源清理工作)>>>MyInterceptor1>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet 渲染了對應的視圖之後執行(主要是用於進行資源清理工作)

根據輸出可以瞭解攔截器鏈的執行順序(具體原理介紹,大家找度娘一問便知)

最後強調一點:只有經過DispatcherServlet 的請求,才會走攔截器鏈,我們自訂的Servlet 請求是不會被攔截的,比如我們自訂的Servlet地址 http://localhost:8080/xs/myservlet 是不會被攔截器攔截的。並且不管是屬於哪個Servlet 只要複合過濾器的過濾規則,過濾器都會攔截。

最後說明下,我們上面用到的 WebMvcConfigurerAdapter 並非只是註冊添加攔截器使用,其顧名思義是做Web配置用的,它還可以有很多其他作用,通過下面便可以大概瞭解,具體每個方法都是幹什麼用的,留給大家自己研究(其實都大同小異也很簡單)。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.