过滤器方式实现拦截(Filter)

通过继承Servlet的Filter类来实现拦截:

@Component
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("time filter init");
}
/**
* 处理服务的请求时间
* @param request
* @param response
* @param chain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//System.out.println("time filter start");
long start = System.currentTimeMillis();
chain.doFilter(request,response);
//System.out.println("time filter 耗时:" + (System.currentTimeMillis() - start));
//System.out.println("time filter finish"); }
@Override
public void destroy() {
//System.out.println("time filter destroy");
}
}

假如这个Filter是第三方jar提供的,怎么加入我们自己的工程呢?通过org.springframework.boot.web.servlet.FilterRegistrationBean来加入

@Configuration
public class WebConfig { @Bean
public FilterRegistrationBean timeFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter();
registrationBean.setFilter(timeFilter); List<String> urls = new ArrayList<>();
urls.add("/*");
registrationBean.setUrlPatterns(urls); return registrationBean; } }

拦截器方式实现拦截(Interceptor)

此种方式可以获取到拦截的类名称、方法名称,不能获取到方法参数,原因是在dispatcherservlet源码中,经过preHandle才对方法参数通过request里面开始处理拼接)

1.继承HandlerInterceptor,preHandle在控制器方法调用之前执行,postHandle在控制器方法正常执行后执行,afterCompletion不管控制器方法执行成功与否,都会执行;拦截器优于过滤器的地方就是拦截器有handler这个参数可以了解到针对哪个具体的方法进行了拦截。

@Component
public class TimeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
//打印类名
System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
//打印方法名
System.out.println(((HandlerMethod)handler).getMethod().getName());
request.setAttribute("startTime",System.currentTimeMillis());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
Long start = (Long)request.getAttribute("startTime");
System.out.println("time intercept 耗时:" + (System.currentTimeMillis() - start));
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception ex) throws Exception {
System.out.println("afterCompletion");
Long start = (Long)request.getAttribute("startTime");
System.out.println("time intercept 耗时:" + (System.currentTimeMillis() - start));
System.out.println("ex is" + ex);
}
}

2. 配置拦截器注入到spring容器(配置类需要继承WebMvcConfigurerAdapter,重写addInterceptors,手动添加自定义拦截器来到达注入的目的),也可为异步请求加入拦截器

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private TimeInterceptor timeInterceptor; /**
* 针对异步的拦截器配置,拦截异步请求
* @param configurer
*/
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
super.configureAsyncSupport(configurer);
//比如如下给异步服务请求添加拦截器
//configurer.registerCallableInterceptors((CallableProcessingInterceptor) timeInterceptor);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor);
}
}

切片方式实现拦截(Aspect)

可以拦截到类名、方法名,方法参数名

@Aspect
@Component
public class TimeAspect {
//切入点
@Around("execution(* com.zlt.web.controller.UserController.*(..))")
//增强
public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.print("time aspect start");
Object[] args = pjp.getArgs();
for (Object arg :args){
System.out.println("arg is" + arg);
}
long start = System.currentTimeMillis();
//调用被拦截的方法
Object object = pjp.proceed();
System.out.println("time filter 耗时:" + (System.currentTimeMillis() - start));
System.out.println("time aspect end");
return object;
}
}

小结

区别:

过滤器:可以拿到原始的HTTP请求和响应信息,拿不到处理请求的方法值信息 
拦截器:既可以拿到HTTP请求和响应信息,也可以拿到请求的方法信息,拿不到方法调用的参数值信息 
切片:可以拿到请求方法的传入参数值,拿不到原始的HTTP请求和响应的对象

发起一个请求,若三者共存的情况下:

正常运行顺序为:filter-interceptor-controllerAdvice-aspect-controller
异常情况下:controller-aspect-controllerAdvice-interceptor-filter

