监听器(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.