Java Web-Filter and listener

Filter:过滤器

概述

拦截请求,完成一些特殊的功能。

过滤器的作用:

  1. 一般用于完成通用的一些操作,例如登录验证(通过session来判断访问是否登录,在未登录之前拦截资源访问请求并强制要求登录)、统一编码处理(统一设置request.setCharacterEncoding("utf-8"))、敏感字符的过滤(例如脏话替换为星号)

快速入门

  1. 步骤:

    1. 定义一个类,实现接口Filter

      注意,有多个包中有Filter接口,我们要的是javax.servlet包下的

    2. 复写对应的方法

    3. 配置拦截路径

      1. 通过web.xml配置
      2. 通过注解配置
  2. 示例:

    package com.jiading.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    @WebFilter("/*")//配置的是urlPattern,对当前目录下的所有资源都添加filter
    public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { } @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("filterDemo1被执行了");
    /*
    考虑是否放行
    */
    //放行
    filterChain.doFilter(servletRequest,servletResponse);
    //上面那一行代码不加的话就不放行
    } @Override
    public void destroy() { }
    }

    如果使用web.xml配置:

    如果要使用web.xml进行配置,我们当然先要为项目配置一个web.xml。

    配置过程和配置servlet很像

    <filter>
    <filter-name>demo1</filter-name>
    <filter-class>com.jiading.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>demo1</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-maping>

