監聽器Listener,它是實現了javax.servlet.XXXListener接口的服務器端程序,它也是隨web應用的啓動而啓動,只初始化一次,隨web應用的中止而銷燬。主要做用是:作一些初始化的內容添加工做、設置一些基本的內容、好比一些參數或者是一些固定的對象等等。java
在javax.servlet.XXXListener接口中定義了2種方法:web
void contextInitialized(ServletContextEvent sce) 監聽器的初始化spring
void contextDestroyed(ServletContextEvent sce) 監聽器銷燬json
Servlet中的過濾器Filter是實現了javax.servlet.Filter接口的服務器端程序,主要的用途是過濾字符編碼、作一些業務邏輯判斷等。其工做原理是,只要你在web.xml文件配置好要攔截的客戶端請求,它都會幫你攔截到請求,此時你就能夠對請求或響應(Request、Response)統一設置編碼,簡化操做;同時還能夠進行邏輯判斷,如用戶是否已經登陸、有沒有權限訪問該頁面等等工做,它是隨你的web應用啓動而啓動的,只初始化一次,之後就能夠攔截相關的請求,只有當你的web應用中止或從新部署的時候才能銷燬。服務器
在javax.servlet.Filter接口中定義了3個方法:session
void init(FilterConfig filterConfig) 用於完成過濾器的初始化app
void destroy() 用於過濾器銷燬前,完成某些資源的回收ide
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 實現過濾功能,該方法對每一個請求增長額外的處理工具
攔截器主要是用在插件上,擴展件上好比spring、struts2等有點相似面向切片的技術,它是基於java反射機制。定義攔截器: 實現HandlerInterceptor 接口,或者繼承實現了HandlerInterceptor 接口的類(經常使用) 。post
過濾器(Filter):當你有一堆東西的時候,你只但願選擇符合你要求的某一些東西。定義這些要求的工具,就是過濾器。 對請求起到過濾的做用,它在監聽器以後,做用在servlet以前,對請求進行過濾。
攔截器(Interceptor):在一個流程正在進行的時候,你但願干預它的進展,甚至終止它進行,這是攔截器作的事情。
監聽器(Listener):當一個事件發生的時候,你但願得到這個事件發生的詳細信息,而並不想幹預這個事件自己的進程,這就要用到監聽器。對項目起到監聽的做用,它能感知到包括request(請求域),session(會話域)和applicaiton(應用程序)的初始化和屬性的變化 。對請求和返回進行攔截,它做用在servlet的內部 。
它們之間的關係,能夠用一張圖來表示:
使用原則
對整個流程清楚以後,而後就是各自的使用,在使用以前應該有一個使用規則,爲何這個說,由於有些功能好比判斷用戶是否登陸,既能夠用過濾器,也能夠用攔截器,用哪個纔是合理的呢?那麼若是有一個原則,使用起來就會更加合理。實際上這個原則是有的:把整個項目的流程比做一條河,那麼監聽器的做用就是可以聽到河流裏的全部聲音,過濾器就是可以過濾出其中的魚,而攔截器則是攔截其中的部分魚,而且做標記。因此當須要監聽到項目中的一些信息,而且不須要對流程作更改時,用監聽器;當須要過濾掉其中的部分信息,只留一部分時,就用過濾器;當須要對其流程進行更改,作相關的記錄時用攔截器。
代碼註冊方式
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class IndexListener implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent arg0) { System.out.println("IndexListener contextDestroyed method"); } @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("IndexListener contextInitialized method"); } }
@Bean public ServletListenerRegistrationBean servletListenerRegistrationBean(){ ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean(); servletListenerRegistrationBean.setListener(new IndexListener()); return servletListenerRegistrationBean; }
註解方式
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class IndexListener2 implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent arg0) { System.out.println("IndexListener2 contextDestroyed method"); } @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("IndexListener2 contextInitialized method"); } }
@SpringBootApplication @ServletComponentScan public class SpringBootSimpleApplication { public static void main(String[] args) { SpringApplication.run(SpringBootSimpleApplication.class, args); } }
代碼註冊方式
public class TestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (......) { ...... response.getWriter().write(writeValueAsString); } else { chain.doFilter(request, response); } } @Override public void destroy() { } }
@Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); TestFilter testFilter = new TestFilter(); registrationBean.setFilter(testFilter); List<String> urlPatterns = new ArrayList<String>(); urlPatterns.add("/service/extract/json/*"); registrationBean.setUrlPatterns(urlPatterns); return registrationBean; }
註解方式
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; /** * 實現javax.servlet.Filter,覆蓋其三個方法 * @author Administrator * */ @WebFilter(filterName="testFilter",urlPatterns="/*") public class TestFilter implements Filter{ @Override public void destroy() { System.out.println("TestFilter過濾器銷燬"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("TestFilter指定過濾器操做......"); //執行操做後必須doFilter chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { System.out.println("TestFilter初始化......"); } }
@SpringBootApplication @ServletComponentScan public class SpringBootSimpleApplication { public static void main(String[] args) { SpringApplication.run(SpringBootSimpleApplication.class, args); } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class CustomInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) throws Exception { //在整個請求結束以後被調用,也就是在DispatcherServlet 渲染了對應的視圖以後執行(主要是用於進行資源清理工做) System.out.println("3. 整個請求結束以後被調用......CustomInterceptor1......"); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView view) throws Exception { // 請求處理以後進行調用,可是在視圖被渲染以前 System.out.println("2. 請求處理以後進行調用,可是在視圖被渲染以前......CustomInterceptor1......"); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { // 在請求處理以前進行調用 System.out.println("1. 在請求處理以前進行調用......CustomInterceptor1......"); // 只有返回true纔會繼續向下執行,返回false取消當前請求 return true; } }
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.example.Interceptor.CustomInterceptor; import com.example.Interceptor.CustomInterceptor2; /** * 繼承WebMvcConfigurerAdapter,複寫addInterceptors方法 * @author Administrator * */ @Configuration public class WebAdapter extends WebMvcConfigurerAdapter{ /** * 主要方法說明: * addPathPatterns 用於添加攔截規則 * excludePathPatterns 用於排除攔截 */ @Override public void addInterceptors(InterceptorRegistry registry) { //衆多的攔截器組成了一個攔截器鏈 registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/*"); super.addInterceptors(registry); } }