博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot三种过滤功能的使用与比较
阅读量:5317 次
发布时间:2019-06-14

本文共 8143 字,大约阅读时间需要 27 分钟。

若要实现对请求的过滤,有三种方式可供选择: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 @Component16 public class TimeFilter implements Filter{17 18     @Override19     public void init(FilterConfig filterConfig) throws ServletException {20         // TODO Auto-generated method stub21         System.out.println("filter init");22         23     }24 25     @Override26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)27             throws IOException, ServletException {28         // TODO Auto-generated method stub29         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     @Override38     public void destroy() {39         // TODO Auto-generated method stub40         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 @Configuration19 public class WebConfig extends WebMvcConfigurerAdapter {20     21     @Autowired22     private TimeInterceptor timeInterceptor;23     24 //    @Override25 //    public void addInterceptors(InterceptorRegistry registry) {26 //        // TODO Auto-generated method stub27 //        registry.addInterceptor(timeInterceptor);28 //    }29     30     @Bean31     public FilterRegistrationBean timeFilter() {32         FilterRegistrationBean registrationBean = new FilterRegistrationBean();33         TimeFilter timeFilter = new TimeFilter();34         registrationBean.setFilter(timeFilter);35         List
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 @Component14 public class TimeInterceptor implements HandlerInterceptor {15 16     @Override17     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)18             throws Exception {19         // TODO Auto-generated method stub20         System.out.println("interceptor 执行preHandle");21 22         request.setAttribute("startTime", new Date().getTime());23         return true;24     }25 26     @Override27     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,28             ModelAndView modelAndView) throws Exception {29         // TODO Auto-generated method stub30         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     @Override42     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)43             throws Exception {44         // TODO Auto-generated method stub45         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 @Configuration19 public class WebConfig extends WebMvcConfigurerAdapter {20     21     @Autowired22     private TimeInterceptor timeInterceptor;23     24     @Override25     public void addInterceptors(InterceptorRegistry registry) {26         // TODO Auto-generated method stub27         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 @Aspect12 @Component13 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

你可能感兴趣的文章
观察者模式(Observer)
查看>>
python中numpy.r_和numpy.c_
查看>>
WPF简单模拟QQ登录背景动画
查看>>
bzoj 2038 小Z的袜子
查看>>
egret3D与2D混合开发,画布尺寸不一致的问题
查看>>
freebsd 实现 tab 命令 补全 命令 提示
查看>>
struts1和struts2的区别
查看>>
函数之匿名函数
查看>>
shell习题第16题:查用户
查看>>
实验4 [bx]和loop的使用
查看>>
Redis常用命令
查看>>
2018.11.06 bzoj1040: [ZJOI2008]骑士(树形dp)
查看>>
2019.02.15 bzoj5210: 最大连通子块和(链分治+ddp)
查看>>
redis cluster 集群资料
查看>>
微软职位内部推荐-Sr. SE - Office incubation
查看>>
微软职位内部推荐-SOFTWARE ENGINEER II
查看>>
centos系统python2.7更新到3.5
查看>>
【Quartz】常用方法的使用方式(三)
查看>>
MVVM模式下关闭窗口的实现
查看>>
C#区域截图——调用API截图
查看>>