细节

  1. 过滤器执行流程

    filter对于一次访问的request和response都要检查一遍

    放行代码之前的代码是对于request的检查

    放行代码之后的代码是对于response的检查

  2. 过滤器生命周期方法

    filter对象在服务器启动后就创建,然后调用init方法

    在服务器关闭时,filter对象被销毁。如果是正常关闭服务器,则会执行destory方法

    每一次请求被拦截时,doFilter方法都被执行

  3. 过滤器配置详解

    1. 拦截路径的配置

      1. 具体资源路径:例如/index.jsp
      2. 拦截目录:例如/user/*
      3. 后缀名拦截:*.jsp
      4. 拦截所有资源:例如/*
    2. 拦截方式的配置

      指的是资源被访问的方式,例如浏览器直接访问、重定向、转发等

      拦截方法的配置同样有两种方法:注解配置和web.xml配置

      1. 注解配置

        设置@WebFilter的dispatcherTypes属性,有五种可能属性

        1. REQUEST,默认值,拦截浏览器直接请求的资源
        2. FORWARD,拦截转发访问
        3. INCLUDE,拦截包含访问资源
        4. ERROR,拦截错误跳转(errorPage)
        5. ASYNC,拦截异步访问资源
      2. web.xml配置

        <filter-mapping>标签下设置<dispatcher>子标签

  4. 过滤器链(配置多个过滤器)

    对于一条访问,可以配置多个过滤器,形成所谓的“过滤器链”

    执行顺序:过滤器1-》过滤器2-》资源访问-》过滤器2-》过滤器1

    当拦截路径有重叠时,确定过滤器先后顺序:

    1. 注解配置

      按照类名的字符串比较规则来比较,值小的先执行,例如一个叫A,一个叫B,那么A就先执行。

    2. web.xml配置

      哪个<filter-mapping>定义在上边,谁就先执行

  5. 举例

权限控制(登录验证)

  1. 判断是否是与登录相关的资源。如果是,则直接放行;反之则拦截,判断是否已经登录,也就是session里面是否有user

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    //1.强制转换
    HttpServletRequest request=(HttpServletRequest)req;
    //2.获取资源请求路径
    String url=request.getRequestURI();
    //3.判断是否包含登录相关资源路径
    if(uri.contains("/login.jsp")||uri.contains("/loginServlet")||uri.contains(<登录页面需要的图片、验证码、CSS等资源>)){
    //证明用户此时的请求就是想要登录,直接放行
    chain.doFilter(req,resp);
    }else{
    //验证用户是否登录,从session中获取user
    request.getSession().getAttribute("user");
    if(user!=null)//说明用户已经登录了
    chain.doFilter(req,resp);
    else{
    //跳转登录页面
    request.setAttribute("login_msg","您尚未登录,请登录");
    request.getRequestDispatcher("/login.jsp").forward(request,resp);
    }
    }
    }
  2. 敏感词汇过滤

    对request对象进行增强,采用设计模式来完成,有23中Java设计模式。装饰模式、代理模式都可以用来增强对象的功能。这里我们选择代理模式的动态代理。

    关于代理模式、装饰模式,可以看我的这篇博文

    代理模式:

    1. 概念

      真实对象:被代理的对象

      代理对象

      代理模式:代理对象来通过代理的方式来增强真实对象的功能

    2. 实现方式

      • 静态代理:有一个类文件描述代理模式
      • 动态代理:在内存中形成代理类

      动态代理用的比较多,这里我们就使用动态代理

    3. 实现步骤

      1. 代理对象和真实对象实现相同的接口

      2. 实例化真实对象

      3. 使用Proxy.newProxyInstance(classLoader,Class,InvocationHandler)来获取代理对象

        classLoader:被代理对象的类加载器

        Class:数组,真实对象实现的接口

        InvocationHandler:一般通过匿名内部类创建该对象

      4. 使用代理对象来调用方法(因为实现了相同的接口,所以可以直接调用代理对象)

      5. 增强方法

        1. 增强参数列表
        2. 增强返回值类型
        3. 增强方法体执行逻辑
    4. 示例:示例程序见我的这篇博文

    5. 实现:

      我们使用过滤器对除登录页面之外的所有页面进行过滤,在过滤器内对ServletRequest对象进行代理,该代理对象对getParameters等获取用户输入参数的方法进行增强:通过遍历敏感词数组检查用户输入参数是否包括敏感词(敏感词数组在init()方法中已经加载到了内存中,保存在过滤器对象内),如果包含,就将敏感词进行替换后返回。

      这样,如果服务器要调用该对象的getParameters()、getParameterMap()、getParameterValue()等方法来获取用户输入的值时,就会因为方法名被拦截下来,拆包、替换。

      因为服务器在通信中只需要获取用户传入的参数,也就是request中的参数,所以凭方法名就可以有效拦截

      ServletRequest proxy_req=(ServletRequest)Proxy.newProxyInstance(req.getClass().getClassLoader(),req.getClass().getInterfaces(),new InvocationHandler(){
      @Override
      public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
      if(method.getName().equals("getParameter")){
      String value=(String)method.invoke(req,args);
      if(value!=null){
      for(String str:list){
      if(value.contains(str){
      value=value.replaceAll(str,"***");
      })
      }
      }
      return value;
      }
      return method.invoke(req,args);
      } })

Listener:监听器

概念

Web三大组件之一

  • 事件的监听机制
  1. 事件:都懂得
  2. 事件源:事件发生的对象
  3. 监听器:一段代码或者一个对象
  4. 注册监听:将事件、事件源、监听器绑定在一起。当时间源上发生某个事件后,执行监听器代码
  • ServletContextListener

    是一个接口,没有对应的实现类,需要自己写

    方法:

    1. void contextInitialized(ServletContext sce),初始化
    2. void contextDestroyed(ServletContext sce),销毁时调用

    这部分用的不多,是略讲的:

    步骤:

    1. 定义一个类来实现该接口

    2. 复写方法

    3. 配置:web.xml或者注解

      • web.xml

        <listener>
        <listener-class>com.jiading.filter.Listener</listener-class>
        </listener>
      • 注解

        @WebListener

    示例:

    Listener.java

    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException; public class Listener implements ServletContextListener {
    /*
    在服务器启动后自动创建,用来监听ServletContext对象(也是服务器启动时自动创建)
    */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
    //一般用来加载资源文件:
    //1.加载ServletContext对象
    ServletContext servletContext = servletContextEvent.getServletContext();
    //2.加载资源文件
    String initParameter = servletContext.getInitParameter("contextConfigLocation");
    //3.获取真实路径
    String realPath = servletContext.getRealPath(initParameter);
    //4.加载资源文件进内存
    try {
    FileInputStream fis=new FileInputStream(realPath);
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    //我们可以在web.xml中指定初始化信息,详见web.xml
    System.out.println("ServletContextListener被创建了");
    } @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    System.out.println("ServletContextListener被销毁了");
    }

    在web.xml中可以创建ServletContext的参数:

        <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/test.xml</param-value>
    </context-param>

