Servlet过滤器
        过滤器Filter)是从servlet 2.3规范开始新增的功能,它也是由servlet容器管理的一个对象,其结构与普通的servlet类似,虽然结构类似,但二者的功能是完全不同的。可以简单的将过滤器理解为在源数据与目的数据之间起过滤功能的中间组件。利用Filter的特点可以实现很多有实际意义的功能,如权限控制、日志记录、 图像转换、 数据压缩等。
        之所以说Filter与Servlet结构类似,是因为其也有用于初始化的init方法、用于销毁的destroy方法等,值得注意的一点是Servlet的init方法是在Servlet第一次被访问的时候执行,而Filter的init方法是在容器启动的时候就执行了。此外,其也有与Servlet的service方法类似的执行业务逻辑的方法doFilter。doFilter方法除常规的ServletRequest和ServletResponse参数外,还有一个FilterChain参数对象,FilterChain也提供了一个doFilter方法,可以根据业务需要决定是否调用该方法,调用该方法后servlet容器就会将请求和响应转化给下一个组件进行处理,下一个组件有可能是一个Servlet,也有可能是一个Filter或者其他的Web组件。

过滤器的创建
新建一个类继并实现javax.servlet.Filter接口。简单创建一个过滤器如下,为方便控制台观察,加上几条简单的输出语句:
package org.devsong.filter;

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;

/**
 * Servlet Filter implementation class FilterTest
 */
public class FilterTest implements Filter {

    /**
     * Default constructor. 
     */
    public FilterTest() {
        System.out.println("------ filter constructor ------");
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        System.out.println("------ filter destroy ------");
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("------do filter: start ------");
        chain.doFilter(request, response);
        System.out.println("------do filter: end ------");
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        System.out.println("------ filter init ------");
        String value = fConfig.getInitParameter("data");       //从部署描述符中获取初始化参数
        System.out.println("------ init param: " + value + "------");
    }

}

为方便观察,新建一个Servlet,同样添加简单的输出语句
package org.devsong.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ServletTest
 */
public class ServletTest extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ServletTest() {
        super();
    }

    @Override
    public void init() throws ServletException {
        System.out.println(" ===== servlet : init =====");
        super.init();
    }
    
    @Override
    protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
        System.out.println(" ===== servlet : service =====");
    }
    
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println(" ===== servlet : doGet/doPost =====");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

Filter的注册与Servlet类似,如下是它们各自的注册详情
<servlet>
    <servlet-name>servletTest</servlet-name>
    <servlet-class>org.devsong.servlet.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>servletTest</servlet-name>
    <url-pattern>/servletTest</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>filterTest</filter-name>
    <filter-class>org.devsong.filter.FilterTest</filter-class>
    <init-param>      <!-- 初始化参数注册 -->
        <param-name>data</param-name>         
        <param-value>hello filter!</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>filterTest</filter-name>
    <url-pattern>/servletTest</url-pattern> <!-- 只对/servletTest的访问进行过滤 -->
</filter-mapping>

可以看到之中配置了一个初始化参数data,可以在filter初始化的时候利用FilterConfig对象进行加载:filterConfig是一个用于初始化过滤器信息的接口。其有一个比较重要的方法:getInitParaneter(), 用于从部署描述符中获取初始化参数。

启动Tomcat
以上配置都完成后就可以启动Tomcat了。启动后可以立即在控制台看到以下打印信息:
------ filter constructor ------
------ filter init ------
------ init param: hello filter!------
此处并未打印出servletTest的相关信息,可见filter的构造方法和初始化方法在容器启动时就执行了,而servlet的初始化在第一次被访问的时候执行。如下,打开浏览器访问一下servletTest,可以看到打印出了servlet的init信息,并且也打印出了filter的工作特点,在一个访问前、后进行过滤。
====== servlet : init ======
------do filter: start ------
====== servlet : service ======
------do filter: end ------

多个Filter的执行顺序
Filter执行顺序由部署描述符中的注册顺序决定,先注册的先执行。如新建一个FilterNew并在web.xml中注册于FilterTest下方,然后访问ServletTest,可以在控制台看到以下信息:
====== servlet : init ======
------do filter: start ------
------do filter_new: start------
====== servlet : service ======
------do filter_new: end------
------do filter: end ------
It's
欢迎访问本站,欢迎留言、分享、点赞。愿您阅读愉快!
*转载请注明出处,严禁非法转载。
https://www.devsong.org
QQ留言 邮箱留言
头像
引用:
取消回复
提交
涂鸦
涂鸦
热门