Swagger 文章合并到 Spring Boot 系列:配置 Swagger2

一、过滤器 - Filter

过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求。

1.1 过滤器介绍

过滤器依赖于Servlet容器

过滤器可以拦截到方法的请求和响应(ServletRequest request, ServletResponse response),并对请求/响应做出过滤操作。

1.2 过滤器用途

用来做一些过滤操作,获取我们想要获取的数据:

  1. 在过滤器中修改字符编码;
  2. 在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等;
  3. 用作 Session 校验,判断用户权限。

一个过滤器实例只能在容器初始化时调用一次。

1.3 过滤器的使用

FilterWeb应用的启动而启动,只初始化一次,随Web应用的停止而销毁。

  1. 启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
  2. 每一次请求时都只调用方法doFilter()进行处理;
  3. 停止服务器时调用destroy()方法,销毁实例。

1.4 示例代码

首先需要实现 Filter.java接口然后重写它的三个方法,对包含我们要求的请求予以放行,将其它请求拦截并重定向。

@Slf4j
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 启动服务器时加载log.info("MyFilter init()");}// 每次请求都会调用该方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);String requestUri = request.getRequestURI();log.info("本次请求地址是:{}", requestUri);if (requestUri.contains("/addSession")|| requestUri.contains("/removeSession")|| requestUri.contains("/getUserCount")) {filterChain.doFilter(servletRequest, response);} else {// 除了以上三个链接,其他请求转发到 /redirectUrlwrapper.sendRedirect("/redirectUrl");}}@Overridepublic void destroy() {// 在服务关闭时销毁log.info("MyFilter destroy()");}
}

二、拦截器

Java 中的拦截器是动态拦截 Action 调用的对象,然后提供了可以在 Action 执行前后增加一些操作,也可以在 Action 执行前停止操作,功能与过滤器类似,但是标准和实现方式不同。

2.1 拦截器介绍

依赖于 Web 框架,在 Spring 中依赖于 SpringMVC 框架。在实现上,基于 Java 的反射机制,属于面向切面编程(AOP)的一种运用,就是在一个方法前,调用一个方法,或者在方法后,调用一个方法。

2.2 拦截器的用途

  1. 登录认证:在一些应用中,可能会通过拦截器来验证用户的登录状态,如果没有登录或者登录失败,就会给用户一个友好的提示或者返回登录页面;
  2. 记录系统日志:记录用户的请求信息,如请求 Ip,方法执行时间等,通过这些记录可以监控系统的状况,以便于对系统进行信息监控、信息统计、计算 PV、性能调优等;
  3. 通用处理:如将接口封装成统一结果集返回。

2.3 拦截器的使用

我们需要实现 HandlerInterceptor 类,并且重写三个方法

  1. preHandle():在 Controoler 处理请求之前被调用,返回值是 boolean类型,如果是true就进行下一步操作;若返回false,则证明不符合拦截条件。在失败的时候不会包含任何响应,此时需要调用对应的response返回对应响应;
  2. postHandler():在 Controoler 处理请求执行完成后、生成视图前执行,可以通过ModelAndView对视图进行处理,当然ModelAndView也可以设置为 null
  3. afterCompletion():在 DispatcherServlet 完全处理请求后被调用,通常用于记录消耗时间,也可以对一些资源进行处理。

2.4 示例代码

@Component
@Slf4j
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("【MyInterceptor】调用了:{}", request.getRequestURI());request.setAttribute("requestTime", System.currentTimeMillis());return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception{if (!request.getRequestURI().contains("/getUserCount")) {HttpSession session = request.getSession();String sessionName = (String) session.getAttribute("name");if ("Van".equals(sessionName)) {log.info("【MyInterceptor】当前浏览器存在 session:{}",sessionName);}}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception {long duration = (System.currentTimeMillis() - (Long)request.getAttribute("requestTime"));log.info("【MyInterceptor】[{}]调用耗时:{}ms",request.getRequestURI(), duration);}
}
  1. Controoler内部有异常,posthandler方法是不会执行的;
  2. 不管Controoler内部是否有异常,都会执行afterCompletion方法;此方法还会有个Exception ex这个参数;如果有异常,ex会有异常值;没有异常 此值为null
  3. 如果Controoler内部有异常,但异常被@ControllerAdvice异常统一捕获的话,ex也会为null

三、监听器

3.1 监听器介绍

监听器通常用于监听 Web 应用程序中对象的创建、销毁等动作的发送,同时对监听的情况作出相应的处理,最常用于统计网站的在线人数、访问量等。

