前言
在Web應(yīng)用中,我們經(jīng)常需要對(duì)用戶的請(qǐng)求進(jìn)行某種處理,比如權(quán)限驗(yàn)證、日志記錄等。
Spring框架提供了兩種機(jī)制來(lái)實(shí)現(xiàn)這一需求:攔截器和過(guò)濾器。雖然它們的目標(biāo)相似,但在使用上存在一些差異。本篇文章我們將詳細(xì)探討這兩種機(jī)制的原理、區(qū)別,希望能給各位大佬帶來(lái)幫助!
攔截器(Interceptor)
- 原理
攔截器是Spring MVC框架的一部分,它允許你在請(qǐng)求被實(shí)際處理之前或之后執(zhí)行某些操作。攔截器基于Java的反射機(jī)制,可以攔截到方法級(jí)別的請(qǐng)求。
- 實(shí)現(xiàn)
實(shí)現(xiàn)一個(gè)攔截器需要實(shí)現(xiàn)HandlerInterceptor
接口,并重寫preHandle
、postHandle
和afterCompletion
方法。
其中,preHandle
方法在請(qǐng)求被處理之前調(diào)用,可以用于權(quán)限驗(yàn)證等;postHandle
方法在請(qǐng)求被處理之后,但在視圖渲染之前調(diào)用;afterCompletion
方法在整個(gè)請(qǐng)求處理完成后調(diào)用。
- 配置
在Spring MVC的配置文件中,可以通過(guò)<mvc:interceptors>
標(biāo)簽來(lái)配置攔截器,并指定其攔截的路徑。
- 舉個(gè)栗子
比如我們使用攔截器來(lái)實(shí)現(xiàn)權(quán)限驗(yàn)證。
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 簡(jiǎn)單的權(quán)限驗(yàn)證邏輯
String role = request.getSession().getAttribute("role");
if ("admin".equals(role)) {
return true; // 允許請(qǐng)求繼續(xù)
} else {
response.sendRedirect("/access-denied"); // 重定向到拒絕訪問(wèn)頁(yè)面
return false; // 中斷請(qǐng)求
}
}
}
三、過(guò)濾器(Filter)
- 原理
過(guò)濾器是Servlet規(guī)范的一部分,它允許你在請(qǐng)求到達(dá)Servlet之前或響應(yīng)離開(kāi)Servlet之后執(zhí)行某些操作。過(guò)濾器基于函數(shù)回調(diào),可以攔截到請(qǐng)求和響應(yīng)對(duì)象,但對(duì)具體的處理方法不可見(jiàn)。
- 實(shí)現(xiàn)
實(shí)現(xiàn)一個(gè)過(guò)濾器需要實(shí)現(xiàn)Filter
接口,并重寫doFilter
方法。在該方法中,你可以對(duì)請(qǐng)求和響應(yīng)對(duì)象進(jìn)行操作。
- 配置
在web.xml文件中,可以通過(guò)<filter>
和<filter-mapping>
標(biāo)簽來(lái)配置過(guò)濾器,并指定其過(guò)濾的路徑。
- 舉個(gè)栗子
比如我們使用過(guò)濾器設(shè)置字符編碼。
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8"); // 設(shè)置請(qǐng)求字符編碼
response.setCharacterEncoding("UTF-8"); // 設(shè)置響應(yīng)字符編碼
chain.doFilter(request, response); // 繼續(xù)處理請(qǐng)求
}
}
四、攔截器與過(guò)濾器的區(qū)別
這塊是面試中的重點(diǎn),在秋招中好幾次被問(wèn)到了這一點(diǎn),在這里詳細(xì)總結(jié)下:
- 規(guī)范不同:攔截器是Spring MVC框架的一部分,而過(guò)濾器是Servlet規(guī)范的一部分。
- 攔截級(jí)別不同:攔截器可以攔截到方法級(jí)別的請(qǐng)求,而過(guò)濾器只能攔截到請(qǐng)求和響應(yīng)對(duì)象。
- 使用范圍不同:攔截器只能用于Spring MVC項(xiàng)目,而過(guò)濾器可以用于任何基于Servlet的項(xiàng)目。
- 執(zhí)行順序不同:過(guò)濾器的執(zhí)行順序由其在web.xml中的配置順序決定,而攔截器的執(zhí)行順序由其在Spring MVC配置文件中的配置順序決定。
再舉個(gè)栗子,現(xiàn)在我們要做一個(gè)用戶登錄操作,我們來(lái)看兩者都是怎么實(shí)現(xiàn)的:
-
使用攔截器實(shí)現(xiàn):在
preHandle
方法中,檢查用戶的登錄狀態(tài)。如果用戶已登錄,則返回true讓請(qǐng)求繼續(xù)處理;如果用戶未登錄,則重定向到登錄頁(yè)面。 -
使用過(guò)濾器實(shí)現(xiàn):在
doFilter
方法中,同樣檢查用戶的登錄狀態(tài)。如果用戶已登錄,則調(diào)用chain.doFilter(request, response)
讓請(qǐng)求繼續(xù)處理;如果用戶未登錄,則重定向到登錄頁(yè)面。
文章到這里就先結(jié)束了,感興趣的可以訂閱專欄哈,后續(xù)會(huì)繼續(xù)分享相關(guān)的知識(shí)點(diǎn)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-856516.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-856516.html
到了這里,關(guān)于Spring中的攔截器與過(guò)濾器:原理、區(qū)別與案例解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!