1、拦截器与过滤器的区别
Spring的拦截器与Servlet的过滤器有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查,日志记录等。不同的是:
1. 使用范围不同:过滤器Filter是Servlet规范规定的,只能用于Web程序中。而拦截器Interceptor既可以用于Web程序中,也可以用于Application、Swing程序中。
2. 规范不同:Filter是在Servlet规范中定义的,是Servlet容器支持的。而拦截器是Spring容器内的,是Spring框架支持的。
3. 使用的资源不同: 同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过 IOC注入到拦截器即可;而Filter则不能。
4. 深度不同:Filter只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性,所以在Spring构架的程序中,要优先使用拦截器。
过滤器和拦截器的区别:(另一种说法)
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
过滤器与拦截器执行顺序:转载原文
以下是过滤器示例代码
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("过滤器之前...");
chain.doFilter(request, response);
System.out.println("过滤器之后...");
}
chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的。
以下是拦截器示例代码
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器之前···");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器业务逻辑···");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器之后···");
}
1). preHandle()这个方法是在过滤器的chain.doFilter(request, response)
方法的前一步执行,也就是在 System.out.println("过滤器之前...")
和 chain.doFilter(request, response)
之间执行。
2). postHandle()方法是在执行完Controller逻辑,在return ModelAndView
之前进行,可以操控Controller的ModelAndView内容。
3). afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在chain.doFilter(request, response)
和System.out.println("过滤器之后...")
之间执行。
总结: SpringMVC的机制是由同一个Servlet来分发请求,吧请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatc()方法的执行顺序应该是如上图:其实非常好测试,自己写一个过滤器,一个拦截器,然后在这些方法中都加个断点,一路F8下去就得出了结论。
监听器 ( 转载出处)
监听器与以上两种区别较大,这里单独介绍
监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。
分类:
按监听的对象划分
- ServletContext对象监听器:用于监听应用程序环境对象事件
- HttpSession对象监听器:用于监听用户会话对象事件
- ServletRequest对象监听器:用于监听请求消息对象事件
按监听的事件划分
- 对象自身的创建和销毁的监听器
- 对象中属性的创建和消除的监听器
- session中的某个对象的状态变化的监听器
示例:统计在线人数
public class onLineCount implements HttpSessionListener {
public int count=0;//记录session的数量
public void sessionCreated(HttpSessionEvent arg0) {//监听session的创建
count++;
arg0.getSession().getServletContext().setAttribute("Count", count);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {//监听session的撤销
count--;
arg0.getSession().getServletContext().setAttribute("Count", count);
}
}
在web.xml中的配置为:
<listener>
<listener-class>com.ygj.control.onLineCount</listener-class>
</listener>