• 小白的springboot之路(十三)、过滤器、监听器、拦截器


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

  • 相关阅读:
    mysql初始化/usr/local/mysql/bin/mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory
    centos重启出现type Control-D to continue【fsck使用】
    find 常用命令
    保持简单----纪念丹尼斯•里奇(Dennis Ritchie)
    最有效的五个方法,彻底控制你的负面情绪,你有吗
    ERROR 1366 (HY000): Incorrect string value: 'xE9x83x91xE5xB7x9E' for column 'aa' at row 1 MySQL 字符集
    Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
    mysql从5.6升级到5.7后出现 Expression #1 of ORDER BY clause is not in SELECT list,this is incompatible with DISTINCT
    mysqld_safe error: log-error set to '/data/log/mysqld.log', however file don't exists. Create writable for user 'mysql'.The server quit without updating PID file (/data/mysql/mysqld.pid)
    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
  • 原文地址:https://www.cnblogs.com/yanghj/p/12071296.html
Copyright © 2020-2023  润新知