JavaWeb之监听器和过滤器

说起监听器和过滤器,就得说一下JavaWeb的三大组件了:

  • Servlet
  • Listener
  • Filter

一、监听器概述

这里有三个概念,监听的事件源监听者事件,举个栗子来说是这样的,警察抓小偷,警察是监听者,小偷是被监听的事件源,抓小偷这个动作就是事件,什么时候会抓小偷呢?在小偷偷东西的时候。
这个概念在前端开发中比较常用,但是在Java服务器端用的相对比较少,比如你在浏览网页的过程中,第一次进入并不会全部加载页面的信息,而是加载一部分,你向下浏览网页,网页才会加载,这也是监听的一种体现形式,你向下滑动网页的过程就是监听的事件源,加载网页就是事件,监听者就是服务器程序咯,可能这些用词不是太准确,但是也算是表达了这个意思。
JavaWeb中,监听的事件源有三个:

  • ServletContext
  • HttpSession
  • ServletRequest

它都会监听什么呢?

  • 监听域对象的创建和销毁的监听器
  • 监听域对象操作域属性的监听器
  • 监听HttpSession的监听器

实例

/*
 * ServletContextListener实现类
 * contextDestroyed() -- 在ServletContext对象被销毁前调用
 * contextInitialized() --  -- 在ServletContext对象被创建后调用
 * ServletContextEvent -- 事件类对象
 *     该类有getServletContext(),用来获取ServletContext对象,即获取事件源对象
 */
public class MyServletContextListener implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent evt) {
        System.out.println("销毁ServletContext对象");
    }

    public void contextInitialized(ServletContextEvent evt) {
        System.out.println("创建ServletContext对象");
    }
}

net.sailfish.listener.MyServletContextListener

  • 监听器要在web.xml中进行配置
  • 监听器的方法都是类似的,这里列出的是域对象的创建和销毁的监听器
  • ServletContextListener在tomcat启动时创建,在tomcat关闭的时候销毁

二、过滤器

  • 过滤器和Servlet比较相似,不过Servlet是处理请求的,但是Filter是用来拦截请求的
  • 过滤器在Servlet之前指向
  • 简单来说Filter是用来决定Servlet是否执行的
JavaWeb之监听器和过滤器_第1张图片
Paste_Image.png
  • 过滤器可以存在多个
  • 过滤器是有执行顺序的
  • 过滤器有拦截规则

过滤器应用

上面大概说一下过滤器,下面主要是应用实践。

分ip统计网站的访问次数

JavaWeb之监听器和过滤器_第2张图片
Paste_Image.png

思路是这样的:

  • 新建一个Listener用于监听ServletContext
  • 在监听器中新建一个Map,将map放入context域中,这样可以保证tomcat已启动就可以创建
  • 新建过滤器,默认拦截所有请求
  • 获取到context中的map属性
  • 通过request获取到请求ip
  • 如果ip已经存在,就在原来的数量上加1
  • 如果ip不存在,就设置ip为1

监听器

public class IPListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent evt) {
        /*
         * 在ServletContext被创建后,就把map保存到ServletContext中
         * 这就保证了在Filter中获取ServletContext中的map,一定会获取到!!!
         */
        /*
         * 1. 得到ServletContext
         * 2. 创建map,并保存
         */
        evt.getServletContext().setAttribute("map", new LinkedHashMap());
    }

    public void contextDestroyed(ServletContextEvent evt) {
    }
}

过滤器

public class IPFilter implements Filter {
    private FilterConfig config;
    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        /*
         * 1. 得到map
         * 2. 得到ip
         * 3. 得到次数
         * 4. 把ip为key,次数为value,保存到map中!
         * 5. 放行!
         */
        /*
         * 1. 得到map
         *   * 得到FilterConfig
         *   * 得到ServletContext
         *   * 得到Map
         */
        Map map = (Map) this.config
                .getServletContext().getAttribute("map");
        
        /*
         * 2. 得到IP
         */
        String ip = request.getRemoteAddr();
        /*
         * 3. 得到次数
         */
        if(map.containsKey(ip)) {//原来就包含这个ip的统计
            int cnt = map.get(ip) + 1;//获取原统计,再加1
            map.put(ip, cnt);
        } else {//原来没有这个ip的统计
            map.put(ip, 1);
        }
        
        /*
         * 4. 放行
         */
        chain.doFilter(request, response);
    }

    public void init(FilterConfig fConfig) throws ServletException {
        this.config = fConfig;
    }
}

简单权限控制

  • index.jsp都可以访问
  • user下的只有登录才可以访问
  • admin下的只有管理员才可以访问

思路:

  • 用户类:username,password,grade,grade用来控制权限,1代表普通用户,2代表管理员
  • 新建两个用户,一个是普通用户,一个是管理员账户
  • 不登录的情况下访问user和admin都不能访问
  • 登陆普通用户访问不了admin

不登录情况

JavaWeb之监听器和过滤器_第3张图片
Paste_Image.png
JavaWeb之监听器和过滤器_第4张图片
Paste_Image.png
JavaWeb之监听器和过滤器_第5张图片
Paste_Image.png
JavaWeb之监听器和过滤器_第6张图片
Paste_Image.png

登陆普通用户

JavaWeb之监听器和过滤器_第7张图片
Paste_Image.png

user页面可以访问!

JavaWeb之监听器和过滤器_第8张图片
Paste_Image.png

admin访问不了

JavaWeb之监听器和过滤器_第9张图片
Paste_Image.png

登陆管理员账号

JavaWeb之监听器和过滤器_第10张图片
Paste_Image.png

user页面可以访问

JavaWeb之监听器和过滤器_第11张图片
Paste_Image.png

admin也可以访问:

JavaWeb之监听器和过滤器_第12张图片
Paste_Image.png

总结

这虽然是一个很简单的项目,但是还是在一定程度上体现出来了Filter的作用,代码贴太多也不好,把项目上传到了GitHub上了,有兴趣的童鞋可以看看。
项目地址:https://github.com/Sailfishc/filter-demo

你可能感兴趣的:(JavaWeb之监听器和过滤器)