前言
最近在做一個基於springboot的專案,順便總結一下springboot專案中的過濾器、攔截器和以前專案的區別。
一、過濾器
1.SpringBoot中使用過濾器不需要在web.xml中配置filter,只需要新增註解@WebFilter同時實現Filter介面
import java.io.IOException;
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 javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
@Component
@WebFilter(urlPatterns = "/*", filterName = "test")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("過濾器初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.printf("過濾器實現");
System.out.println(((HttpServletRequest) servletRequest).getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("過濾器銷燬了");
}
}
複製程式碼
啟動專案後檢視日誌:
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'webStatFilter' to urls: [/*]
INFO 6780 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'testFilter' to: [/*]
過濾器初始化
複製程式碼
可以看到過濾器已經被初始化了,接下來再訪問一下
日誌:過濾器實現/test
複製程式碼
說明過濾器已經正常執行(剛開始發現被呼叫了兩次,第二次url列印的是/favicon.ico,這是瀏覽器在請求網站圖示)
二、攔截器
首先建立攔截器MyInterceptor實現HandlerInterceptor
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* 攔截器
*/
public class MyInterceptor implements HandlerInterceptor{
//在請求處理之前進行呼叫(Controller方法呼叫之前
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse
httpServletResponse, Object o) throws Exception {
System.out.println("preHandle被呼叫");
System.out.println("實現攔截器");
return true;
}
//請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse
httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle被呼叫");
}
//在整個請求結束之後被呼叫,也就是在DispatcherServlet
渲染了對應的檢視之後執行
@Override
public void afterCompletion(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion被呼叫");
}
}
複製程式碼
然後建立一個配置類,用於註冊攔截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 註冊攔截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").
excludePathPatterns("/a.do");
}
}
複製程式碼
addPathPatterns和excludePathPatterns可以分別指定要攔截的請求和排除的請求,引數也可以是一個List<string>
好了,訪問一下
可以看出過濾器和攔截器都正常執行了
需要注意的是,不同於過濾器,攔截器是spring的元件,不依賴servlet容器,且只有通過DispatcherServlet的請求才能被攔截。所以,過濾器只能用於web程式,而攔截器還可以用於普通java應用。
攔截器可以訪問spring管理的物件以及資源,能方便的呼叫service物件等,所以web應用中優先考慮攔截器。