01.29 聊聊面試中的過濾器與攔截器

背景

做過 JavaWeb 開發的對過濾器和攔截器肯定不會陌生,而且也會熟練的使用,但是關於過濾器和攔截器具體的區別和差異可能不是特別的瞭解,這篇文章就跟大家介紹下過濾器和攔截器的區別。

過濾器 Filter

首先介紹下什麼是過濾器,過濾器英文叫 Filter,是 JavaEE 的標準,依賴於 Servlet 容器,使用的時候是配置在 web.xml 文件中的,可以配置多個,執行的順序是根據配置順序從上到下。常用來配置請求編碼以及過濾一些非法參數,垃圾信息或者是網站登錄驗證碼。

<code>

<filter>
<filter-name>CharacterEncodingFilter/<filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter/<filter-class>
<init-param>
<param-name>encoding/<param-name>
<param-value>UTF-8/<param-value>
/<init-param>
<init-param>
<param-name>forceEncoding/<param-name>
<param-value>true/<param-value>
/<init-param>
/<filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


/<code>

參考實現

<code>
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

public class CaptchaFilter implements Filter {

\t

\tpublic void init(FilterConfig config) throws ServletException {
\t}

\tpublic void destroy() {
\t}

\tpublic void doFilter(ServletRequest servletRequest,
\t\t\tServletResponse servletResponse, FilterChain filterChain)
\t\t\tthrows IOException, ServletException {
\t\tHttpServletRequest request = (HttpServletRequest) servletRequest;
\t\tHttpServletResponse response = (HttpServletResponse) servletResponse;
\t\tString servletPath = request.getServletPath();
\t\t//獲取驗證碼
\t\tif(servletPath.matches("/captcha.jpg")) {
\t\t\tresponse.setContentType("image/jpeg");
\t\t\t//禁止圖像緩存。
\t\t\tresponse.setHeader("Pragma", "no-cache");
\t\t\tresponse.setHeader("Cache-Control", "no-cache");
\t\t\tresponse.setDateHeader("Expires", 0);
\t\t\t//參數:寬、高、字符數、干擾量
\t\t\tCaptchaProductor vCode = new CaptchaProductor(70,30,4,75);

\t\t\t//根據token保存驗證碼內容
\t\t\tCaptchaBean bean = new CaptchaBean();
\t\t\tbean.setCaptcha(vCode.getCode());
\t\t\tbean.setCreateTime(new Date());
\t\t\tHttpSessionUtils.setSessionValue(request, "sessionCaptcha", bean);
\t\t\tvCode.write(response.getOutputStream());
\t\t\treturn;
\t\t}
\t}
}

/<code>

過濾器的實現可以通過實現 Filter 接口或者繼承 Spring 的org.springframework.web.filter.OncePerRequestFilter 來實現。

攔截器 Interceptor

攔截器 Interceptor 不依賴 Servlet 容器,依賴 Spring 等 Web 框架,在 SpringMVC 框架中是配置在SpringMVC 的配置文件中,在 SpringBoot 項目中也可以採用註解的形式實現。攔截器是 AOP 的一種應用,底層採用 Java 的反射機制來實現的。與過濾器一個很大的區別是在攔截器中可以注入 Spring 的 Bean,能夠獲取到各種需要的 Service 來處理業務邏輯,而過濾器則不行。

<code>

<interceptors>

<bean>
/<interceptors>

/<code>

參考實現

<code>
public class AuthInterceptor extends HandlerInterceptorAdapter {

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//todo
super.postHandle(request, response, handler, modelAndView);
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//todo
return super.preHandle(request, response, handler);
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}
}


/<code>

攔截器的實現可以通過繼承org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 來實現。

執行順序

因為我們的過濾器和攔截器都可以配置多個,那麼關於各自的執行順序是什麼樣子的呢?

過濾器的執行順序首先跟在 web.xml 中配置的順序有關,先配置的先執行,但是並不是說是等上一個過濾器執行結束了再執行下一個,它們之間是通過鏈來執行的,具體的過濾器和攔截器的執行過程我畫了個圖,可以看下。


聊聊面試中的過濾器與攔截器


小結

今天簡單的給大家介紹了過濾器和攔截器的區別和使用,希望對大家有幫忙。平時的工作中可能這些東西都是組長或者架構師搭建好的,自己只關注業務邏輯,但是很多時候我們還是要知其然知其所以然,多瞭解一些對自己是很有幫助的。


分享到:


相關文章: