若要实现对请求的过滤,有三种方式可供选择:filter、interceptort和aop。本文主要讨论三种拦截器的使用场景与使用方式。

下文中的举例功能是计算每个请求的从开始到结束的时间,例子来源是慕课网。

一、filter

特点:可以获取原始的ServletRequest,但无法获取具体方法

实现:

1.继承javax.servlet.Filter类,

2.@Component注解将其注入到框架中

3.实现其中的dofilter方法,所有的请求都会经过该方法,可以在此计算出每个请求的耗时,代码如下:

 1 package com.zzy.web.filter;
 2
 3 import java.io.IOException;
 4 import java.util.Date;
 5
 6 import javax.servlet.Filter;
 7 import javax.servlet.FilterChain;
 8 import javax.servlet.FilterConfig;
 9 import javax.servlet.ServletException;
10 import javax.servlet.ServletRequest;
11 import javax.servlet.ServletResponse;
12
13 import org.springframework.stereotype.Component;
14
15 @Component
16 public class TimeFilter implements Filter{
17
18     @Override
19     public void init(FilterConfig filterConfig) throws ServletException {
20         // TODO Auto-generated method stub
21         System.out.println("filter init");
22
23     }
24
25     @Override
26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
27             throws IOException, ServletException {
28         // TODO Auto-generated method stub
29         Long startTime = new Date().getTime();
30         System.out.println("filter 请求开始时间:"+ startTime);
31         chain.doFilter(request, response);
32          Long endTime = new Date().getTime();
33         System.out.println("filter 请求结束时间:" + endTime +",请求耗时:" + (endTime - startTime));
34
35     }
36
37     @Override
38     public void destroy() {
39         // TODO Auto-generated method stub
40
41     }
42
43 }

注:如果有的框架没有@Component 这个注解,可以自己写一个配置类,在该类中指定过滤器,而且还可以指定过滤的url,配置类如下:

 1 package com.zzy.web.config;
 2
 3 import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
 4
 5 import java.util.ArrayList;
 6 import java.util.List;
 7
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.boot.web.servlet.FilterRegistrationBean;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.context.annotation.Configuration;
12 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
13 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
14
15 import com.zzy.web.filter.TimeFilter;
16 import com.zzy.web.interceptor.TimeInterceptor;
17
18 @Configuration
19 public class WebConfig extends WebMvcConfigurerAdapter {
20
21     @Autowired
22     private TimeInterceptor timeInterceptor;
23
24 //    @Override
25 //    public void addInterceptors(InterceptorRegistry registry) {
26 //        // TODO Auto-generated method stub
27 //        registry.addInterceptor(timeInterceptor);
28 //    }
29
30     @Bean
31     public FilterRegistrationBean timeFilter() {
32         FilterRegistrationBean registrationBean = new FilterRegistrationBean();
33         TimeFilter timeFilter = new TimeFilter();
34         registrationBean.setFilter(timeFilter);
35         List<String> urls = new ArrayList<>();
36         urls.add("/user/*");
37         registrationBean.setUrlPatterns(urls);
38         return registrationBean;
39     }
40
41 }

二、interceptor

特点:可以获取到原始的request和请求的方法,但无法获取方法的具体参数的值。

实现:

1.继承HandlerInterceptor接口

2.请求前的逻辑写在prehandle(请求前调用)

3.请求后的逻辑写在posthandle(请求成功后调用,失败则不调用)

4.请求后,不管成功失败都会调用aftercompletion。

5.intceptor方式继承了之后还没起作用,还需要在配置类里面加一下,把刚声明的拦截器注册一下。

代码示例:

 1 package com.zzy.web.interceptor;
 2
 3 import java.util.Arrays;
 4 import java.util.Date;
 5
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8
 9 import org.springframework.stereotype.Component;
