ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

过滤器Filter

2021-04-13 21:58:04  阅读:153  来源: 互联网

标签:MyFilter1 Filter doFilter 过滤器 servlet public


一、概述

过滤器:
地漏,滤网,滤纸,口罩,净水机 :过滤掉杂质

servlet 过滤器:
拦截不符合要求的请求进行拦截,使之不能够到达servlet
对请求的数据进行加工处理

在这里插入图片描述

作用:
1.拦截 (不符合要求请求拦截,使之不达到servlet)
2.抽取公共代码,对共同的的业务进行抽离,加工数据

二、过滤器使用场景

设置编码格式

 //解决当前servlet 接收中文乱码
req.setCharacterEncoding("utf-8");
// 解决响应乱码
resp.setContentType("text/html;charset=utf-8");

记录日志信息

记录所用请求的路径,参数,客户端ip,异常 等信息
为什么记录日志?
在软件的生产/线上环境 只能使用日志排查bug

将鉴权的代码抽离带过滤其中

减少代码冗余

黑白名单,敏感词过滤

举例:一个用户每秒钟访问服务器100次/机器攻击 将用户加入黑名单,拒绝提供服务

三、实现过滤器

实现Filter

编写Java类实现Filter接口
在doFilter方法中编写拦截逻辑
设置拦截路径

import javax.servlet.*;
import java.io.IOException;

/**
 * 第一个过滤器
 * 1.实现 javax.servlet.Filter
 *
 *  2.完成  public void doFilter 方法
 *
 *  3.声明 Filter
 *        1.在web.xml
 *                  <!--
 *         声明 过滤器
 *     -->
 *     <filter>
 *         <filter-name>MyFilter1</filter-name>
 *         <filter-class>com.qfedu.servlet.filter.MyFilter1</filter-class>
 *     </filter>
 *
 *     <!--
 *         为MyFilter1 配置感兴趣的路径
 *         /*   对 / 下所有的路径都惊醒拦截过滤
 *         /goods/*  只对/goods/ 下的路径 过滤
 *
 *         *.do  只对所有 以.do  结尾的路径匹配
 *
 *     -->
 *     <filter-mapping>
 *         <filter-name>MyFilter1</filter-name>
 *         <url-pattern>/*</url-pattern>
 *     </filter-mapping>
 *
 *   2.使用注解声明
 *
 */
public class MyFilter1 implements Filter {
    // 初始化方法  容器启动时加载调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("MyFilter1 -----init");

    }

    @Override // 当请求 符合 过滤器拦截的路径 当前方法执行 过滤/拦截 业务逻辑
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("MyFilter1 -----doFilter");
        // servletRequest 请求
        // servletResponse 响应
        // filterChain 过滤器调用连 ,决定者是否放行当前请求到 后面的过滤器 或者 servlet

        // 放行当前请求  交给后面 的  过滤器 或者 servlet 进行处理
        //如果不写,则默认拦截全部
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        System.out.println("MyFilter1 -----destroy");
    }
}

web.xml声明


    <!--
        声明 过滤器
    -->
    <filter>
        <filter-name>MyFilter1</filter-name>
        <filter-class>com.qfedu.servlet.filter.MyFilter1</filter-class>
    </filter>

    <!--
        为MyFilter1 配置感兴趣的路径
        /*   对 / 下所有的路径都惊醒拦截过滤
        /goods/*  只对/goods/ 下的路径 过滤

        *.do  只对所有 以.do  结尾的路径匹配

    -->
    <filter-mapping>
        <filter-name>MyFilter1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

web.xml声明的优先级

<!--
        声明 过滤器
    -->
    <filter>
        <filter-name>MyFilter1</filter-name>
        <filter-class>com.qfedu.servlet.filter.MyFilter1</filter-class>
    </filter>

    <filter>
        <filter-name>MyFilter2</filter-name>
        <filter-class>com.qfedu.servlet.filter.MyFilter2</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>MyFilter1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--
        在web.xml 中声明 的  <filter-mapping>  的顺寻决定 Filter 拦截的顺序
        <filter-mapping> 越靠上,优先级越高
    -->


    <filter-mapping>
        <filter-name>MyFilter2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

基于注解的声明

基于注解的Filter 过滤的顺序,是按照Filter名称的字典顺序进行加载(也就是按照英文字母)

@WebFilter("/*")// 声明 当前Filter 加入到容器
public class MyFilter1 implements Filter {
。。。。
}

@WebFilter("/*")// 声明 当前Filter 加入到容器
public class MyFilter2 implements Filter {
。。。。
}

设置编码格式过滤器

/**
  配置编码格式
   使用过滤器结局中文乱码问题
 */
@WebFilter("*.do")// 声明 当前Filter 加入到容器
public class EncodingFilter implements Filter {
    // 初始化方法  容器启动时加载调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("EncodingFilter -----init");

    }

    @Override // 当请求 符合 过滤器拦截的路径 当前方法执行 过滤/拦截 业务逻辑
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("EncodingFilter -----doFilter");


        servletRequest.setCharacterEncoding("utf-8");

        // 设置响应编码格式
        // "text/html;charset=utf-8"  告诉浏览器得到响应 使用html 解析该请求
        // css js .png .image 不能解析为html
        servletResponse.setContentType("text/html;charset=utf-8");


        // 放行当前请求交给后面的过滤器或者servlet 进行处理
        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        System.out.println("EncodingFilter -----destroy");
    }
}

登录鉴权过滤器

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

/**
 * 鉴权用户是否登录 过滤器
 */
@WebFilter("*.do")
public class LoginFilter implements Filter {

    // 初始化方法  容器启动时加载调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("LoginFilter -----init");

    }

    @Override // 当请求 符合 过滤器拦截的路径 当前方法执行 过滤/拦截 业务逻辑
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("LoginFilter -----doFilter");

        // 将 ServletRequest 转化为 HttpServletRequest
        HttpServletRequest req  = (HttpServletRequest) servletRequest;

        // 获取当前浏览器请求的session
        HttpSession session = req.getSession();

        // 获取标记位
        Object result =  session.getAttribute("loginFlag");

        if (result!=null){ // 鉴权(鉴定用户是否登录)
            boolean loginFlag = (boolean) result;

            if (loginFlag){ // 鉴权成功  放行

                // 放行当前请求  交给后面 的  过滤器 或者 servlet 进行处理
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }

        }

        // 鉴权失败 需要登录才可以访问
        req.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);

    }

    @Override
    public void destroy() {
        System.out.println("LoginFilter -----destroy");
    }

}

顺序问题总结

1.基于xml声明的Filter,是按照FilterMapping 进行排序
2.注解:基于注解的Filter 过滤的顺序,是按照Filter名称的字典顺序进行加载
3.xml 和注解 的Filter 顺序,所有的xml顺序都优于 注解的顺序

标签:MyFilter1,Filter,doFilter,过滤器,servlet,public
来源: https://blog.csdn.net/xue_yun_xiang/article/details/115679907

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有