javax.servlet.Filter详解(二) 转自:http:hi.baidu.comjxnuywfblogitemf3834aee93e2fdf8b2fb95cc.html

    技术2025-09-23  45

    转自:http://hi.baidu.com/jxnuywf/blog/item/f3834aee93e2fdf8b2fb95cc.html

     

    1.5禁用激活器servlet

    在对资源应用过滤器时,可通过指定要应用过滤器的URL模式或servlet名来完成。如果提供servlet名,则此名称必须与web.xml的servlet元素中给出的名称相匹配。如果使用应用到一个serlvet的URL模式,则此模式必须与利用web.xml的元素servlet-mapping指定的模式相匹配。但是,多数服务器使用“激活器servlet”为servlet体统一个缺省的URL:http://host/WebAppPrefix/servlet/ServletName。需要保证用户不利用这个URL访问servlet(这样会绕过过滤器设置)。

    例如,假如利用filter和filter-mapping指示名为SomeFilter的过滤器应用到名为SomeServlet的servlet,则如下:

    <filter>

    <filter-name>SomeFilter</filter-name>

    <filter-class>somePackage.SomeFilterClass</filter-class>

    </filter>

    <!-- ... -->

    <filter-mapping>

    <filter-name>SomeFilter</filter-name>

    <servlet-name>SomeServlet</servlet-name>

    </filter-mapping>

     

    接着,用servlet和servlet-mapping规定URLhttp://host/webAppPrefix/Blah 应该调用SomeSerlvet,如下所示:

    <filter>

    <filter-name>SomeFilter</filter-name>

    <filter-class>somePackage.SomeFilterClass</filter-class>

    </filter>

    <!-- ... -->

    <filter-mapping>

    <filter-name>SomeFilter</filter-name>

    <servlet-name>/Blah</servlet-name>

    </filter-mapping>

     

    现在,在客户机使用URLhttp://host/webAppPrefix/Blah 时就会调用过滤器。过滤器不应用到

    http://host/webAppPrefix/servlet/SomePackage.SomeServletClass

    尽管有关闭激活器的服务器专用方法。但是,可移植最强的方法时重新映射Web应用钟的/servlet模式,这样使所有包含此模式的请求被送到相同的servlet中。为了重新映射此模式,首先应该建立一个简单的servlet,它打印一条错误消息,或重定向用户到顶层页。然后,使用servlet和servlet-mapping元素发送包含/servlet模式的请求到该servlet。程序清单9-1给出了一个简短的例子。

    程序清单9-1 web.xml(重定向缺省servlet URL的摘录)

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <!DOCTYPE web-app PUBLIC

    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

    "http://java.sun.com/dtd/web-app_2_3.dtd">

    <web-app>

    <!-- ... -->

    <servlet>

    <servlet-name>Error</servlet-name>

    <servlet-class>somePackage.ErrorServlet</servlet-class>

    </servlet>

    <!-- ... -->

    <servlet-mapping>

    <servlet-name>Error</servlet-name>

    <url-pattern>/servlet/*</url-pattern>

    </servlet-mapping>

    <!-- ... -->

    </web-app>

     

    2.样例:报告过滤器

    趁热打铁,我们来试验一个简单的过滤器,只要调用相关的servlet或JSP页面,它就打印一条消息到标准输出。为了完成此任务,相应的过滤器必须具有下面的内容:

    1)实现Filter接口的一个类。这个类名为ReportFilter,如程序清单9-2所示。这个类对init和destroy方法提供空体。

    2)在doFilter方法中过滤行为。每当调用与这个过滤器相关的servlet或JSP页面时,doFilter方法就生成一个打印输出,此输出列出请求主机和调用的URL。因为getRequestURL方法位于HttpServletRequest而不是ServletRequest中,所以把ServletRequest对象构造为HttpServletRequest类型。

    3)调用FilterChain的doFilter方法。在打印输出报告后,过滤器调用FilterChain的doFilter方法激活servlet或JSP页面(如果有的话,调用下一个过滤器)

    4)对Web应用主页和显示TodaysSpecialservlet进行注册。首先,filter元素将名称Reporter与类moreservlets.filters.ReportFilter相关联。然后,filter-mapping元素使用/index.jsp的url-pattern将过滤器与主页相关联。最后,filter-mapping元素使用TodaysSpecial的servlet-name将过滤器与TodaysSpecialservlet(名称TodaysSpecial是在servlet元素中声明的)相关联。参见程序清单9-3。

    5)禁用激活器servlet。首先,建立一个RedirectorServlet(见程序清单9-6),它把接收到的所有请求重定向到此Web应用的主页。接着,利用servlet和servlet-mapping元素(参见程序清单9-3)指定所有以http://host/webAppPrefix/servlet/ 开始的URL都应该激活RedirectorServlet。

    给出这些设置后,每当客户机请求此Web应用主页(程序清单9-4)或TodaysSpecialservlet(程序清单9-5)时,都调用此过滤器。

    程序清单9-2 ReportFilter.java

    package moreservlets.filters;

    import java.io.*;

    import javax.servlet.*;

    import javax.servlet.http.*;

    import java.util.*; // For Date class

    /** Simple filter that prints a report on the standard output

    * each time an associated servlet or JSP page is accessed.

    */

    public class ReportFilter implements Filter {

    public void doFilter(ServletRequest request,

    ServletResponse response,

    FilterChain chain)

    throws ServletException, IOException {

    HttpServletRequest req = (HttpServletRequest)request;

    System.out.println(req.getRemoteHost() +

    " tried to access " +

    req.getRequestURL() +

    " on " + new Date() + ".");

    chain.doFilter(request,response);

    }

    public void init(FilterConfig config)

    throws ServletException {

    }

    public void destroy() {}

    }

    最新回复(0)