Filter过滤器

过滤器

  1. 概念:用来过滤用户的请求和响应,修改用户请求和响应的数据,对请求进行拦截
  2. 作用:
  • 解决全局乱码问题
    解决全局乱码问题

  • 过滤论坛发表内容中的非法字符

  • 登录权限的检查
    登录权限的检查

  1. 使用过滤器
    步骤:
    (1) 创建类实现Filter接口
    (2) 注解配置过滤器拦截的请求路径
    (3) 在doFilter方法中描写过滤任务
    (4) 调用chain.Filter方法放行
  2. 注意事项:
    (1) Filier类是一个接口
    (2) 只有访问过滤器请求路径指定的网页才会执行过滤功能
    (3) doFilter方法默认拦截请求,如果需要经过过滤器之后可以继续访问资源,需要调用chain.Filter方法放行
  3. 过滤器的执行流程
    过滤器的执行流程
    先执行Demo1Filter的doFilter方法,如果存在chain.doFilter放行就执行Demo1Servlet,再回到Demo1Filter
  4. 过滤器的生命周期
    过滤器的生命周期相关的方法包括三个,分别是:init,doFilter,destroy
  • init方法
    创建Filter对象的时候调用init方法,服务器启动则会创建Filter对象,调用init方法,并说明Filter对象在内存中只有一个
    应用场景:配置文件的代码可以放在init方法中执行,这样配置文件代码只会自行一次
  • doFilter方法
    每次请求符合过滤路径就会执行一次
  • destroy方法
    Filter对象销毁的时候会执行destroy方法,服务器重启或关闭的时候会销毁Filter对象,从而执行destroy方法
  1. 映射路径
    介绍:配置过滤器不同的映射路径可以让过滤器有选择地过滤请求
    7.1 精准匹配
    路径为完整路径,比较"/demo01",“/1.html”。只有访问demo01或者1.html的时候才会执行过滤功能
    7.2 模糊匹配(必须使用到通配符"*“)
    使用规则:
    (1) 如果是”/"开头的路径,必须以*符号结尾。如果*不在结尾,则*通配符失效,失去通配符的作用,变成普通的*
    使用:

    1. 映射路径为:/*,则表示过滤全局资源
    2. 映射路径为:/目录名称…/*,表示要访问目录下的所以文件时,会执行过滤功能
      (2) 如果需要匹配后缀名,则必须需要以"*"符号开头。比如*.jsp,*.html
  2. 拦截方式
    注意:过滤器只会过滤url地址直接访问和请求重定向的资源,不会拦截请求转发的资源
    8.1 拦截方式类别
    (1) request,默认的拦截方式,只会过滤url地址直接访问和请求重定向,不会拦截请求转发
    (2) forward,只会拦截请求转发的资源
    配置方式:dispatcherTypes用于配置拦截方式
    在@WebFilter()中配置dispatcherTypes的属性,dispatcherTypes = dispatcherType.REQUEST或FORWARD
    注意:dispatcherTypes是一个数组类型,如果想要过滤三种方式的资源,可以赋值一个数组值,如:dispatcherTypes = {dispatcherType.REQUEST,dispatcherType.FORWARD}

  3. 过滤器链

    1. 概念: 访问资源的时候会经过多重过滤,多个过滤器组合成过滤器链
    2. 执行流程
      过滤器链的执行流程
    3. 注意实现:
      (1) 如果访问一个资源需要经过多个过滤器,则过滤器的执行顺序取决于Filter的类名的字符串顺序,与filterName无关(不推荐)
      (2) 把filter的信息配置在web.xml文件上,执行顺序按照web.xml的先后配置执行(推荐)
      配置过程:
      点击Project Struct

    在这里插入图片描述
    项目中存在的文件
    AB过滤器都要过滤TestServlet
    在这里插入图片描述

在web.xml文件中配置过滤器的映射路径,先配置哪个过滤器哪个就先执行

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">



    <!-- 先配置哪个过滤器哪个过滤器则先执行 -->
    <!--先配置了B过滤器所以先执行B过滤器-->
    <!-- 配置Filter的基本信息 -->
    <filter>
        <!--别名-->
        <filter-name>BFilter</filter-name>
        <!--完整类名-->
        <filter-class>filter.BFilter</filter-class>
    </filter>

    <!--映射信息-->
    <filter-mapping>
        <!--别名-->
        <filter-name>BFilter</filter-name>
        <!--映射路径-->
        <url-pattern>/demo01</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>AFilter</filter-name>
        <filter-class>filter.AFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>AFilter</filter-name>
        <url-pattern>/demo01</url-pattern>
    </filter-mapping>

</web-app>

运行结果
在这里插入图片描述
执行顺序:B->A->servlet->A->B

案例一

  1. 需求:过滤言论,屏蔽不文明词汇,将不文明词汇变成*
  2. 代码
package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

//检测言语
@WebFilter(filterName = "TalkFilter",urlPatterns = "/talk")
public class TalkFilter implements Filter {

    private List<String> list = new ArrayList<>();

    public void init(FilterConfig config) throws ServletException {
        //加载配置文件,将内容存入集合中
        try {

            //1.得到配置文件的流对象
            InputStream resourceAsStream = TalkFilter.class.getResourceAsStream("/improper/improperLanguage.txt");
            //2. 将字节流转成字符流,InputStreamReader流默认编码方式为gbk,所以需要指定编码方式为utf-8
            InputStreamReader reader = new InputStreamReader(resourceAsStream,"utf-8");
            //3. 得到BufferedReader对象,从而可以是用该类的readLine()方法
            BufferedReader bufferedReader = new BufferedReader(reader);
            //4. 开始存储数据
            String line = null;
            while((line = bufferedReader.readLine()) != null){
                list.add(line);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //解决中文输出乱码问题
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        //拦截言论

        //1. 得到用户输入的言论
        String content = req.getParameter("talk");
        boolean key = false;
        //2. 开始检测
        for (String con : list) {
            if(content.contains(con)){
                key = true;
                content = replaceImproperChar(content,con);

            }

        }
        if(key){
            out.write(content);
            return;
        }else{
            //放行
            chain.doFilter(req, resp);
        }

    }



    public void destroy() {
    }

    private String replaceImproperChar(String content, String replaceStr){
        //得到首字母所在的索引
        int index = 0;
        do {
            index = content.indexOf(replaceStr);
            if(index >= 0){
                //转成char类型数组
                char[] contentCharArray = content.toCharArray();
                //开始替换
                for(int i = 0; i < replaceStr.length(); i++){
                    contentCharArray[index + i] = '*';
                }
                content = new String(contentCharArray);
            }

        }while(index >= 0);

        return content;
    }

}

案例二

  1. 需求:解决全站的中文输出乱码问题和post请求接受中文乱码问题
  2. 代码
package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

//解决全站的乱码问题和post请求接受中文乱码问题
@WebFilter(filterName = "CharacterFilter", urlPatterns = "/*")
public class CharacterFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //解决全站乱码问题
        resp.setContentType("text/html;charset=utf-8");
        //解决post请求接受乱码问题
        //1. 强制类型转换,ServletRequest是HttpServletRequest的父类
        HttpServletRequest request = (HttpServletRequest) req;
        //2. 调用getMethod方法得到请求方式
        String method = request.getMethod();
        //3. 判断,如果是post方法则将编码方式设置为utf-8
        if("post".equalsIgnoreCase(method)){
            request.setCharacterEncoding("utf-8");
        }
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值