springboot三种拦截器的使用与比较

springboot中有三种拦截器可供选择:filter、interceptort和aop。本文主要讨论三种拦截器的使用场景与使用方式。

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

一、filter

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

实现:

1.继承javax.servlet.Filter类,

[email protected]注解将其注入到框架中

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注解

[email protected]声明切面,声明切面的语法可参考官网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 }

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo }

原文地址:https://www.cnblogs.com/zuxiaoyuan/p/9702363.html

时间: 2024-11-05 17:24:43

springboot三种拦截器的使用与比较的相关文章

Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

Springboot + redis + 注解 + 拦截器来实现接口幂等性校验 1. SpringBoot 整合篇 2. 手写一套迷你版HTTP服务器 3. 记住:永远不要在MySQL中使用UTF-8 4. Springboot启动原理解析 一.概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如: 订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多次回调, 必须处理重复回调 普通表单提交接口, 因为网络超时

Struts2.x教程(三) Struts2拦截器

一.Struts2拦截器介绍 Struts2拦截器是使用AOP实现的,主要是针对action对象进行拦截,可以在访问action的某个方法.字段之前或之后实施拦截. 可以为action配置多个拦截器,Struts2会将这一组拦截器按照一定顺序组织成一个拦截器栈.action可以直接引用某个拦截器栈来实现配置多个拦截器的目的. 对于继承struts_default的package中的action,都会默认引用name=defaultStack的拦截器栈(在struts_default中定义了Str

通过fsharp 使用Enterprise Library Unity 3 - 三种拦截模式的探索

这篇就三种拦截模式进行一下探索. 特性总结   类型 特点 其它 InterfaceInterceptor Innstance 仅单接口 类内部函数互相引用无法引起拦截行为 TransparentProxyInterceptor           Instance 多接口(接口之间能够切换)  MarshalByRef 执行缓慢 接口类型(virtual, non-virtual, or interface) 类内部函数互相引用能够引起拦截行为 VirtualMethodInterceptor

在springboot中使用拦截器

在springMVC中可以实现拦截器,是通过实现HandlerInterceptor接口,然后在springmvc-web.xml中配置就可以使用拦截器了.在springboot中拦截器也是一样的思想,使用方法还是没有变,只不过是配置稍微变了一下. 在springboot中使用拦截器步骤如下: 1.按照springmvc模式写一个拦截器类 和springmvc一样,也要写一个类实现HandlerInterceptor接口,然后重新其中的prehandle方法. 2.然后写一个配置类,继承WebM

Springboot中SpringMvc拦截器配置与应用(实战)

一.什么是拦截器,及其作用 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式. 拦截器的使用场景越来越多,尤其是面向切片编程流行之后.那通常拦截器可以做什么呢? 之前我们在Agent介绍中,提到过统计函数的调用耗时.这

Struts2学习第三天——拦截器与文件传输

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.06.15 lutianfei none 内容摘要: 1.国际化(了解) 2.拦截器(Interceptor)-重点 3.struts2文件上传与下载(次重点) 4.ognl与valuestack 国际化 国际化原理,什么是国际化 ? 同一款软件 可以为不同用户,提供不同语言界面 -- 国际化软件 需要一个语言资源包(很多properties文件,每个properties文件 针对一个国家或者语言 ,通过java程序根

SpringBoot三种启动方式

SpringBoot第一种启动方式 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.

[十四]SpringBoot 之 Spring拦截器(HandlerInterceptor)

过滤器属于Servlet范畴的API,与spring 没什么关系. Web开发中,我们除了使用 Filter 来过滤请web求外,还可以使用Spring提供的HandlerInterceptor(拦截器). HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前.request被响应之后.视图渲染之前以及request全部结束之后.我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执

【Struts2三】拦截器

拦截器:就是在访问action之前,对其进行拦截!可以在拦截器中做一些逻辑的处理!比如权限验证,没有权限就不给予访问! 拦截器等效于servlet中的过滤器! 使用拦截器步骤: 1.定义自己的拦截器: import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; /** * 定义自己的拦截器,需要实现Intercept接口! * */ public