Java Web 之过滤器

前言

学一学Java Web 三大组件之一过滤器。

Filter过滤器

Filter过滤器用来对Web资源进行一些拦截。比如实现url的权限控制访问、字符编码、过滤敏感词汇等等。

开发使用

实现一个Filter很简单,只需要两步:
1、写一个类实现Filter接口,并重写其doFilter方法;
2、注册一个过滤器,在web.xml文件中使用元素配置filter;
以实现一个字符编码为utf-8为例
实现Filter的接口代码如下:

package com.guigu.servlet;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CharacterEncodingFilter implements Filter{

    @Override
    public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        
        System.out.println("CharacterEncodingFilter执行前");
        chain.doFilter(request, response);//让请求过滤后继续执行
        System.out.println("CharacterEncodingFilter执行后");
        
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");
        
    }

}

web.xml注册一个Filter

  
    CharacterEncodingFilter
    com.guigu.servlet.CharacterEncodingFilter
  
  
    CharacterEncodingFilter
    
    /hello1
  

当访问到hello1这个页面时,Filter就会执行。
为了完善整个过程,再编写一个Servlet2类

package com.guigu.servlet;

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

public class Servlet2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("中国");
    }
}

再给servlet配置上可访问的URI映射地址。

    
        Servlet2
        com.guigu.servlet.Servlet2
    
    
        Servlet2
        /hello1
    

创建一个form表单,访问该servlet。

用户名:
密码:

当访问 http://localhost:8080/Servlet/hello1 时,url 映射到Servlet2类,向浏览器输出"中国"字符串。同时在web.xml配置了Filter会对hello1进行utf-8编码。

image.png
image.png

Filter 生命周期

阶段如下:
1、执行构造器方法;
2、执行init()初始化方法;
3、执行doFilter()方法;
4、执行destroy()销毁方法;

  • 创建构造器方法
    服务器启动项目加载,创建filter对象,执行构造器方法(只执行一次)
  • 创建 init() 方法
    服务器启动项目加载,创建filter对象,执行init方法(只执行一次)
  • 运行(过滤拦截)doFilter() 方法
    用户访问被拦截目标资源时,执行doFilter方法,需要"放行"的时候记得在此调用FilterChain的doFilter()方法,让程序继续往下访问资源。
  • 销毁 destroy() 方法
    服务器关闭项目卸载时,销毁filter对象,执行方法(只执行一次)

FilterConfig 对象

FilterConfig 是Filter过滤器配置文件的类。
主要操作web.xml文件

    
        CharacterEncodingFilter
        com.guigu.servlet.CharacterEncodingFilter

        
            username
            cseroad
        

    
    
        CharacterEncodingFilter
        
        /hello1
    

如:
getInitParameter() 表示获取配置中某参数值;
getServletContext() 表示获取ServletContext对象;

public void init(FilterConfig filterConfig) throws ServletException {
    // filterConfig 类获取名称
    System.out.println("CharacterEncodingFilter初始化init");
    System.out.println("filter-name的值为:" + filterConfig.getInitParameter("username"));
    System.out.println("filter-name的值为:" + filterConfig.getServletContext());
}

FilterChain 对象

当一个filter收到请求的时候,调用chain.doFilter才可以访问下一个匹配的filter,若当前的filter是最后一个filter,调用chain.doFilter才能访问目标资源。
当存在多个filter的时候,多个过滤器filter的先后顺序为:web.xml中的filter-mapping元素的顺序决定了web容器过滤器的先后顺序。

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter 执行前");
        chain.doFilter(request, response);//让请求过滤后继续执行
        System.out.println("CharacterEncodingFilter执行后");

    }

Filter拦截路径

再补充一下web.xml中url-pattern的匹配规则:

  • 精确匹配
/index.jsp

精确匹配 http://ip:port/web/index.jsp

  • 目录匹配
/admin/*

匹配 http://ip:port/web/admin/*

  • 后缀名匹配
*.action

匹配请求以action结尾的地址

思维脑图

image.png

参考资料

https://www.bilibili.com/video/BV1Y7411K7zz?p=296

你可能感兴趣的:(Java Web 之过滤器)