Filter(过滤器)

发布时间:2022-07-03 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Filter(过滤器)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

目录
  • Filter 介绍
  • Filter API
  • Filter 生命周期
  • Filter 入门案例
  • FilterConfig:过滤器配置对象

Filter 介绍

什么是 Filter ?

Filter(过滤器)是 JavaWeb 三大组件之一(另外两个是 Servlet 和 Listener),是在 2000 年发布的 Servlet2.3 规范中加入的一个接口,是 Servlet 规范中非常实用的技

它可以对 web 应用中的所有资进行拦截,并且在拦截之后进行一些特殊的操作。

  • 当一个请求访问服务器资源时,服务器首先判断会是否有过滤器与请求资源相关联,如果有,过滤器会先将请求拦截下来,完成一些特定的功能,再由过滤器决定是否继续交给请求资源进行处理。
  • 响应也是类似的。

Filter 应用场景

  • URL 级别的权限控制
  • 过滤敏感词汇
  • 中文乱码问题
  • ...

Filter API

Filter

Filter 是一个接口。如果想实现过滤器的功能,则必须实现该接口。

核心方法:

返回值 方法名 作用
void inIT(FilterConfig config) 初始化方法
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 对请求资源和响应资源进行拦截
void destroy() 销毁方法

配置方式:

  • 方式一:使用注解 @WebFilter("拦截路径")

  • 方式二:web.XMl 配置

    Filter(过滤器)

Filter(过滤器)

Filter(过滤器)

FilterChain

  • FilterChain 是一个接口,代表过滤器链对象,由 Servlet 容器提供实现类对象,我们直接使用即可。

  • 过滤器可以定义多个,就会组成过滤器链。

核心方法:

返回值 方法名 作用
void doFilter(ServletRequest request, ServletResponse response) 放行方法
  • 如果有多个过滤器,则会在第一个过滤器中再调用下一个过滤器,依次类推,直到到达最终访问资源。
  • 如果只有一个过滤器,放行时,就会直接到达最终访问资源。

Filter(过滤器)

FilterConfig

FilterConfig 是一个接口,代表过滤器的配置对象,可以加载一些初始化参数。

核心方法:

返回值 方法名 作用
String getFilterName() 获取过滤器对象名称
String getInitParameter(String key) 根据 key 获取 value
Enumeration<String> getInitParameternames() 获取所有参数的 key
ServletContext getServletContext() 获取应用上下文对象

Filter(过滤器)

Filter 生命周期

