天天看点

过滤器Filter总结+案例-实现敏感词汇过滤

过滤器Filter案例-实现敏感词汇过滤

Filter概念: web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。

过滤器的作用:

  1. 一般用于完成通用的操作,如:登陆验证,统一编码处理、敏感字符过滤…等。
  2. Filter过滤器能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和Response的内容,实现多次过滤。
  3. Filter可以过滤的web组件包括Servlet,JSP和HTML等文件。

Filter的过滤原理

当浏览器向服务器发出资源的请求时,当浏览器满足过滤条件时,Web服务器根据应用程序配置文件设置的过滤规则进行检查。是一次双向过滤的过程

过滤器Filter总结+案例-实现敏感词汇过滤

过滤器生命周期方法

init()方法:在服务器启动后,会创建filter对象,然后调用init方法。只执行一次,用于加载资源。

doFilter()方法:每一次请求被拦截资源时,会执行,执行多次。

destroy()方法:在服务器关闭后,filter对象会被销毁,如果服务器时正常关闭,则会执行destroy方法,只执行一次,用于释放资源。

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

执行顺序:如果有两个过滤器:过滤器1,过滤器2

过滤器1–>过滤器2–>资源执行–>(返回)–>过滤器2–>过滤1

过滤器先后顺序问题:

注解配置:按照类名的字符串比较规则比较,值小的先执行。

如:Afilter 和 Bfilter,A<B A先执行

过滤器配置

拦截方式配置:dispatcherTypes 资源访问的方式:

//假如时浏览器直接请求index.jsp路径,那么将直接拦截,转发到该路径则不予阻拦
@WebFilter(value = "/index.jsp", dispatcherTypes = DispatcherType.REQUEST)
	//释放代码
   chain.doFilter(req, resp);
           
过滤器Filter总结+案例-实现敏感词汇过滤

案例敏感词的过滤:

代理模式详解图:(灵魂画手)、反正意思就似乎用上代理类,效率高,还能过滤掉敏感词汇

过滤器Filter总结+案例-实现敏感词汇过滤

为什么要用代理模式?

中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

接下来就是实现代理模式

** public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        String name = req.getParameter("name");
       //动态代理增强,增强getParameter方法
        /* 三个参数:
                1. 类加载器:真实对象.getClass().getClassLoader()
                2. 接口数组:真实对象.getClass().getInterfaces()
                3. 处理器:new InvocationHandler()
           这边的真实对象就是ServletRequest req的参数;
         */
        ServletRequest ser = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         /*   代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
                    参数:1. proxy:代理对象
                         2. method:代理对象调用的方法,被封装为的对象
                         3. args:代理对象调用的方法时,传递的实际参数
             */
                //判断是不是getParameter方法
                if (method.getName().equals("getParameter")){
               	  //使用真实对象调用该方法
                    String invoke = (String) method.invoke(req, args);
                    //假如返回的值不为空,则进行敏感字符过滤
                    if (invoke != null ){
                        for (String s : list) {
                            if (invoke.contains(s)){
                                invoke = invoke.replaceAll(s,"***");
                            }
                        }
                    }
                    return invoke;
                }
                return method.invoke(req,args);
            }
        });
        String name1 = ser.getParameter("name");
        String rows = ser.getParameter("rows");
        System.out.println(rows);
        chain.doFilter(ser, resp);

    }
    
	//init方法在第一时间进行执行,并且只会执行一次。把每对敏感字符存入到list集合中
    private List<String> list = new ArrayList<>();
    @Override
    public void init(FilterConfig config) throws ServletException {
        //获取路径
        try {
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("//WEB-INF//classes//敏感词汇.txt");
            //防止乱码 用InputStreamReade是从字节流到字符流的桥梁。
            BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream(realPath),"gbk"));
            String len = null;
            while ((len = bufr.readLine()) != null){
                list.add(len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }**
           
过滤器Filter总结+案例-实现敏感词汇过滤

效果展示:

你是坏蛋,王八蛋
你是***,***
你是***,***