10 import org.springframework.web.method.HandlerMethod;
11 import org.springframework.web.servlet.HandlerInterceptor;
12 import org.springframework.web.servlet.ModelAndView;
13 @Component
14 public class TimeInterceptor implements HandlerInterceptor {
15
16     @Override
17     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
18             throws Exception {
19         // TODO Auto-generated method stub
20         System.out.println("interceptor 执行preHandle");
21
22         request.setAttribute("startTime", new Date().getTime());
23         return true;
24     }
25
26     @Override
27     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
28             ModelAndView modelAndView) throws Exception {
29         // TODO Auto-generated method stub
30         Long startTime = Long.parseLong(request.getAttribute("startTime").toString());
31         Long endTime = new Date().getTime();
32         System.out.println("interceptor 执行postHandle");
33         System.out.println("interceptor 请求类:"+((HandlerMethod)handler).getBean().getClass().getName());
34         System.out.println("interceptor 请求方法:"+((HandlerMethod)handler).getMethod());
35 //        System.out.println("interceptor 请求参数:");
36 //        Arrays.asList(((HandlerMethod)handler).getMethodParameters()).stream().forEach(arg->System.out.println(arg));
37         System.out.println("interceptor 请求耗时:" + (endTime - startTime));
38
39     }
40
41     @Override
42     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
43             throws Exception {
44         // TODO Auto-generated method stub
45         Long startTime = Long.parseLong(request.getAttribute("startTime").toString());
46         Long endTime = new Date().getTime();
47         System.out.println("interceptor 执行afterCompletion");
48         System.out.println("interceptor 请求类:"+((HandlerMethod)handler).getBean().getClass().getName());
49         System.out.println("interceptor 请求方法:"+((HandlerMethod)handler).getMethod());
50         System.out.println("interceptor 请求耗时:" + (endTime - startTime));
51         System.out.println("interceptor 请求异常:" + ex);
52
53     }
54
55 }

配置类如下:

 1 package com.zzy.web.config;
 2
 3 import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
 4
 5 import java.util.ArrayList;
 6 import java.util.List;
 7
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.boot.web.servlet.FilterRegistrationBean;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.context.annotation.Configuration;
12 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
13 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
14
15 import com.zzy.web.filter.TimeFilter;
16 import com.zzy.web.interceptor.TimeInterceptor;
17
18 @Configuration
19 public class WebConfig extends WebMvcConfigurerAdapter {
20
21     @Autowired
22     private TimeInterceptor timeInterceptor;
23
24     @Override
25     public void addInterceptors(InterceptorRegistry registry) {
26         // TODO Auto-generated method stub
27         registry.addInterceptor(timeInterceptor);
28     }
29
30
31 }

三、aop

特点:能拿到方法和具体参数的值,但是拿不到原始的servletrequest的信息。

实现:

1.使用@aspect注解

2.@execution声明切面,声明切面的语法可参考官网https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference/htmlsingle/#aop-pointcuts

3.使用@Around(方法前和方法后),@Before(方法前)或@After(方法后)

以下为@Around举例,代码如下:

 1 package com.zzy.web.aspect;
 2
 3 import java.util.Date;
 4
 5 import org.aspectj.lang.ProceedingJoinPoint;
 6 import org.aspectj.lang.annotation.Around;
 7 import org.aspectj.lang.annotation.Aspect;
 8 import org.codehaus.jackson.map.ObjectMapper;
 9 import org.springframework.stereotype.Component;
10
11 @Aspect
12 @Component
13 public class TimeAspect {
14
15     @Around("execution(* com.zzy.web.controller.UserController.*(..))")
16     public Object test(ProceedingJoinPoint pjp) throws Throwable {
17         Long startTime = new Date().getTime();
18         Object[] args = pjp.getArgs();
19         for (Object arg : args) {
20             System.out.println("aspect 参数:" + arg);
21         }
22         Object object = pjp.proceed();
23         System.out.println("aspect 请求耗时:" + (new Date().getTime() - startTime));
24         System.out.println("aspect 请求结果:" + new ObjectMapper().writeValueAsString(object));
25
26         return object;
27
28     }
29 }

下图是三种方式的拦截顺序,图片来自慕课网:

转载于:https://www.cnblogs.com/zuxiaoyuan/p/9702363.html