Springboot 三种拦截Rest API的方法-过滤器、拦截器、切片的更多相关文章

  1. Linux操作系统下三种配置环境变量的方法

    现在使用linux的朋友越来越多了,在linux下做开发首先就是需要配置环境变量,下面以配置java环境变量为例介绍三种配置环境变量的方法. 1.修改/etc/profile文件 如果你的计算机仅仅作 ...

  2. Linux操作系统下三种配置环境变量的方法——转载

    来源:赛迪网 作者:millio       现在使用linux的朋友越来越多了,在linux下做开发首先就是需要配置环境变量,下面以配置java环境变量为例介绍三种配置环境变量的方法. 1.修改/e ...

  3. hadoop搭建杂记:Linux下JDK环境变量的设置(三种配置环境变量的方法)

    Linux下JDK环境变量的设置(三种配置环境变量的方法) Linux下JDK环境变量的设置(三种配置环境变量的方法) ①修改/etc/profile文件 如果你的计算机仅仅作为开发使用时推荐使用这种 ...

  4. mssql sqlserver 三种数据表数据去重方法分享

    摘要: 下文将分享三种不同的数据去重方法数据去重:需根据某一字段来界定,当此字段出现大于一行记录时,我们就界定为此行数据存在重复. 数据去重方法1: 当表中最在最大流水号时候,我们可以通过关联的方式为 ...

  5. Win7怎么进入安全模式 三种轻松进入Win7安全模式方法

    发布时间:2013-05-27 11:23 作者:电脑百事网原创 来源:www.pc841.com 13783次阅读 win7的安全模式和XP如出一辙,在安全模式里我们可以删除顽固文件.查杀病毒.解除 ...

  6. sqlserver 下三种批量插入数据的方法

    本文将介绍三种批量插入数据的方法,需要的朋友可以参考下 本文将介绍三种批量插入数据的方法.第一种方法是使用循环语句逐个将数据项插入到数据库中:第二种方法使用的是SqlBulkCopy,使您可以用其他源 ...

  7. SpringBoot 三种方式配置 Druid(包括纯配置文件配置)

    记录一下在项目中用纯 YML(application.yml 或者 application.properties)文件.Java 代码配置 Bean 和注解三种方式配置 Alibaba Druid 用 ...

  8. 三种解密 HTTPS 流量的方法介绍

    转载自:https://imququ.com/post/how-to-decrypt-https.html作者: Jerry Qu Web 安全是一项系统工程,任何细微疏忽都可能导致整个安全壁垒土崩瓦 ...

  9. 大数据学习day13------第三阶段----scala01-----函数式编程。scala以及IDEA的安装,变量的定义,条件表达式,for循环(守卫模式,推导式,可变参数以及三种遍历方式),方法定义,数组以及集合(可变和非可变),数组中常用的方法

    具体见第三阶段scala-day01中的文档(scala编程基础---基础语法)  1. 函数式编程(https://www.cnblogs.com/wchukai/p/5651185.html): ...

随机推荐

  1. 九度oj 题目1056:最大公约数

    题目1056:最大公约数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:8068 解决:5317 题目描述: 输入两个正整数,求其最大公约数. 输入: 测试数据有多组,每组输入两个正整数. ...

  2. Java Class 利用classpath来获取源文件地址

    利用classpath来获取源文件地址 @author ixenos 应用场景 Properties props = new Properties(); /** * . 代表java命令运行的目录 * ...

  3. add favorite & 收藏夹

    add favorite // 收藏夹 function favorite (){ var ctrl = (navigator.userAgent.toLowerCase()).indexOf(&qu ...

  4. Apple & APPID & iOS & React Native

    Apple & APPID & iOS & React Native 在没有 苹果开发者账号证书 APPID, ios 是否支持导出 app https://developer ...

  5. [ C语言 ] 迷宫 迷宫生成器 [ 递归与搜索 ]

    [原创]转载请注明出处 [浙江大学 程序设计专题] [地图求解器] 本题目要求输入一个迷宫地图,输出从起点到终点的路线. 基本思路是从起点(Sx,Sy)每次枚举该格子上下左右四个方向,直到走到终点(T ...

  6. Linux下汇编语言学习笔记62 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  7. 技术杂记之:在阿里云centos7上部署JDK MYSQL TOMCAT

    今日小编闲来无事,乘着公司新项目即将上线之际,在阿里云上整了一台centos作为测试机.原本以为一个小时搞定,结果还是花了一点小小时间.不管怎么说,记录下来,给各位小白当成课后甜点吧. 价格 先上价格 ...

  8. 动态演示冒泡排序java

    动态演示冒泡排序java //冒泡排序是一种简单的交换排序,基本思路,从数列左边开始扫描元素,在扫描过程中依次对相邻元素进行比较,将较大元素后移. public class NumberSort { ...

  9. JSP的调试

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/debugging.html: 一.使用System.out.println() System.out.p ...

  10. C#程序如何把窗体文件从从一个项目中复制到另一个项目

    一个窗体有三个文件,全部拷贝到新的项目中   在新的项目中点击显示所有文件,然后右击导入的文件,点击包括在项目中,会自动修改颜色(此时还没有被识别为窗体)   重启这个项目,三个文件已经被识别出来了 ...