3.2 监听器的用途

大概分为以下几种:

  1. ServletContextListener:用来监听 ServletContext 属性的操作,比如新增、修改、删除;
  2. HttpSessionListener:用来监听 Web 应用中的 Session 对象,通常用于统计在线情况;
  3. ServletRequestListener:用来监听 Request 对象的属性操作。

3.3 监听器的使用

  • HttpSessionListener

通常用来统计当前在线人数、ip 等信息,为了避免并发问题我们使用AtomicInteger来计数。

  • ServletContext

是一个全局的储存信息的空间,它的生命周期与 Servlet 容器也就是服务器保持一致,服务器关闭才销毁。request,一个用户可有多个;session,一个用户一个;而 ServletContext,所有用户共用一个。所以,为了节省空间,提高效率,ServletContext 中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。因此我们用 ServletContext 来存储在线人数最为合适。

3.4 示例代码

@Slf4j
public class MyHttpSessionListener implements HttpSessionListener {/*** 在线人数*/public static AtomicInteger userCount = new AtomicInteger(0);@Overridepublic synchronized void sessionCreated(HttpSessionEvent se) {userCount.getAndIncrement();se.getSession().getServletContext().setAttribute("sessionCount", userCount.get());log.info("【在线人数】人数增加为:{}",userCount.get());}@Overridepublic synchronized void sessionDestroyed(HttpSessionEvent se) {userCount.getAndDecrement();se.getSession().getServletContext().setAttribute("sessionCount", userCount.get());log.info("【在线人数】人数减少为:{}",userCount.get());}
}

Spring Boot 中监听器也可通过实现ApplicationListener接口实现,这里就不演示了。

四、过滤器、拦截器、监听器

4.1 过滤器与拦截器的区别

1. 参考标准

  • 过滤器是 JavaEE 的标准,依赖于 Servlet 容器,生命周期也与容器一致,利用这一特性可以在销毁时释放资源或者数据入库;
  • 拦截器是 SpringMVC 中的内容,依赖于 Web 框架,通常用于验证用户权限或者记录日志,但是这些功能也可以利用 AOP 来代替。

2. 实现方式

  • 过滤器是基于回调函数实现,无法注入 IOC 容器;
  • 拦截器是基于反射来实现,因此拦截器中可以注入 IOC 容器中。

4.2 实例化三器

@Configuration
public class WebConfig implements WebMvcConfigurer {@ResourceMyInterceptor myInterceptor;/*** 注册过滤器* @return*/@Beanpublic FilterRegistrationBean filterRegistrationBean(){FilterRegistrationBean filterRegistration = new FilterRegistrationBean();filterRegistration.setFilter(new MyFilter());filterRegistration.addUrlPatterns("/*");return filterRegistration;}/*** 注册拦截器* @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor);}/*** 注册监听器* @return*/@Beanpublic ServletListenerRegistrationBean registrationBean(){ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();registrationBean.setListener(new MyHttpSessionListener());return registrationBean;}
}

4.3 测试接口

@RestController
@RequestMapping("")
public class TestController {/*** 增加在线人数* @param request*/@GetMapping("/addSession")public void addSession(HttpServletRequest request) {HttpSession session = request.getSession();session.setAttribute("name", "Van");}/*** 减少在线人数* @param request*/@GetMapping("/removeSession")public void removeSession(HttpServletRequest request) {HttpSession session = request.getSession();session.invalidate();}/*** 统计在线人数* @return*/@GetMapping("/getUserCount")public String getUserCount() {return "当前在线人数" + MyHttpSessionListener.userCount.get() + "人";}/*** 重定向的地址* @return*/@GetMapping("/redirectUrl")public String redirectUrl() {return "欢迎关注:风尘博客!";}}

五、测试

  • 启动项目,过滤器成功加载:
...
cn.van.fil.filter.MyFilter               : MyFilter init()
....

5.1 查看在线人数

  • 接口链接

http://localhost:8080/getUserCount

  • 返回结果:
当前在线人数0人
  • 控制台日志:
c.v.fil.listener.MyHttpRequestListener   : 接口:/getUserCount被调用
cn.van.fil.filter.MyFilter               : 本次请求地址是:/getUserCount
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】调用了:/getUserCount
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】[/getUserCount]调用耗时:1ms
c.v.fil.listener.MyHttpRequestListener   : request 监听器被销毁

