springboot工程中过滤器、拦截器、监听器浅析

filter:过滤器,是 Servlet 技术中最实用的技术。用于过滤掉一些不符合要求的请求。常见场景如session校验、url校验,若不符合条件,则会被过滤掉做出特殊的响应。
interceptor:拦截器,动态拦截 action 调用的对象,然后提供了可以在 action 执行前后增加一些操作。常见场景如登录认证,通过拦截器验证用户的登录状态,若没有登录就会返回一个友好提示;记录日志,记录请求ip、方法执行时间等。
listener:监听器,监听 Web 应用程序中对象的创建、销毁等动作的发送,同时对监听的情况作出相应的处理。常见场景如统计网站的在线人数、访问量等。
实例:
1、创建springboot工程
2、filter
实现过滤器首先需要实现Filter接口,然后重写三个方法,init、destroy、doFilter。

@Log4j2
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //在实例化时创建
        log.info("初始化过滤器");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //HttpServletRequestWrapper,HttpServletResponseWrapper的使用往往配合过滤器Filter使用
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response);
        String requestUri = request.getRequestURI();
        log.info("进入过滤器的请求地址是:{}", requestUri);
        if (requestUri.contains("/addSession") || requestUri.contains("/removeSession") || requestUri.contains("/online") || requestUri.contains("/favicon.ico")) {
            //放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            //返回
            ResponseUtil.returnResultAjax(response, requestUri + " is filtered", "UTF-8");
            //wrapper.sendRedirect("/online");
        }
    }

    @Override
    public void destroy() {
        //在服务关闭时销毁
        log.info("销毁过滤器");
    }
}

3、interceptor
实现拦截器首先需要实现HandlerInterceptor 接口,然后重写三个方法,preHandle、postHandle、afterCompletion。

@Log4j2
@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("进入拦截器的请求地址是:{}", request.getRequestURI());
        request.setAttribute("requestTime", System.currentTimeMillis());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (!request.getRequestURI().contains("/online") && request.getSession(false) != null) {
            HttpSession session = request.getSession();
            String sessionName = (String) session.getAttribute("name");
            if ("caocao".equals(sessionName)) {
                log.info("当前浏览器存在 session:{}",sessionName);
            }
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long duration = System.currentTimeMillis() - Long.parseLong(request.getAttribute("requestTime").toString());
        log.info("进入拦截器的请求地址是:{},耗时:{}ms",request.getRequestURI(), duration);
    }
}

4、listener
实现监听器首先需要实现HttpSessionListener接口,然后重写两个方法。

@Log4j2
public class MyHttpSessionListener implements HttpSessionListener {

    public static AtomicInteger userCount = new AtomicInteger(0);

    @Override
    public synchronized void sessionCreated(HttpSessionEvent sessionEvent) {
        userCount.getAndIncrement();
        sessionEvent.getSession().getServletContext().setAttribute("sessionCount", userCount.get());
        log.info("在线人数人数增加为:{}",userCount.get());
    }

    @Override
    public synchronized void sessionDestroyed(HttpSessionEvent sessionEvent) {
        userCount.getAndDecrement();
        sessionEvent.getSession().getServletContext().setAttribute("sessionCount", userCount.get());
        log.info("在线人数人数减少为:{}",userCount.get());
    }
}
@Log4j2
public class MyHttpRequestListener implements ServletRequestListener {

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
        String requestUri = request.getRequestURI();
        log.info("进入监听器的请求地址是:{}", requestUri);
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        log.info("监听器被销毁");
    }
}

5、实例化

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor myInterceptor;

    /**
     * 注册拦截器
     * @return
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor);
    }

    /**
     * 注册过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new MyFilter());
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }

    /**
     * 注册监听器
     * @return
     */
    @Bean
    public ServletListenerRegistrationBean registrationBean(){
        ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();
        registrationBean.setListener(new MyHttpRequestListener());
        registrationBean.setListener(new MyHttpSessionListener());
        return registrationBean;
    }
}

6、测试

	@GetMapping("addSession")
    public String addSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute("name", "caocao");
        return "当前在线人数:" + session.getServletContext().getAttribute("sessionCount") + "人";
    }

    @GetMapping("removeSession")
    public String removeSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.invalidate();
        return "当前在线人数:" + session.getServletContext().getAttribute("sessionCount") + "人";
    }

    @GetMapping("online")
    public String online() {
        return "当前在线人数:" + MyHttpSessionListener.userCount.get() + "人";
    }

7、结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
filter、interceptor、listener的执行顺序为filter>interceptor>listener(HttpSessionListener),可以理解为从外到内,层层递进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值