关注Java后端技术全栈

回复“面试”获取全套大厂面试资料

在开发中用到过滤器、监听器、拦截器的场景非常多,今天就来聊聊这三者在日常开发中是如何使用的。

概念和使用场景

监听器

listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。

实现方式:实现接口javax.servlet.http.HttpSessionListener

其主要可用于以下方面:

  • 统计在线人数和在线用户

  • 系统启动时加载初始化信息

  • 统计网站访问量

  • 记录用户访问路径

过滤器

Filter是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源。过滤器是在请求进入tomcat容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

  • 例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能

  • 例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能

它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。过滤器只在servlet前后起作用,所以它既不能捕获异常,获得bean对象等

实现方式:实现接口javax.servlet.Filter

拦截器

拦截器中用于在某个方法或字段被访问之前,进行拦截然后,在之前或之后加入某些操作。比如日志,安全等。一般拦截器方法都是通过动态代理的方式实现。可以通过它来进行权限验证,或者判断用户是否登陆,或者是像12306 判断当前时间是否是购票时间。通常在项目开发中基本上都会做一个异常统一拦截处理的地方。对比一下其实我们可以发现,过滤器能做的事拦截器都能做,二拦截器做的事过滤器不一定做的了。

实现方式:实现org.springframework.web.servlet.HandlerInterceptor

三者对比

拦截器和过滤器:过滤前->拦截前->action/controller执行->拦截后->过滤后

为了让大家更好的理解,这里借用网上几张图:


实战

项目继续使用之前文章中用到的项目。

添加过滤器
import java.io.IOException;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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;public class UserFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(servletRequest.getParameter("name"));HttpServletRequest hrequest = (HttpServletRequest) servletRequest;HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);//过滤URI存在部分关键字的if (hrequest.getRequestURI().indexOf("/index") != -1 ||hrequest.getRequestURI().indexOf("/online") != -1 ||hrequest.getRequestURI().indexOf("/login") != -1) {filterChain.doFilter(servletRequest, servletResponse);} else {wrapper.sendRedirect("/login");}}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}
}

自定义Filter还可以 使用Servlet3.0的注解进行配置第三步的@WebFilter就是3.0的注解

1)启动类里面增加 @ServletComponentScan,进行扫描

2)新建一个Filter类,implements Filter,并实现对应的接口

3) @WebFilter 标记一个类为filter,被spring进行扫描

urlPatterns:拦截规则,支持正则

4)控制chain.doFilter的方法的调用,来实现是否通过放行不放行,web应用resp.sendRedirect("/index.html");场景:权限控制、用户登录(非前端后端分离场景)等

添加监听器

监听器就会联想到监听器设计模式。就相当于于考试的时候,考官一直盯着你们,一旦有人有动静,考官就一直监督者你们,一旦有人作弊,考官马上将其拿下。

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;public class UserHttpSessionListener implements HttpSessionListener {//监控在线人数public static int online = 0;@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("创建session");online++;}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("销毁session");}
}
添加拦截器
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;public class UserInterceptor implements HandlerInterceptor {//进入controller方法之前@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println("preHandle被调用");System.out.println(httpServletRequest.getParameter("username"));if(httpServletRequest.getParameter("username").equals("zhangsan")) {return true;   }else {//如果false,停止流程,api被拦截//通常验证是都登录,如果没有登录则进行登录操作PrintWriter printWriter = httpServletResponse.getWriter();printWriter.write("please login again!");return false;}}//调用完controller之后,视图渲染之前@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("postHandle被调用");}//整个完成之后,通常用于资源清理@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("afterCompletion被调用");}
}

preHandle方法是在我们的controller方法执行之前调用的。