5.2 增加在线人数

  • 接口链接

http://localhost:8080/addSession

  • 无返回结果:

  • 控制台日志:

cn.van.fil.filter.MyFilter               : 本次请求地址是:/addSession
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】调用了:/addSession
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】当前浏览器存在 session:Van
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】[/addSession]调用耗时:16ms

5.3 再次请求 5.1 查看在线人数接口

当前在线人数1人
  • 控制台日志:
cn.van.fil.filter.MyFilter               : 本次请求地址是:/getUserCount
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】调用了:/getUserCount
cn.van.fil.interceptor.MyInterceptor     : 【MyInterceptor】[/getUserCount]调用耗时:2ms

5.4 减少在线人数

http://localhost:8080/removeSession

六、总结

Github 示例代码

参考文章:SpringBoot使用拦截器、过滤器、监听器

6.1 日常求赞

博主祖传秘籍 Spring Boot 葵花宝典 开源中,欢迎前来吐槽,提供线索,告诉博主接下来更新哪方面文章,共同进步!

6.2 文化交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. 风尘博客-CSDN
  5. Github

最新文章,欢迎关注:公众号-风尘博客;交流观点,欢迎添加:个人微信

Spring Boot 系列:过滤器+拦截器+监听器相关推荐

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

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

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

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

  3. java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西

    过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...

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

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

  5. Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理

    Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 参考文章: (1)Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 ( ...

  6. spring 两次进入拦截器_过滤器和拦截器的 6 个区别,别再傻傻分不清了

    点击上方 肉眼品世界,选择 设为星标 深度价值体系传递 作者 :程序员内点事 来源 :toutiao.com/i6834310440495874563 毕竟这两种工具开发中用到的频率都相当高,应用起来 ...

  7. Spring MVC中的拦截器/过滤器HandlerInterceptorAdapter的使用

    转载自 https://www.cnblogs.com/EasonJim/p/7704740.html 一般情况下,对来自浏览器的请求的拦截,是利用Filter实现的 而在Spring中,基于Filt ...

  8. 国内最全的Spring Boot系列之二

    历史文章 <国内最全的Spring Boot系列之一> 视频&交流平台 SpringBoot视频:http://t.cn/R3QepWG Spring Cloud视频:http:/ ...

  9. Spring AOP原理及拦截器

    原理 AOP(Aspect Oriented Programming),也就是面向方面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP将应用系统分为两部分,核心业务逻辑(Core bu ...

最新文章

  1. 我们常称自己“码农”,这次已得到官方认定:“新生代农民工!
  2. lvm扩张与收缩小结
  3. 微服务已过时!DDD领域建模与架构设计才是未来!
  4. linux用户管理类常用命令:
  5. 基于java mail实现简单的QQ邮箱发送邮件
  6. 首尾相接数组求子数组最大和
  7. wtforms Form实例化流程(源码解析)
  8. QA: 自闭合标签要不要手动闭合?
  9. 随机抽样方法正太分布 MC, MCMC, Gibbs采样 原理实现(in R)
  10. 企业微信最全17种获客+4种自动转化玩法
  11. 英语单词发音中/s/后的/p/,/t/,/k//tr/什么时候读作/b/,/d/,/g/,/dr/?
  12. win32.mak下载地址github
  13. 微信小程序 教你如何复制页面路径 (以及京东、虎牙、苏宁、拼多多、等大厂的加密路径详解)(多图!!!)
  14. Apache 301转向技巧
  15. 基于51单片机万年历
  16. 哪里东西更便宜?读《卧底经济学(珍藏版)》
  17. 题目:输入一个8bit数,输出其中1的个数,只能使用1bit全加器
  18. 水的黏度 Viscosity of Water
  19. (Vulnhub练习)-- fristileaks渗透实战
  20. 每日一问 --什么是信源、信宿?

热门文章

  1. 利用Winwebmail密码算法加密网页木马
  2. 高考改革后计算机老师,2018高考改革后,什么老师最紧缺?
  3. 预测A股行业板块动向
  4. missing go.sum entry for module providing package
  5. 【屏幕刷新】Android 屏幕刷新机制
  6. 软件测试数据刷新频率,性能测试-流畅度指标、数据的获取
  7. 抖音涨粉变现最快的账号的一致性和美观性设计-阿甘电商
  8. 2022.5.2 五一假期痛苦的第三天
  9. python如何爬取文献_这个工具,可全网爬取科研圈中外文献!
  10. 历经风雨,才能看透人心真假;