@H_304_245@
  • 出生:当应用加载时,执行初始化方法。
  • 活着:只要应用一直提供服务,对象就一直存在。
  • 死亡:当应用卸载时(执行销毁方法)或服务器宕机时,对象消亡。
  • Filter 的实例对象在内存中也只有一份,所以 Filter 也是单例的。

    import javax.servlet.*;
    import java.io.IOException;
    
    /*
        过滤器生命周期
     */
    //@WebFilter("/*")
    public class FilterDemo03 implements Filter{
    
        /*
            初始化方法
         */
        @override
        public void init(FilterConfig filterConfig) {
            System.out.PRintln("对象初始化成功了...");
        }
    
        /*
            提供服务方法
         */
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("filterDemo03执行了...");
    
            //处理乱码
            servletResponse.setContentTyPE("text/htML;charset=UTF-8");
    
            //放行
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        /*
            对象销毁
         */
        @Override
        public void destroy() {
            System.out.println("对象销毁了...");
        }
    }
    

    Filter 入门案例

    1)编写接收和处理请求的 Servlet:

    public class ServletDemo1 extends HttpServlet {
    
        /**
         * 处理请求的方法
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("ServletDemo1接收到了请求");
            req.getRequestDispatcher("/WEB-iNF/pages/success.jsp").forward(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           doGet(req,resp);
        }
    }
    

    2)配置 Servlet:

    <?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"
             metadata-complete="true">
        
        <!--配置Servlet-->
        <servlet>
            <servlet-name>ServletDemo1</servlet-name>
            <servlet-class>com.itheima.web.servlet.ServletDemo1</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>ServletDemo1</servlet-name>
            <url-pattern>/ServletDemo1</url-pattern>
        </servlet-mapping>
    </web-app>
    

    3)编写 index.jsp:

    <%-- Created by IntelliJ IDEA. --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>主页面</title>
      </head>
      <body>
        <a href="${pageContext.request.contextPath}/ServletDemo1">访问ServletDemo1</a>
      </body>
    </html>
    

    4)编写 success.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>成功页面</title>
    </head>
    <body>
    <% System.out.println("success.jsp执行了"); %>
    执行成功!
    </body>
    </html>
    

    5)编写 Filter:

    public class FilterDemo1 implements Filter {
    
        /**
         * 过滤器的核心方法
         * @param request
         * @param response
         * @param chain
         * @throws IOException
         * @throws ServletException
         */
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            /**
             * 如果不写此段代码,控制台会输出两次:FilterDemo1拦截到了请求。
             */
            HttpServletRequest req = (HttpServletRequest) request;
            String requestURI = req.getRequestURI();
            if (requestURI.contains("favicon.ico")) {
                return;
            }
    
            System.out.println("FilterDemo1拦截到了请求");
        }
    }
    

    6)配置 Filter:

    <!--配置过滤器-->
    <filter>
        <filter-name>FilterDemo1</filter-name>
        <filter-class>com.itheima.web.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    运行结果分析:

    Filter(过滤器)

    当我们启动服务并在地址栏输入访问地址后,发现浏览器任何内容都没有,控制台却输出了【FilterDemo1拦截到了请求】,也就是说在访问任何资源的时候,都先经过了过滤器。

    这是因为,我们在配置过滤器的拦截规则时,使用了/*,表示访问当前应用下的任何资源,此过滤器都会起作用。

    除了这种全部过滤的规则之外,它还支持特定类型的过滤配置。我们可以稍作调整,修改的方式如下:

    Filter(过滤器)

    新的问题是,我们拦截下来了,但点击链接发送请求,运行结果是:

    Filter(过滤器)

    对此,需要对过滤器执行放行操作,才能让它继续执行,那么如何放行的?

    我们需要使用FilterChain中的doFilter方法放行。

    Filter(过滤器)

    继续修改:在FilterDemo1doFilter方法后添加一行代码

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            /**
             * 如果不写此段代码,控制台会输出两次:FilterDemo1拦截到了请求。
    
            HttpServletRequest req = (HttpServletRequest) request;
            String requestURI = req.getRequestURI();
            if (requestURI.contains("favicon.ico")) {
                return;
            }*/
            System.out.println("FilterDemo1拦截到了请求");
            // 过滤器放行
            chain.doFilter(request,response);
            // 新增一行代码
            System.out.println("FilterDemo1放行之后,又回到了doFilter方法");
        }
    

    运行结果如下,我们发现过滤器放行之后执行完目标资源,最后仍会回到过滤器中。

    Filter(过滤器)

    FilterConfig:过滤器配置对象

    1)新增过滤器 FilterDemo2 :

    public class FilterDemo2 implements Filter {
    
        private FilterConfig filterConfig;
    
        /**
         * 初始化方法
         */
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("FilterDemo2的初始化方法执行了");
            // 给过滤器配置对象赋值
            this.filterConfig = filterConfig;
        }
    
        /**
         * 过滤器的核心方法
         */
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
            System.out.println("FilterDemo2拦截到了请求");
    
            // 根据名称获取过滤器的初始化参数
            String paramValue = filterConfig.getInitParameter("filterInitParamName");
            System.out.println(paramValue);
    
            // 获取过滤器初始化参数名称的枚举
            Enumeration<String> initNames = filterConfig.getInitParameterNames();
            while(initNames.hasMoreElements()){
                String initName = initNames.nextElement();
                String initValue = filterConfig.getInitParameter(initName);
                System.out.println(initName+","+initValue);
            }
    
            // 获取ServletContext对象
            ServletContext servletContext = filterConfig.getServletContext();
            System.out.println(servletContext);
    
            // 获取过滤器名称
            String filterName = filterConfig.getFilterName();
            System.out.println(filterName);
    
            // 过滤器放行
            chain.doFilter(request, response);
        }
        
        /**
         * 销毁方法
         */
        @Override
        public void destroy() {
            System.out.println("FilterDemo2的销毁方法执行了");
        }
    }
    

    2)配置 FilterDemo2 :

    <filter>
        <filter-name>FilterDemo2</filter-name>
        <filter-class>com.itheima.web.filter.FilterDemo2</filter-class>
        <!--配置过滤器的初始化参数-->
        <init-param>
            <param-name>filterInitParamName</param-name>
            <param-value>filterInitParamValue</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>FilterDemo2</filter-name>
        <url-pattern>/ServletDemo1</url-pattern>
    </filter-mapping>
    

    运行效果

    Filter(过滤器)

    脚本宝典总结

    以上是脚本宝典为你收集整理的Filter(过滤器)全部内容,希望文章能够帮你解决Filter(过滤器)所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。