SpringBoot中的過濾器和攔截器的實現

分手請別帶走鍋發表於2018-06-14

前言

最近在做一個基於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: [/*]
過濾器初始化
複製程式碼

可以看到過濾器已經被初始化了,接下來再訪問一下

SpringBoot中的過濾器和攔截器的實現

日誌:過濾器實現/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>

好了,訪問一下

SpringBoot中的過濾器和攔截器的實現

可以看出過濾器和攔截器都正常執行了

需要注意的是,不同於過濾器,攔截器是spring的元件,不依賴servlet容器,且只有通過DispatcherServlet的請求才能被攔截。所以,過濾器只能用於web程式,而攔截器還可以用於普通java應用。

攔截器可以訪問spring管理的物件以及資源,能方便的呼叫service物件等,所以web應用中優先考慮攔截器。

相關文章