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,他们在有些功能上是交叉的,根据实际需要灵活选用即可;