SpringBoot過濾器與攔截器使用方法深入分析
什么是過濾器
過濾器 Filter 基于 Servlet 實現(xiàn),過濾器的主要應(yīng)用場景是對字符編碼、跨域等問題進行過濾。Servlet 的工作原理是攔截配置好的客戶端請求,然后對 Request 和 Response 進行處理。Filter 過濾器隨著 web 應(yīng)用的啟動而啟動,只初始化一次。
Filter 使用時需要繼承 Filter 接口,實現(xiàn)對應(yīng)的 init、doFilter 以及 destroy 方法即可。
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.springframework.stereotype.Component; @Component public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("初始化攔截器"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //做一些處理 System.out.println("doSomeThing"); chain.doFilter(request,response); } @Override public void destroy() { System.out.println("銷毀攔截器"); } }
1、init:在容器啟動時調(diào)用初始化方法,只會初始化一次
2、doFilter:每次請求都會調(diào)用 doFilter 方法,通過 FilterChain 調(diào)用后續(xù)的方法。
3、destroy:當容器銷毀時,執(zhí)行 destory 方法,只會被調(diào)用一次。
什么是攔截器
攔截器是 SpringMVC 中實現(xiàn)的一種基于 Java 反射(動態(tài)代理)機制的方法增強工具,攔截器的實現(xiàn)是繼承 HandlerInterceptor 接口,并實現(xiàn)接口的 preHandle、postHandle 和 afterCompletion 方法。
1、preHandle:請求方法前置攔截,該方法會在 Controller 處理之前進行調(diào)用,Spring 中可以有多個 Interceptor,這些攔截器會按照設(shè)定的 Order 順序調(diào)用,當有一個攔截器在 preHandle 中返回 false 的時候,請求就會終止。
2、postHandle:preHandle 返回結(jié)果為 true 時,在 Controller 方法執(zhí)行之后,視圖渲染之前被調(diào)用
3、afterCompletion:在 preHandle 返回 ture,并且整個請求結(jié)束之后,執(zhí)行該方法。
具體的代碼實現(xiàn)如下,首先編寫一個攔截器:
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); String userName=request.getParameter("username"); String password = request.getParameter("password"); if (userName==null||password==null){ response.setStatus(500); response.setContentType("text/html; charset=UTF-8"); response.getWriter().print("參數(shù)缺失"); return false; } //進行用戶校驗 if (userName.equals("admin")&&password.equals("admin")){ return true; }else { response.setStatus(500); response.setContentType("text/html; charset=UTF-8"); response.getWriter().print("用戶名或密碼錯誤"); return false; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
編寫完攔截器之后,通過一個配置類設(shè)置攔截器,并且可以通過 addPathPatterns 和 excludePathPatterns 執(zhí)行哪些請求需要被攔截,哪些不需要被攔截。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MvcConfig implements WebMvcConfigurer { @Autowired private UserInterceptor userInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor) .addPathPatterns("/**") .excludePathPatterns("/error"); } }
再次訪問 /test 頁面,如果不帶任何參數(shù),就會在頁面上提示 參數(shù)缺失。只有當帶上參數(shù) /test?username=admin&password=admin 才能夠訪問。
攔截器與過濾器的區(qū)別
相同點:
1、 攔截器與過濾器都是體現(xiàn)了 AOP 的思想,對方法實現(xiàn)增強,都可以攔截請求方法。
2、 攔截器和過濾器都可以通過 Order 注解設(shè)定執(zhí)行順序
不同點:
1、 過濾器屬于 Servlet 級別,攔截器屬于 Spring 級別。
Filter 是在 javax.servlet 包中定義的,要依賴于網(wǎng)絡(luò)容器,因此只能在 web 項目中使用。
Interceptor 是 SpringMVC 中實現(xiàn)的,歸根揭底攔截器是一個 Spring 組件,由 Spring 容器進行管理。
2、過濾器和攔截器的執(zhí)行順序不同:
下面通過一張圖展示 Filter 和 Interceprtor 的執(zhí)行順序:
首先當一個請求進入 Servlet 之前,過濾器的 doFilter 方法進行過濾,進入 Servlet 容器之后,執(zhí)行 Controller 方法之前,攔截器的 preHandle 方法進行攔截,執(zhí)行 Controller 方法之后,視圖渲染之前,攔截器的 postHandle 方法進行攔截,請求結(jié)束之后,執(zhí)行攔截器的 postHandle 方法。
3、 過濾器基于函數(shù)回調(diào)方式實現(xiàn),攔截器基于 Java 反射(動態(tài)代理)機制實現(xiàn)。
到此這篇關(guān)于SpringBoot過濾器與攔截器使用方法深入分析的文章就介紹到這了,更多相關(guān)SpringBoot過濾器與攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java基于SpringBoot和tk.mybatis實現(xiàn)事務(wù)讀寫分離代碼實例
這篇文章主要介紹了Java基于SpringBoot和tk.mybatis實現(xiàn)事務(wù)讀寫分離代碼實例,讀寫分離,基本的原理是讓主數(shù)據(jù)庫處理事務(wù)性增、改、刪操作,而從數(shù)據(jù)庫處理SELECT查詢操作,數(shù)據(jù)庫復制被用來把事務(wù)性操作導致的變更同步到集群中的從數(shù)據(jù)庫,需要的朋友可以參考下2023-10-10elasticsearch bucket 之rare terms聚合使用詳解
這篇文章主要為大家介紹了elasticsearch bucket 之rare terms聚合使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11Java生產(chǎn)者和消費者例子_動力節(jié)點Java學院整理
生產(chǎn)者-消費者(producer-consumer)問題,也稱作有界緩沖區(qū)(bounded-buffer)問題,兩個進程共享一個公共的固定大小的緩沖區(qū)。下文通過實例給大家介紹java生產(chǎn)者和消費者,感興趣的朋友一起學習吧2017-05-05SpringBoot使用Redisson實現(xiàn)延遲執(zhí)行的完整示例
這篇文章主要介紹了SpringBoot使用Redisson實現(xiàn)延遲執(zhí)行的完整示例,文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-06-06Java的Socket網(wǎng)絡(luò)編程基礎(chǔ)知識入門教程
這篇文章主要介紹了Java的Socket網(wǎng)絡(luò)編程基礎(chǔ)知識入門教程,包括基于TCP/IP和UDP協(xié)議的簡單實例程序講解,需要的朋友可以參考下2016-01-01