0、前言
過濾器、監聽器、攔截器在實際開發中經常需要用到,下面我們來介紹一下spring boot中如何使用;
一、------ 過濾器 -----
1、作用:
過濾器是客戶端與服務器資源文件之間的一道過濾網,可以幫助我們過濾一些不符合要求的請求、可以對服務器的資源請求(如圖片、文件等)進行攔截以實現一些特殊功能以及給予特殊響應;
常用作session校驗、判斷用戶權限、過濾敏感詞匯、壓縮響應信息、控制URL級別訪問權限等
2、實現:
使用過濾器很簡單,只需要實現Filter類,重寫他的三個方法即可:
init:過濾器創建時執行的方法;
destroy:過濾器銷毀時執行的方法
doFilter:主方法,處理邏輯;里面有三個參數,可以通過他們獲得請求的相關信息;
1)創建過濾器類 LogFilter,添加@WebFilter注解
package com.anson.common.filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.IOException; /** * @description: 過濾器 * @author: anson * @Date: 2019/12/20 6:03 */ @WebFilter(filterName = "logfilter1", urlPatterns = "/*") public class LogFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(LogFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { logger.info("----------------------->過濾器被創建"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponseWrapper resp = new HttpServletResponseWrapper((HttpServletResponse) servletResponse); String requestURI = req.getRequestURI(); logger.info("--------------------->過濾器:請求地址"+requestURI); //記錄請求 if(requestURI.contains("info")){ // servletRequest.getRequestDispatcher("/failed").forward(servletRequest, servletResponse); resp.sendRedirect("/failed"); }else{ filterChain.doFilter(servletRequest, servletResponse); } } @Override public void destroy() { logger.info("----------------------->過濾器被銷毀"); } }
2)在啟動類上加入@ServletComponentScan注解
@ServletComponentScan("com.anson.common") //用於支持過濾器、監聽器注解
即可
注意:我們以上采用的注解自動注冊的方式,過濾器還可以采用代碼注冊的方式(略),自己選用一種即可;
二、----- 監聽器 -----
1、作用:
監聽器用於監聽web應用對象的創建、銷毀、增加、修改、刪除等動作的發生,並做出相應的響應處理;
常用於統計在線人數、訪問量、系統加載時信息初始化;
2、分類:
ServletContextListener:對應application,用於監聽ServletContex屬性的操作;
HttpSessionListener: 對應session,用於監聽session對象,常用於統計在線情況;
ServletRequestListener:對應request,監聽request對象的屬性操作;
3、實現:
1}創建監聽器 OnlineSessionListener
package com.anson.common.listener; import com.anson.common.exception.GlobalExceptionHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; //import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; //import javax.servlet.http.HttpSessionEvent; //import javax.servlet.http.HttpSessionListener; /** * @description: TODO * @author: anson * @Date: 2019/12/20 6:48 */ @WebListener public class OnlineSessionListener implements ServletContextListener //HttpSessionListener { private static final Logger logger = LoggerFactory.getLogger(OnlineSessionListener.class); @Override public void contextInitialized(ServletContextEvent servletContextEvent) { logger.info("系統啟動了"); System.out.println("系統啟動了"); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { logger.info("系統停止了"); System.out.println("系統停止了"); } //============================= // public static int online=0; // // @Override // public void sessionCreated(HttpSessionEvent httpSessionEvent) // { // // online ++; // logger.info("有用戶上線了,當前在線人數:" + online); // System.out.println("有用戶上線了,當前在線人數:" + online); // } // // @Override // public void sessionDestroyed(HttpSessionEvent httpSessionEvent) // { // online --; // logger.info("有用戶下線了,當前在線人數:" + online); // System.out.println("有用戶下線了,當前在線人數:" + online); // } }
2)在啟動類上加入@ServletComponentScan注解
@ServletComponentScan("com.anson.common") //用於支持過濾器、監聽器注解
即可
注意:我們以上采用的注解自動注冊的方式,過濾器還可以采用代碼注冊的方式(略),自己選用一種即可;
三、 ------ 攔截器 ------
1、作用:
攔截器是動態攔截action調用的對象,使得可以在action前后增加一些操作,也可以在action執行前停止操作;
常用於登錄認證、記錄操作日志、通用處理等;
2、實現:
使用過濾器很簡單,只需要實現HandlerInterceptor類,重寫他的三個方法即可:
preHandle:處理請求之前被調用;
postHandle:請求執行完后調用;
afterCompletion:在dispatcharservlet完全處理請求后調用,常用於記錄耗時時間,也可用於進行一些資源處理操作;
1)編寫攔截器類MyInterceptor
package com.anson.common.interceptor; import com.anson.common.exception.GlobalExceptionHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @description: 攔截器 * @author: anson * @Date: 2019/12/20 7:23 */ @Component public class MyInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class); public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { logger.info("afterCompletion被調用"); long startime = (Long) arg0.getAttribute("startime"); logger.info("請求耗時:"+ (System.currentTimeMillis() - startime)); } public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { logger.info("postHandle被調用"); } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { logger.info("preHandle被調用"); request.setAttribute("startime",System.currentTimeMillis()); return true; } }
2)增加配置類AppConfigurer,注冊攔截器
package com.anson.config; import com.anson.common.interceptor.MyInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @description: 配置類 * @author: anson * @Date: 2019/12/20 7:35 */ @Configuration public class AppConfigurer implements WebMvcConfigurer { @Autowired private MyInterceptor myInterceptor; //注冊攔截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor); } }
即可
四、后記
過濾器、攔截器、監聽器的簡單用法就是這樣,包括后面要講的AOP,他們在有些功能上是交叉的,根據實際需要靈活選用即可;