springboot三种过滤功能的使用与比较相关推荐

  1. SpringBoot 三种拦截http请求方式Filter,interceptor和aop

    SpringBoot 三种拦截http请求方式Filter,interceptor和aop. 这三种拦截方式的拦截顺序是:filter->Interceptor-->ControllerA ...

  2. SpringBoot三种方式实现定时任务

    SpringBoot三种方式实现定时任务 定时任务实现的三种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用 ...

  3. 一文读懂TDengine的三种查询功能

    小 T 导读:作为一款专业的时序数据库(Time Series Database,TSDB),为满足用户在不同场景下的查询需求,TDengine 提供了丰富的查询功能.除了一些主要的查询外,还包括多表 ...

  4. SpringBoot三种方法实现定时发送邮件的案例

    介绍 这里是小编成长之路的历程,也是小编的学习之路.希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡. 一个人为什么要努力? ...

  5. SpringBoot三种获取Request和Response的方法

    一.可以封装为静态方法. ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestCo ...

  6. SpringBoot实现定时任务的三种方式

    第一种我们可以使用java原生提供的api去实现一个定时任务 利用Timer这个api,去实现定时任务,用Timertask去创建一个任务 public class javaJob {public s ...

  7. python中spark有什么功能_Spark SQL是什么,提供的主要功能有哪三种?

    Spark SQL允许大家在Python.Java以及Scala中使用数据帧;利用多种结构化格式读取并写入数据;通过SQL进行大数据查询. Spark SQL属于Spark用于处理结构化与半结构化数据 ...

  8. ZBrush中的三种对称类型的完美运用

    ZBrush是一款功能强大的数字建模软件,在使用ZBrush进行雕刻建模的时候,为达到雕刻速度和雕刻效果的美观,经常需要使用对称功能来制作.ZBrush®软件为我们提供了三种对称功能,分别是基于轴的对 ...

  9. [4G5G专题-57]:L2 RLC层-详解RLC架构、数据封装、三种模式:透明TM、非确认模式UM、确认模式AM

    目录 第1章  L2 RLC层的架构 1.1 RAN的架构 1.2 L2架构概述 1.3 RLC软件系统结构图 第2章 TCP/IP协议提供的三种传输服务 ​2.1 TCP 2.2 UDP 2.3 R ...

最新文章

  1. Web的桌面提醒(Popup)
  2. jsp判断语句_Java的web展现层JSP的JSTL标签详细总结
  3. 独家 | 手把手教你用Python的Prophet库进行时间序列预测
  4. python中的静态方法和类方法
  5. 在Windows Server 2008上部署SVN代码管理总结
  6. angular4设置全局变量_angularjs 设置全局变量的7种方法
  7. 特斯拉电池检测_特斯拉风格的割草机,也是采用电池供电
  8. h5红包雨代码_【多管闲事】非专业人士H5学习指北:从门还没入到放弃 | 叙一来闲...
  9. “代理XP”组件已作为此服务器安全配置的一部分被关闭
  10. 前端性能优化(慕课网笔记)-3-代码优化
  11. 案例分享:Qt管道焊接参数条码打印系统(条码打印机TSC 244 Pro、打印条码、打印中文、打印字符、多张连续打印)
  12. C#--打包安装项目
  13. 192.168.8.1手机登陆_192.168.8.1手机登陆设置教程
  14. (1.4.10.1)SXF测试笔试题
  15. Mininet连接真实网络的实现
  16. 神马都是浮云!神马浮云是什么意思?-出自小月月
  17. 7-35 英文字母的大小写转换
  18. A review of 3D vessel lumen segmentation techniques: Models, features and extraction schemes
  19. 【个人研究】21世纪西方运用脑电(EEG)的音乐研究动向分析(二)
  20. 计算机专业里的麦课尔雅,艺术导论超星尔雅网课答案2020年_高校邦_计算机文化基础_章节答案...

热门文章

  1. C语言常用字符串操作函数大全详解(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等)
  2. python装饰器参数讲解_python装饰器的详细解析
  3. 计算机网络必备知识,非常全面!
  4. 前端:Element UI 多选框组用法笔记
  5. jmeter如何定位网络延时_JMeter用户定义变量和properties变量高级使用
  6. java executequery,JDBC中的execute(),executeQuery()和executeUpdate()方法有什么区别?
  7. Java网络编程2---Socket-TCP编程
  8. Java(ArrayList和LinkedList)、(HashTable与HashMap)、(HashMap、Hashtable、LinkedHashMap和TreeMap比较)
  9. 模式匹配 怎么匹配减号_如何使您的应用导航与用户的思维模式匹配
  10. 前端抢饭碗系列之Vue项目如何做单元测试