面试题:拦截器,过滤器,监听器的区别和触发顺序

监听器(Listener)
@WebListener
public class RequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // TODO Auto-generated method stub
        System.out.println("======销毁监听器========");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("======进入监听器========");
        
    }
}

Listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。其主要可用于以下方面:

  • 统计在线人数和在线用户
  • 系统启动时加载初始化信息
  • 统计网站访问量
  • 记录用户访问路径。

常用的监听器:

  • servletContextListener
  • httpSessionListener
  • servletRequestListener
过滤器(Filter)
//过滤器拦截路径
@WebFilter(urlPatterns = "/api/*", filterName = "loginFilter")
public class TestFilter implements Filter{
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	    System.out.println("拦截器进入========拦截器进入========");
	}
	
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
	    System.out.println("拦截中========拦截中========");
	}
	
	@Override
    public void destroy() {
        System.out.println("拦截器销毁========拦截器销毁========");
    }
}

过滤器是在请求进入tomcat容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前

理解上面这句话我们就可以知道,进入servlet之前,主要是两个参数:ServletRequest,ServletResponse 那我们得到这两个测试可以干哪些事呢?

我们可以通过ServletRequest得到HttpServletRequest,此时你就可以对请求或响应(Request、Response)那就可以对对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如:

  • 实现URL级别的权限访问控制
  • 过滤敏感词汇
  • 压缩响应信息
  • 字符集统一等。

它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。它是随你的web应用启动而启动的,只初始化一次,但是以后就可以每次拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。(每次热部署后,都会销毁)。

拦截器(Interceptor)
public class LoginIntercepter implements HandlerInterceptor{

    /**
     * 进入controller方法之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("LoginIntercepter------->preHandle");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    /**
     * 调用完controller之后,视图渲染之前
     */
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        
        System.out.println("LoginIntercepter------->postHandle");
        
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 整个完成之后,通常用于资源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("LoginIntercepter------->afterCompletion");
        
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

滤器只在servlet前后起作用,所以它既不能捕获异常,获得bean对象等,这些是只能是进入servlet里面的拦截器能过做到。拦截器中用于在某个方法或字段被访问之前,进行拦截然后,在之前或之后加入某些操作。比如日志,安全等。一般拦截器方法都是通过动态代理的方式实现。拦截器除了可以实现过滤器的作用,还可以用于:

  • 进行权限验证
  • 判断用户是否登陆

对比一下其实我们可以发现,过滤器能做的事拦截器都能做,而拦截器做的事过滤器不一定做的了

拦截器实际是上属于Java层面的东西,而过滤器属于JavaWeb中Servlet层面的东西。过滤器只能应用在Servlet中,而拦截器的层面则更高,使用也更广泛。

所以触发顺序其实是:监听器->过滤器->拦截器。


THE END.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值