过滤器Filter

1.filter简介

Flter中文意思为过滤器。顾名思义,过滤器可在浏览器以及目标资源之间起到一个过滤的作用。例如:水净化器,可以看成是生活中的一个过滤器,他可以将污水中的杂质过滤,从而使进入的污水变成净水。

对于WEB应用来说,过滤器是一个驻留在服务器中的WEB组件,他可以截取客户端和WEB资源之间的请求和响应信息。

WEB资源可能包括Servlet、JSP、HTML页面等。

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:
过滤器Filter_第1张图片

Filter是Tomcat容器内的过滤器,在请求到达容器是先会调用过滤器,再调用我们的servlet或者jsp

当服务器收到特定的请求后,会先将请求交给过滤器,程序员可以在过滤器中对请求信息进行读取修改等操作,然后将请求信息再发送给目标资源。目标资源作出响应后,服务器会再次将响应转交给过滤器,在过滤器中同样可以对响应信息做一些操作,然后再将响应发送给浏览器。

2.Filter过滤器的介绍

  1. Filter过滤器是JavaWeb三大组件之一,其余组件是:Servlet程序、Listener监听器

  1. Filter过滤器是JavaEE规范,也就是一个接口

  1. Filter过滤器的作用是:拦截请求、过滤响应

3.Filter请求和响应

Filter是可以转换请求或响应的标头和内容 (或两者) 的对象。Filter与 web 组件的区别在于, Filter本身通常不会创建响应。相反, Filter提供了可 "附加" 到任何类型的 web 资源的功能。因此, Filter不应依赖于它充当其Filter的 web 资源。这样, 它可以由多种类型的 web 资源组成。

Filter可以执行的主要任务如下所示:

  • 查询请求并采取相应的操作。

  • 阻止请求和响应对通过任何进一步。

  • 修改请求标头和数据。您可以通过提供请求的自定义版本来执行此操作。

  • 修改响应标头和数据。您可以通过提供响应的自定义版本来执行此操作。

  • 与外部资源交互。

Filter的应用包括身份验证、日志记录、图像转换、数据压缩、加密、令牌流、XML 转换等。

您可以将 web 资源配置为按特定顺序按零、一个或多个Filter链进行筛选。此链是在部署包含该组件的 web 应用程序时指定的, 并且在 web 容器加载组件时实例化。

4.filter的实现

编写Filter和编写Servlet类似,都需要实现接口。

编写Filter需要实现Filter接口,我们来看一下Filter接口的主要方法:

Filter
init(FilterConfig): void
doFilter(ServletRequest, ServletResponse, FilterChain) : void
destroy() : void

Filter接口,实现Filter需要实现该接口

  1. init0方法用于初始化Filter

  1. doFilter()作用和service()方法类似,是过滤请求和响应的主要方法。

  1. destroy()用于在Filter对象被销毁前做一些收尾工作。如:释放资源等

FilterConfig
getFilterName() : String
getSenvletContext() : ServletContext
getinitParameter(String) : String
getinitParameterNames() : Enumeration

FilterConfig对象在服务器调用init()方法时传递进来

  1. getFilterName() 获取Filter的名字

  1. getServletContext() 获取ServletContext对象(即application)

  1. getInitParameter() 获取Filter的初始化参数

  1. getlnitParameterNames() 获取所有初始化参数的名字

5.Filter过滤器的生命周期

  1. 构造方法

  1. init初始化方法

  1. doFilter方法(其中有filterChain.doFilter方法)

  1. destroy方法

其中:

①1和2在web工程启动的时候执行(即在创建Filter过滤器)

②第三步,符合拦截路径的请求发送到服务器的时候,自动的执行,若请求不属于拦截路径,则不会执行

③第四步,停止web工程的时候执行(停止web工程,也会销毁Filter过滤器)

6.FilterConfig类

  1. FilterConfig类是Filter过滤器的配置文件类,每次创建Filter的时候,也会创建一个FilterConfig

类,其中包含了Filter配置文件的配置信息

  1. FilterConfig类的作用是获取Filter过滤器的配置文件内容:

⑴获取Filter的名称,即web.xml文件中标签的值:

filterConfig.getFilterName(;

⑵获取web.xml文件中标签的值(写在filter标签中,可写多),如:


username
root

⑶获取ServletContext对象: filterConfig.getServletContext()

7.FilterChain过滤器链

作用: 解决多个过滤器如何一起工作

过滤器Filter_第2张图片

注意:

  1. 上述两个Filter拦截的资源路径相同,代表一定会执行两个Filter过滤器的doFilter方法,但因为手动注释不一定执行其中的chain.doFilter方法

  1. 如果两Flter栏戴资源不同,且栏截资源符合Filter1,不符合Flter2,则会执行Flter1 的doFiter方法,且执行其中的chain.doFiter方法时,不会去执行Filter2的doFiter方法,直接去访问资源,之后执行Filter1的后置代码(在chain.doFilter之后的均是后置代码)

  1. 如果请求的资源不符合过滤器1和2的拦截路径,两个doFilter方法都不执行

  1. 前置代码、chain.doFilter方法、后置代码都在doFilter方法中

8.Filter过滤器的使用

1.Filter过滤器的使用步骤:

  1. 编写一个类实现Filter接口 (导入的包为:javax.servlet.Filter)

  1. 实现三个方法:

  • 实现过滤方法doFilter(),此方法中的:

  • filterChain.doFilter(servletRequest,servletResponse);

  • 只有执行此方法,才可以访问拦截路径中的资源,若未执行此方法则代表拦截

  • 实现init()方法

  • 实现destroy()方法

  1. 到web.xml中配置Filter的拦截路径

2.Filter过滤器的工作流程:

过滤器Filter_第3张图片

3.案例:在web目录下有一个Admin目录,此目录下的所有资源都必须用户登录之后才可访问,若没有登录,则跳转到登录页面

分析: 用户登录之后会把登录信息保存到Session域中,所以检查用户是否登录,可以判断Session 中是否包含用户的登录信息即可

代码演示:创建MyFilter程序

package com.zhao.filter;

import com.zhao.bean.User;

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

@WebFilter("/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter...init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter...执行过滤");
        //先把ServletRequest、ServletResponse、转换为HttSpervletRequest和HttServletResponse
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse) servletResponse;


        //1.获取请求的资源名称
        String path = request.getServletPath();
        System.out.println(path);

        //2.从session中获取登录的用户信息----session中有用户信息表示已登录,没有用户信息表示未登录
        HttpSession session=request.getSession();
        User user=(User) session.getAttribute("user");


        //index.jsp、login.jsp、error.jsp、register.jsp、login、register这些页面或地址请求放行
        if(path.equals("/index.jsp") || path.equals("/login.jsp") || path.equals("/register.jsp") || path.equals("/error.jsp") ||
                path.equals("/login") || path.equals("/register")){
            filterChain.doFilter(servletRequest,servletResponse);
        }else if (user!=null){
            //session中有用户信息表示已登录,没有用户信息表示未登录,已登录则放行
            filterChain.doFilter(servletRequest,servletResponse);//放行
        }else {
            response.sendRedirect("login.jsp");
        }

    }

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

9.展示页面效果

代码运行之后进入浏览器页面,修改的地址为zhuye.jsp

过滤器Filter_第4张图片

修改的地址为zhuye.jsp,点击登录,然后被拦截,进入主页页面。

过滤器Filter_第5张图片

在控制台可以看出被拦截

过滤器Filter_第6张图片

你可能感兴趣的:(servlet)