Servlet过滤器
4967字,阅读需时17分钟
来自课程
课程/专栏

Servlet过滤器是服务器与客户端请求与响应的中间层组件,主要用于对浏览器的请求进行过滤处理,用于拦截客户端对服务端的请求,并对这些请求进行过滤,或者重定向的不同目标资源。

过滤器以一种组件的方式绑定到WEB应用程序,它采用了“链”的方式进行处理的,可以进行多级过滤。

01.png

若在服务端部署了多个过滤器,请求会依次按照过滤器的顺序进行处理,在第一个过滤器处理请求后,会传递给第二个过滤器进行处理,以此类推,一直传递到最后一个过滤器。

过滤器的对象主要是Filter,它不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理。

Filter是一个接口,编写过滤器对象需要实现Filter接口,在Filter接口定义了三个方法,分别是init()、destory() 和doFilter()。

init()方法

该方法在 Filter 生命周期中仅执行一次,在过滤器被初始化时调用。

destory()方法

该方法在Web容器卸载 Filter 对象之前被调用,在这个方法中,可以释放过滤器使用的资源。

doFilter()方法

对请求进行过滤处理。

例1:创建一个过滤器对象,实现Filter接口的三个方法。

在项目的com.example包下新建filter包,在filter包下建立MyFilter类。

程序清单 MyFilter.java

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        //过滤器初始化代码
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 过滤器处理代码
    }
 
    @Override
    public void destroy() {
        Filter.super.destroy();
        // 过滤器释放资源
    }
}

MyFilter类实现了Filter接口的三个方法。

init()方法主要是初始化过滤器,过滤器的初始化处理代码可以放置到该方法内。参数filterConfig是FilterConfig接口,该接口封装了 Filter 程序在 web.xml 中的所有注册信息,并且提供了一系列获取这些配置信息的方法。

FilterConfig接口的主要方法说明如下:

(1)String getFilterName()

返回在 web.xml 文件中为 Filter 所设置的名称,也就是返回 <filter-name> 元素的设置值。

(1)String getInitParameter(String name)

返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化参数值,如果指定名称的初始化参数不存在,则返回 null。

(3)ServletContext getServletContext()

返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。

doFilter()方法是过滤器处理代码,对请求进行过滤处理的代码可以放置到该方法内;过滤器生命周期结束后,会调用destroy()方法,在方法内可以放置释放过滤器资源的代码。

参数chain是FilterChain接口,该接口的doFilter 方法将激活下一个 Filter的doFilter 方法,能够让过滤器链顺序执行。

要让过滤器生效,需要在web.xml文件内配置过滤器,主要是声明过滤器和配置过滤器映射。

web.xml是tomcat非常重要的配置文件,tomcat启动过程中会读取该配置文件,并加载配置文件内配置的过滤器、监听器、Servlet等Java对象。web.xml在项目webapp目录下的WEB-INF目录。

MyFilter过滤器在web.xml文件内的配置代码如下:

<filter>
  <filter-name>myfilter</filter-name>
  <filter-class>com.example.filter.MyFilter</filter-class>
</filter>
  <filter-mapping>
   <filter-name>myfilter</filter-name>
   <url-pattern>/myfilter</url-pattern>
</filter-mapping>

在web-app标签内添加上面的代码。filter标签用于声明过滤器对象,在这个标签中,必须配置<filter-name>和<filter-class>两个子元素,<filter-name>配置过滤器对象名称,<filter-class>配置过滤器完整类路径。

filter-mapping标签用于配置过滤器的映射路径,<filter-name>是在filter标签内配置的过滤器名称,<url-pattern>配置过滤器应用的URL。

例2:配置一个过滤器,实现网站计数器的功能。

网站计数器的初始化值配置在filter标签内,打开web.xml配置文件,修改filter标签的内容:

<filter>
  <filter-name>myfilter</filter-name>
  <filter-class>com.example.filter.MyFilter</filter-class>
  <init-param>
    <param-name>count</param-name>
    <param-value>1000</param-value>
  </init-param>
</filter>

在filter标签内添加<init-param>子元素,该元素主要用于配置过滤器的初始化参数,参数可以使用FilterConfig接口提供的方法读取。

程序清单 MyFilter.java

public class MyFilter implements Filter {
    // 计数变量
    private int count;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        // 获取在web.xml配置的初始值
        String param = filterConfig.getInitParameter("count");
        count = Integer.valueOf(param);
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 过滤器处理代码
        // 过滤器每执行1次,count自增
        count++;
        HttpServletRequest req = (HttpServletRequest) request;
        ServletContext context = req.getSession().getServletContext();
        context.setAttribute("count", count);
        chain.doFilter(request, response);
    }
 
    @Override
    public void destroy() {
        Filter.super.destroy();
        // 过滤器释放资源
    }
}

MyFilter对象在Tomcat启动后被加载,其init方法被调用,在init方法内初始化计数变量count,当客户端请求与MyFilter过滤器配置的映射URL匹配后,doFilter方法被调用,在doFilter方法内让计数变量count自增,并将计数变量count设置到ServletContext应用环境对象,JSP页面就可以通过application对象的getAttribute方法获取计数变量的值。

在webapp目录下创建filetesample.jsp文件,代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
访客:<%=application.getAttribute("count")%>
</body>
</html>

在浏览器输入filetesample.jsp网页的链接地址,运行结果如下图所示:

02.png

我要评论
全部评论