昨天晚上做夢,夢見面試官問我過濾器和攔截器的區別。。。
過濾器和攔截器的區別:
1、過濾器和攔截器觸發時機不一樣,過濾器是在請求進入容器后,但請求進入servlet之前進行預處理的。
請求結束返回也是,是在servlet處理完后,返回給前端之前。
2、攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,因為攔截器是spring提供並管理的,
spring的功能可以被攔截器使用,在攔截器里注入一個service,可以調用業務邏輯。
而過濾器是JavaEE標准,只需依賴servlet api ,不需要依賴spring。
3、過濾器的實現基於回調函數。而攔截器(代理模式)的實現基於反射,代理分靜態代理和動態代理,
動態代理是攔截器的簡單實現。
何時使用攔截器?何時使用過濾器?
如果是非spring項目,那么攔截器不能用,只能使用過濾器。
如果是處理controller前后,既可以使用攔截器也可以使用過濾器。
如果是處理dispaterServlet前后,只能使用過濾器。
過濾器注解實現:
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /** * @author maxixnhai * @PackageName www.maxinhai.com.diary.common.filter * @ClassName AuthFilter * @Description * @date 2020/4/5 17:41 */ @WebFilter(urlPatterns = "/*", filterName = "authFilter") public class AuthFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long start = System.currentTimeMillis(); Object name = request.getParameter("name"); System.out.println("name => " + name); for(int i=0; i<10000; i++) { //System.out.println("過濾器打印: " + i); } long end = System.currentTimeMillis(); System.out.println("authFilter 耗時: " + (end - start)); } @Override public void destroy() { } }
注解實現需要在啟動器(本文為SpringBoot) 添加 @ServletComponentScan("www.maxinhai.com.diary.common") 掃描過濾器。
非注解實現的話,需要在web.xml添加如下配置:
<!-- 配置登陸過濾器 --> <filter> <filter-name>authFilter</filter-name> <filter-class>www.maxinhai.com.filter.AuthFilter</filter-class> <init-param> <param-name>passUrl</param-name> <param-value>index;FunctionServlet</param-value> </init-param> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>