servlet fillter 作用

来源:互联网 发布:软件架构风格 编辑:程序博客网 时间:2024/06/05 07:32
Servlet 过滤器
也许你还不熟悉情况,一个过滤器是一个可以传送请求或修改响应的对象。过滤器并不是servlet,他们并不实际创建一个请求。他们是请求到达一个servlet前的预处理程序,和/或响应离开servlet后的后处理程序。就像你将在后面的例子中看到的,一个过滤器能够:
·在一个servlet被调用前截获该调用
·在一个servlet被调用前检查请求
·修改在实际请求中提供了可定制请求对象的请求头和请求数据
·修改在实际响应中提供了可定制响应对象的响应头和响应数据
·在一个servlet被调用之后截获该调用
    一个过滤器以作用于一个或一组servlet,零个或多个过滤器能过滤一个或多个servlet。一个过滤器需要实现java.servlet.Filter接口,并定义它的三个方法:
1.              void init(FilterConfig config) throws ServletException:在过滤器执行service前被调用,以设置过滤器的配置对象。
2.              void destroy();在过滤器执行service后被调用。
3.              Void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException,ServletException;执行实际的过滤工作。
服务器调用一次init(FilterConfig)以为服务准备过滤器,然后在请求需要使用过滤器的任何时候调用doFilter()。FilterConfig接口检索过滤器名、初始化参数以及活动的servlet上下文。服务器调用destory()以指出过滤器已结束服务。过滤器的生命周期和servelt的生命周期非常相似 ——在Servlet API 2.3 最终发布稿2号 中最近改变的。先前得用setFilterConfig(FilterConfig)方法来设置生命周期。
doFilter()方法中,每个过滤器都接受当前的请求和响应,而FilterChain包含的过滤器则仍然必须被处理。doFilter()方法中,过滤器可以对请求和响应做它想做的一切。(就如我将在后面讨论的那样,通过调用他们的方法收集数据,或者给对象添加新的行为。)过滤器调用
chain.doFilter()将控制权传送给下一个过滤器。当这个调用返回后,过滤器可以在它的doFilter()方法的最后对响应做些其他的工作;例如,它能记录响应的信息。如果过滤器想要终止请求的处理或得对响应的完全控制,则他可以不调用下一个过滤器。
循序渐进
如果想要真正理解过滤器,则应该看它们在实际中的应用。我们将看到的第一个过滤器是简单而有用的,它记录了所有请求的持续时间。在Tomcat 4.0发布中被命名为ExampleFilter。代码如下:
java 代码
  1. import java.io.*;   
  2. import javax.servlet.*;   
  3. import javax.servlet.http.*;   
  4.   
  5. public class TimerFilter implements Filter {   
  6.   
  7. private FilterConfig config = null;   
  8.   
  9. public void init(FilterConfig config) throws ServletException {   
  10.     this.config = config;   
  11. }   
  12.   
  13. public void destroy() {   
  14.      config = null;   
  15. }   
  16.   
  17. public void doFilter(ServletRequest request, ServletResponse response,   
  18.                       FilterChain chain) throws IOException, ServletException {   
  19.     long before = System.currentTimeMillis();   
  20.      chain.doFilter(request, response);   
  21.     long after = System.currentTimeMillis();   
  22.   
  23.      String name = "";   
  24.     if (request instanceof HttpServletRequest) {   
  25.        name = ((HttpServletRequest)request).getRequestURI();   
  26.      }   
  27.      config.getServletContext().log(name + ": " + (after - before) + "ms");   
  28. }   
  29. }   
当服务器调用init()时,过滤器用config变量来保存配置类的引用,这将在后面的doFilter()方法中被使用以更改ServletContext。当调用doFilter()时,过滤器计算请求发出到该请求执行完毕之间的时间。该过滤器很好的演示了请求之前和之后的处理。注意doFilter()方法的参数并不是HTTP对象,因此要调用HTTP专用的getRequestURI()方法时必须将request转化为HttpServletRequest类型。
使用此过滤器,你还必须在web.xml文件中用<filter></filter>标签部署它,见下:
  1. <filter>  
  2.        <filter-name>timerFilterfilter-name>  
  3.        <filter-class>TimerFilterfilter-class>  
  4. /filter>  
这将通知服务器一个叫timerFiter的过滤器是从TimerFiter类实现的。你可以使用确定的URL模式或使用<filter-mapping></filter-mapping>标签命名的servelt 来注册一个过滤器,如:
  1. <filter-mapping>  
  2.     <filter-name>timerFilterfilter-name>  
  3.     <url-pattern>/*url-pattern>  
  4. filter-mapping>  
这种配置使过滤器操作所有对服务器的请求(静态或动态),正是我们需要的计时过滤器。如果你连接一个简单的页面,记录输出可能如下:
2001-05-25 00:14:11 /timer/index.html: 10ms
Tomcat 4.0 beta 5中,你可以在server_root/logs/下找到该记录文件。OpenSymphony成员写的clickstream过滤器。这个过滤器跟踪用户请求(比如:点击)和请求队列(比如:点击流)以向网络管理员显示谁在她的网站上以及每个用户正在访问那个页面。这是个使用LGPL的开源库。
clickstream包中你将发现一个捕获请求信息的ClickstreamFilter类,一个像操作结构一样的Clickstream类以保存数据,以及一个保存会话和上下文事件的ClickstreamLogger类以将所有东西组合在一起。还有个BotChecker类用来确定客户端是否是一个机器人(简单的逻辑,像“他们是否是从robots.txt来的请求?”)。该包中提供了一个clickstreams.jsp摘要页面和一个viewstream.jsp详细页面来查看数据。
ClickstreamFilter类。所有的这些例子都做了些轻微的修改以格式化并修改了些可移植性问题,这我将在后面将到。
  1. import java.util.*;   
  2. import javax.servlet.*;   
  3. import javax.servlet.http.*;   
  4.   
  5. public class ClickstreamLogger implements ServletContextListener,   
  6.                                            HttpSessionListener {   
  7. Map clickstreams = new HashMap();   
  8.   
  9. public ClickstreamLogger() { }   
  10.   
  11. public void contextInitialized(ServletContextEvent sce) {   
  12.      sce.getServletContext().setAttribute("clickstreams", clickstreams);   
  13. }   
  14.   
  15. public void contextDestroyed(ServletContextEvent sce) {   
  16.      sce.getServletContext().setAttribute("clickstreams"null);   
  17. }   
  18.   
  19. public void sessionCreated(HttpSessionEvent hse) {   
  20.      HttpSession session = hse.getSession();   
  21.      Clickstream clickstream = new Clickstream();   
  22.      session.setAttribute("clickstream", clickstream);   
  23.      clickstreams.put(session.getId(), clickstream);   
  24. }   
  25.   
  26. public void sessionDestroyed(HttpSessionEvent hse) {   
  27.      HttpSession session = hse.getSession();   
  28.      Clickstream stream = (Clickstream)session.getAttribute("clickstream");   
  29.      clickstreams.remove(session.getId());   
  30. }   
  31. }   
    logger(记录器)获取应用事件并将使用他们将所有东西帮定在一起。当context创建中,logger在context中放置了一个共享的流map。这使得clickstream.jsp页面知道当前活动的是哪个流。而在context销毁中,logger则移除此map。当一个新访问者创建一个新的会话时,logger将一个新的Clickstream实例放入此会话中并将此Clickstream加入到中心流map中。在会话销毁时,由logger从中心map中移除这个流。
web.xml部署描述片段将所有东西写在一块:
0 0
原创粉丝点击