真正使用时,监听器一般是框架写好的,一般使用的时候会配置就可以了

Java Web-Filter and listener的更多相关文章

  1. Java Web(五) 监听器Listener

    监听器概述 在上一篇里介绍了过滤器Filter,而Listener是Servlet的另一个高级特性.Listener用于监听Java Web程序中的事件,例如创建,修改,删除Session,reque ...

  2. 【java web】监听器listener

    一.简介 Java的监听器,也是系统级别的监听.监听器随web应用的启动而启动.Java的监听器在c/s模式里面经常用到,它会对特定的事件产生产生一个处理.监听在很多模式下用到,比如说观察者模式,就是 ...

  3. java web filter 学习(2)

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  4. java web filter 之一 基础实现

    本文主要对filter的基本使用进行了讲解,其中涉及到了 filter是什么 一个filter处理一个jsp 多个filter处理一个jsp filter是什么 Filter 是java下的一种过滤器 ...

  5. java web filter读取classpath配置文件内容

    以下demo,从类路径classpath中获取venus.properties(本项目中用到的文件),思路是在初始化的时候读取,然后放在局部变量里面. package club.codeapes.we ...

  6. Java Web Filter登录验证

    初做网站需要登录验证,转自 :http://blog.csdn.net/daguanjia11/article/details/48995789 Filter: Filter是服务器端的组件,用来过滤 ...

  7. 学习java web中的listener

    web.xml里的顺序为:context-param->listener->filter->servlet 监听器是需要新建一个类,然后按监听的对象继承:ServletContext ...

  8. 【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener

    [Java Web开发学习]Spring MVC添加自定义Servlet.Filter.Listener 转载:https://www.cnblogs.com/yangchongxing/p/9968 ...

  9. 【Java Web开发学习】Servlet、Filter、Listener

    [Java Web开发学习]Servlet 转发:https://www.cnblogs.com/yangchongxing/p/9274739.html 1.Servlet package cn.y ...

  10. 【Web】servlet、filter和listener

    一般地,servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是:context-param -> listener -> filter -&g ...

随机推荐

  1. github又提交不了代码了..... X_X

    如下: 我们使用git提交代码过程中,突然就登录不上了 原因是 用户名被更改了:git@gitlab.0easy.com 是你的用户名 造成的原因是: 我们clone代码过程中选择了SSH的地址 解决 ...

  2. android: 日期转Unix时间戳,Unix时间戳转日期,带时区

    1.UTC时间&GMT时间 UTC时间是时间标准时间(Universal Time Coordinated),UTC是根据原子钟来计算时间,误差非常小. UTC也是指零时区的时间,如果要表示其 ...

  3. $createElement实现自定义弹窗

    <el-button type="text" @click="open4">点击打开 Message Box</el-button> m ...

  4. LC 516. Longest Palindromic Subsequence

    Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...

  5. Tomcat日志监控工具——Probe

    今天遇到项目运行过程中需要查看用户访问日志,log4j.properties配置好,将log日志输出到tomcat的log文件夹下,但不可能每次都去服务器上拉取log文件查看,网上找了下,发现一个日志 ...

  6. Linux 下kafka集群搭建

    主机的IP地址: 主机IP地址 zookeeper kafka10.19.85.149 myid=1 broker.id=110.19.15.103 myid=2 broker.id=210.19.1 ...

  7. 启后台JOB处理单据遇到锁定问题

    /用户XXX已经处理采购凭证 9000036590 DN过账失败:/已冻结临时过账:用户 XXX已冻结编号范围 /用户XXX已经处理采购凭证 9000036589   ???问题:怎么检查采购订单正在 ...

  8. LeetCode_66. Plus One

    66. Plus One Easy Given a non-empty array of digits representing a non-negative integer, plus one to ...

  9. Masonry详解

    - (void)viewDidLoad { [super viewDidLoad]; //1.view1 居中显示 UIView *view1 = [[UIView alloc]init]; view ...

  10. 2.app自动化测试--adb常用API

    adb常用API  Driver.current_activity 获取当前运行应用界面的启动名 Driver.current_package 获取当前运行应用的包名 Driver.contexts ...