添加配置类
package com.example.demo.config;import com.example.demo.filter.UserFilter;
import com.example.demo.listener.UserHttpSessionListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;//主拦截器,根据拦截不同路径跳转不同自定义拦截器
@Configuration
public class UserWebConfig implements WebMvcConfigurer {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/index").setViewName("login");}@SuppressWarnings({ "rawtypes", "unchecked" })@Beanpublic FilterRegistrationBean filterRegist() {FilterRegistrationBean frBean = new FilterRegistrationBean();frBean.setFilter(new UserFilter());frBean.addUrlPatterns("/*");System.out.println("filter");return frBean;}@SuppressWarnings({ "rawtypes", "unchecked" })@Beanpublic ServletListenerRegistrationBean listenerRegistry() {ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();srb.setListener(new UserHttpSessionListener());System.out.println("listener");return srb;}
}

测试类,写个controller来测试

package com.example.demo;import java.util.Date;
import java.util.Map;
import java.util.UUID;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;import com.example.demo.listener.UserHttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class UserController {private final Logger logger = LoggerFactory.getLogger(UserController.class);@GetMapping("/welcome")public String welcome(Map<String, Object> model) {model.put("time", new Date());model.put("message", "hello world");return "welcome";}@RequestMapping("/login")@ResponseBodypublic Object login() {logger.info("-----login---");return "login";}@RequestMapping("/index/{name}")@ResponseBodypublic Object index(@PathVariable String name, HttpServletRequest request) {HttpSession session = request.getSession(true);session.setAttribute(UUID.randomUUID().toString(), name);return "index";}@RequestMapping("/online")@ResponseBodypublic Object online() {return "当前在线人数:" + UserHttpSessionListener.online + "人";}
}

以上便是今天分享的监听器、过滤器、拦截器的相关知识。建议大家手动试试~

纸上得来终觉浅,绝知此事要躬行。

IT技术分享社区

个人博客网站:https://programmerblog.xyz

文章推荐程序员效率:画流程图常用的工具程序员效率:整理常用的在线笔记软件远程办公:常用的远程协助软件,你都知道吗?51单片机程序下载、ISP及串口基础知识硬件:断路器、接触器、继电器基础知识

【转载】Spring Boot 过滤器、监听器、拦截器的使用相关推荐

  1. Spring Boot 过滤器与拦截器的使用及其区别 和过滤器怎么设置运行顺序

    过滤器 过滤器的定义 在客户端将请求发送到服务器端之前,拦截这些请求:在服务器端的响应返回给客户端之前,处理这些响应. 比如字符编码过滤器CharacterEncodingFilter,就是设置req ...

  2. Spring Boot实战:拦截器与过滤器

    一.拦截器与过滤器 在讲Spring boot之前,我们先了解一下过滤器和拦截器.这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的.在分析两者的区别之前,我们先理解一下AOP的概念,A ...

  3. 过滤器-监听器-拦截器对比

    1,拦截器的概念     java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action 执行前阻止其执行,同时也提 ...

  4. Spring Boot 实现登录拦截器,这才是正确的姿势!!

    原文:https://blog.csdn.net/qq_27198345/article/details/111401610 对于管理系统或其他需要用户登录的系统,登录验证都是必不可少的环节,在Spr ...

  5. springBoot 2.x过滤器--监听器--拦截器

    springboot 2.x过滤器 1.什么是 springboot 2.x过滤器 类似于检票员,检验游客的门票 2.springboot里的过滤器 ApplicationContextHeaderF ...

  6. Spring Boot笔记-设置拦截器为false时返回的Body

    以preHandle拦截器为例: @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse ...

  7. 聊聊过滤器与拦截器区别

    开发者(KaiFaX) 面向全栈工程师的开发者专注于前端.Java/Python/Go/PHP的技术社区 1. 过滤器(Filter) Servlet 中的过滤器 Filter 实现了 javax.s ...

  8. Spring Boot实战:过滤器、拦截器与切片

    Spring Boot实战:过滤器.拦截器与切片 Q:使用过滤器.拦截器与切片实现每个请求耗时的统计,并比较三者的区别与联系 过滤器Filter 过滤器概念 Filter是J2E中来的,可以看做是Se ...

  9. spring boot 拦截器获取controller返回的数据_高级码农Spring Boot实战与进阶之过滤器和拦截器的使用及其区别...

    众所周知的Spring Boot是很优秀的框架,它的出现简化了新Spring应用的初始搭建以及开发过程,大大减少了代码量,目前已被大多数企业认可和使用.这个专栏将对Spring Boot框架从浅入深, ...

最新文章

  1. 【编译原理】让我们来构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 6.)(python/c/c++版)(笔记)
  2. JS中怎样获取当前年以及前后几年并构造成对象数组
  3. 3.C#基础之基本概念(完成)
  4. 在gitee上创建自己的仓库步骤
  5. Fedora 20 配置
  6. stm32 isp下载官方软件android_OpenCanvas免费版下载_OpenCanvas绘图软件官方版下载7.0.25...
  7. bzoj 3594: [Scoi2014]方伯伯的玉米田
  8. K-Means聚类算法的原理及实现
  9. redis hashmap过期_看完这篇再也不怕 Redis 面试了
  10. 电大c 语言程序设计程序,中央电大 C语言程序设计A
  11. Zookeeper之事件监听机制
  12. 程序员的自我修养_之四_曾国藩是如何脱胎换骨的
  13. 计算 x 的 n 次幂函数
  14. JavaScript之E-mail 地址格式验证
  15. NovelAi + Webui + Stable-diffusion本地配置
  16. 被拿走的雨伞——我想到的
  17. 【Python】图片视频处理常用操作及方法
  18. Axure RP 9.0.0.3727 授权码
  19. YOLO目标检测之IOU计算及其衍变体
  20. CAD如何调整线形比例?

热门文章

  1. wince版本ffmpeg的编译 第四篇
  2. 谷歌退出中国几成定局 谈判已谈崩
  3. u-boot nand flash read/write cmd
  4. 3D Reconstruction三维重建halcon算子,持续更新
  5. 德国汽车厂发生机器人杀人事件 人机协作是大势所趋
  6. Pytorch基础(十)——优化器(SGD,Adagrad,RMSprop,Adam,LBFGS等)
  7. C++11系列学习之七---------初始化列表
  8. 苏州软件测试11k工资要什么水平,3个月从机械转行软件测试,他的入职薪资是11K...
  9. 初中计算机职称答辩,晋升中学语文高级教师职称答辩内容举例
  10. android 监听界面变化,Android之页面有变化用onWindowFocusChanged来监听权限是否开启...