Servlet——过滤器

来源:互联网 发布:薛之谦男装店淘宝地址 编辑:程序博客网 时间:2024/05/29 03:09

Servlet过滤器

什么是过滤器

过滤器是一个程序,它先于与之相关的Servlet页面运行在服务器上,但它并不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。它主要用于对HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理。过滤器可以附加到一个或多个Servlet、JSP页面或者是HTML静态页面上,然后检查进入这些资源的请求信息。它对这些请求进行拦截,从而实现一些特殊的功能,比如可以实现权限访问控制,过滤敏感词汇,设置统一字符集等功能。

  • 过滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求和响应
  • 在请求到达Servlet或者JSP之前,过滤器截获请求
  • 在响应送给客户端之前,过滤器截获响应
  • 多个过滤器可以形成一个过滤器链,过滤器链中不同过滤器的先后顺序由部署文件web.xml中过滤器映射<filter-mapping>的顺序决定

Servlet过滤器的基本原理

在Servlet作为过滤器使用时,它可以对客户的请求进行处理。处理完成之后,它会交给下一个过滤器处理,这样,客户的请求在过滤器链中逐个处理,直到请求发送到目标为止。例如,我们访问用户管理系统的某个页面,服务器在进行处理时需要做两项工作:①判断客户端的会话是否有效然后检查权限;②对提交的数据进行统一编码。这两项工作可以在由两个过滤器组成的过滤器链中进行处理。当过滤器处理成功后,再把提交的数据发送到最终目标。

可以看一下过滤器链在整个Web应用中的位置:

过滤器

Servlet过滤器开发以及部署步骤

过滤器的开发

开发Servlet过滤器的步骤为:
1.编写实现Filter接口的Servlet类。
2.在web.xml中配置Filter

开发一个过滤器需要实现Filter接口,Filter接口定义了以下方法:

destory()由web容器调用,销毁此Filter
init(FilterConfig filterConfig)由Web容器调用,初始化此Filter
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)具体处理过滤的代码

一个过滤器的代码类似如下,其中最重要的是在doFilter()方法中的实现自己对request和response的过滤:

public class MyFilter implements Filter {    @Override    public void destroy() {        //销毁代码    }    @Override    public void doFilter(ServletRequest arg0, ServletResponse arg1,            FilterChain chain) throws IOException, ServletException {        //具体的过滤细节    }    @Override    public void init(FilterConfig arg0) throws ServletException {        //初始化代码    }}

过滤器的部署

过滤器的部署细节与Servlet很相似,Servlet是要配置<servlet><servlet-mapping>,而过滤器是要配置<filter><filter-mapping>

配置如下所示,假设我的Filter放在com.gavin.filter包下:

<filter>    <filter-name>FilterName</filter-name>    <filter-class>com.gavin.filter.FilterName</filter-class>  </filter>

配置mapping的方法有很多种,根据映射到Servlet或者JSP的不同,相应的配置也不相同:

(1)映射到一个或多个Servlet

filter-mapping>    <filter-name>FilterName</filter-name>    <servlet-name>ServletName1</servlet-name></filter-mapping><filter-mapping>    <filter-name>FilterName</filter-name>    <servlet-name>ServletName2</servlet-name></filter-mapping>

(2)映射到一个或多个JSP:

<filter-mapping>    <filter-name>FilterName</filter-name>    <url-pattern>/path/FileName.jsp</url-pattern></filter-mapping>

(3)映射到任意的URL:

<filter-mapping>    <filter-name>FilterName</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>

在实际应用中,要特别注意过滤器链的执行顺序问题,web服务器根据过滤器在web.xml文件中的注册顺序,决定先调用哪个过滤器,当第一个过滤器的doFilter方法被调用时,web服务器会创建一个代表过滤器链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

过滤器的简单应用

在【Servlet(2)之简单应用】中,我们介绍了使用Session防止用户非法登录到某个页面,采用的是在登录页面将用户信息放入Session,在需要防止非法登录的页面取出登录的信息,如果没有登录用户的信息,则为非法登录,然后将其强制跳转到登录页面。

那么就出现了一个问题,如果我们的Web应用有很多个需要防止非法登录的页面怎么办?一个个都这样处理肯定非常麻烦。这时候,过滤器的应用就让这个问题变得非常简单。

首先,我们编写CheckUserFilter,它的doFilter()代码如下:

public void doFilter(ServletRequest arg0, ServletResponse arg1,        FilterChain chain) throws IOException, ServletException {    HttpServletRequest request = (HttpServletRequest)arg0;    HttpServletResponse response = (HttpServletResponse)arg1;    User login_user = (User)request.getSession().getAttribute("login-user");    if(login_user == null){        // 说明用户没有登录,让他跳转到错误页面        request.setAttribute("error", "请登录!");        request.getRequestDispatcher("/LoginServlet").forward(request,response);    }else{        // 让其通过        chain.doFilter(request, response);    }}

可以看到,在doFilter中,我们去判断Session中是否有登录用户的信息,如果有,让其通过;如果没有,则强制跳转到登录页面。然后我们对这个Filter进行部署,假设我们的主页面MainFrame,添加用户的页面AddUser和更新用户的页面UpdateUser都需要防止非法登录,则可以让其映射到所有的这些Servlet上,部署如下:

<filter>    <filter-name>CheckUserFilter</filter-name>    <filter-class>com.gavin.filter.CheckUserFilter</filter-class></filter><filter-mapping>    <filter-name>CheckUserFilter</filter-name>    <servlet-name>MainFrame</servlet-name></filter-mapping><filter-mapping>    <filter-name>CheckUserFilter</filter-name>    <servlet-name>AddUser</servlet-name></filter-mapping><filter-mapping>    <filter-name>CheckUserFilter</filter-name>    <servlet-name>UpdateUser</servlet-name></filter-mapping>

实验可得,在没有登录之前去访问MainFrame、AddUser或者UpdateUser,都会提示错误信息,然后跳转到登录页面。


其实过滤器还有更多的知识与细节,比如request、forward、include和error四种过滤器的具体使用方法等。这些知识在这里先不展开,后续用到再补充。

2 0