javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)


文章目录

  • 1.Filter
    • 1.2 Filter快速入门
    • 1.3 Filter执行流程
    • 1.4 Filter拦截路径配置
    • 1.5 过滤器链
    • 1.6 案例
      • 1.6.1 判断用户是否登陆: 过滤器完整代码
  • 2 Listener
      • 2.3 代码演示

1.Filter javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。Servlet 我们之前都已经学习过了,Filter和Listener 我们今天都会进行学习。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
1.2 Filter快速入门 javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

接下来编写过滤器。过滤器是 Web 三大组件之一,所以我们将 filter 创建在 com.itheima.web.filter 包下,起名为 FilterDemo
@WebFilter("/*") public class FilterDemo implements Filter {@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("FilterDemo..."); //放行 chain.doFilter(request,response); }@Override public void init(FilterConfig filterConfig) throws ServletException { }@Override public void destroy() { } }

1.3 Filter执行流程 javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

1.4 Filter拦截路径配置 javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

1.5 过滤器链 javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

上图中的过滤器链执行是按照以下流程执行:
  1. 执行 Filter1 的放行前逻辑代码
  2. 执行 Filter1 的放行代码
  3. 执行 Filter2 的放行前逻辑代码
  4. 执行 Filter2 的放行代码
  5. 访问到资源
  6. 执行 Filter2 的放行后逻辑代码
  7. 执行 Filter1 的放行后逻辑代码
以上流程串起来就像一条链子,故称之为过滤器链。
  • 编写第一个过滤器 FilterDemo ,配置成拦截所有资源
    @WebFilter("/*") public class FilterDemo implements Filter {@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//1. 放行前,对 request数据进行处理 System.out.println("1.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 数据进行处理 System.out.println("5.FilterDemo..."); }@Override public void init(FilterConfig filterConfig) throws ServletException { }@Override public void destroy() { } }

  • 编写第二个过滤器 FilterDemo2 ,配置炒年糕拦截所有资源
    @WebFilter("/*") public class FilterDemo2 implements Filter {@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//1. 放行前,对 request数据进行处理 System.out.println("2.FilterDemo..."); //放行 chain.doFilter(request,response); //2. 放行后,对Response 数据进行处理 System.out.println("4.FilterDemo..."); }@Override public void init(FilterConfig filterConfig) throws ServletException { }@Override public void destroy() { } }

  • 修改 hello.jsp 页面中脚本的输出语句
    Title hello JSP~

  • 启动服务器,在浏览器输入 http://localhost/filter-demo/hello.jsp 进行测试,在控制台打印内容如下
    javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
    文章图片

1.6 案例 javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

1.6.1 判断用户是否登陆: 过滤器完整代码
@WebFilter("/*") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest) request; //判断访问资源路径是否和登录注册相关 //1,在数组中存储登陆和注册相关的资源路径 String[] urls = {"/login.jsp","/imgs/","/css/","/loginServlet","/register.jsp","/registerServlet","/checkCodeServlet"}; //2,获取当前访问的资源路径 String url = req.getRequestURL().toString(); //3,遍历数组,获取到每一个需要放行的资源路径 for (String u : urls) { //4,判断当前访问的资源路径字符串是否包含要放行的的资源路径字符串 /* 比如当前访问的资源路径是/brand-demo/login.jsp 而字符串 /brand-demo/login.jsp 包含了字符串 /login.jsp ,所以这个字符串就需要放行 */ if(url.contains(u)){ //找到了,放行 chain.doFilter(request, response); //break; return; } }//1. 判断session中是否有user HttpSession session = req.getSession(); Object user = session.getAttribute("user"); //2. 判断user是否为null if(user != null){ // 登录过了 //放行 chain.doFilter(request, response); }else { // 没有登陆,存储提示信息,跳转到登录页面req.setAttribute("login_msg","您尚未登陆!"); req.getRequestDispatcher("/login.jsp").forward(req,response); } }public void init(FilterConfig config) throws ServletException { }public void destroy() { } }

2 Listener javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

这里面只有 ServletContextListener 这个监听器后期我们会接触到,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。
ServletContextListener 接口中有以下两个方法
  • void contextInitialized(ServletContextEvent sce)ServletContext 对象被创建了会自动执行的方法
  • void contextDestroyed(ServletContextEvent sce)ServletContext 对象被销毁时会自动执行的方法
2.3 代码演示
【javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)】javaWEb|黑马程序( 12、Filter 过滤器 ,Listener监听器)
文章图片

我们只演示一下 ServletContextListener 监听器
  • 定义一个类,实现ServletContextListener 接口
  • 重写所有的抽象方法
  • 使用 @WebListener 进行配置
代码如下:
@WebListener public class ContextLoaderListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { //加载资源 System.out.println("ContextLoaderListener..."); }@Override public void contextDestroyed(ServletContextEvent sce) { //释放资源 } }

启动服务器,就可以在启动的日志信息中看到 contextInitialized() 方法输出的内容,同时也说明了 ServletContext 对象在服务器启动的时候被创建了。

    推荐阅读