前言
学一学Java Web 三大组件之一过滤器。
Filter过滤器
Filter过滤器用来对Web资源进行一些拦截。比如实现url的权限控制访问、字符编码、过滤敏感词汇等等。
开发使用
实现一个Filter很简单,只需要两步:
1、写一个类实现Filter接口,并重写其doFilter方法;
2、注册一个过滤器,在web.xml文件中使用
以实现一个字符编码为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编码。
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结尾的地址
思维脑图
参考资料
https://www.bilibili.com/video/BV1Y7411K7zz?p=296