spring中过滤器(filter)、拦截器(intercept
2019-09-29 本文已影响0人
不知名的蛋挞
三者区别
Filter(过滤器)
过滤器是服务端的一个组件,是基于servlet实现从客户端访问服务端web资源的一种拦截机制,对请求request和响应response都进行过滤,依赖于serverlet容器,使用时,实现Filter接口,在web.xml里配置对应的class还有mapping-url。
//@Component
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
System.out.println("过滤器初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器执行了");
long start2 = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
long time = System.currentTimeMillis() - start2;
System.out.println("过滤器执行的时间是 :" + time);
System.out.println("过滤器执行结束");
}
@Override
public void destroy() {
System.out.println("过滤器销毁了");
}
}
interceptor(拦截器)
拦截器,顾名思义,它的作用就是拦截,这个要和过滤器区分开,过滤器依赖serverlet容器,获取request和response处理,是基于函数回调(框架本身调用的,它会遍历所有注册的过滤器,并且一一调用doFilter()),简单说就是“去取你想取的”。拦截器是通过Java反射机制来拦截web请求,是“拒你想拒绝的”,它只拦截web请求,但不拦截静态资源。
拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
@Component
public class TimeInterceptor implements HandlerInterceptor {
// 在controller调用之前调用,通过返回true或者false决定是否进入Controller层
@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", new Date().getTime());
return true;
}
// 在请求进入控制层之后调用,但是在处理请求抛出异常时不会调用
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
Long start = (Long)request.getAttribute("startTime");
System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
}
// 在请求处理完成之后,也就是在DispatherServlet渲染了视图之后执行,也就是说这个方法必定是执行,包含异常信息,它的主要作用就是清理资源
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion");
Long start = (Long) request.getAttribute("startTime");
System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
System.out.println("ex is "+ex);
}
}
Aspect(切片)
相比过滤器,拦截器能够知道用户发出的请求最终被哪个控制器处理,但是拦截器还有一个明显的不足,即不能够获取request的参数以及控制器处理之后的response。(注意 ,我曾经试过,获得被拦截方法的一些参数,但是通过methodParaters无法获得,后来只能通过request.getParameter(..)来获取)所以就有了切片的用武之地了。
@Aspect
@Component
public class TimeAspect {
@Around("execution(* com.wtzhou.security.controller.UserController.*(..))")
// @After("")
// @Before("")
// @AfterThrowing()
// @AfterReturning()
public Object handlerControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg : args) {
out.println("请求参数为:"+arg);
}
out.println("TimeAspect 切片开始执行");
long start = currentTimeMillis();
Object proceed = proceedingJoinPoint.proceed();
out.println("切片执行耗时:" + (currentTimeMillis() - start));
out.println("切片执行结束!");
return proceed;
}
}
总结
【Filter与Interceptor的区别】
- filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;
- filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;
- filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);
- 在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。
【Interceptor 与spring AOP的区别】
- spring Interceptor也是一种aop思想,我们这里面的spring AOP主要是讲aop应用,interceptor 的使用场合比aop小很多,顾名思义,它是拦截一些action请求,但是比aop使用起来简便;
- 程序执行的顺序是先进过滤器,再进拦截器,最后进切面;
- Interceptor可以阻止代码执行下去,当preHandle返回false,那么这个请求就到此结束,真正的被拦截了,但是aop不能,它只是单纯的切入添加操作;