filter的做用 二

這注冊了ClickstreamFilter並設置其處理*.jsp和*.html來的請求。這也將ClickstreamLogger註冊爲一個監聽器以在應用事件發生時接受他們。
   兩個JSP頁面從會話中取clickstream數據和context對象並使用HTML界面來顯示當前狀態。下面的clickstream.jsp文件顯示了個大概:
js 代碼
  1. <%@ page import="java.util.*" %>   
  2. <%@ page import="Clickstream" %>   
  3. <%   
  4. Map clickstreams = (Map)application.getAttribute("clickstreams");   
  5. String showbots = "false";   
  6. if (request.getParameter("showbots") != null) {   
  7.   if (request.getParameter("showbots").equals("true"))   
  8.      showbots = "true";   
  9.   else if (request.getParameter("showbots").equals("both"))   
  10.      showbots = "both";   
  11. }   
  12. %>   
  13. <font face="Verdana" size="-1">   
  14. <h1>All Clickstreams</h1>   
  15. <a href="clickstreams.jsp?showbots=false">No Bots</a> |   
  16. <a href="clickstreams.jsp?showbots=true">All Bots</a> |   
  17. <a href="clickstreams.jsp?showbots=both">Both</a> <p>   
  18. <% if (clickstreams.keySet().size() == 0) { %>   
  19.          No clickstreams in progress   
  20. <% } %>   
  21. <%   
  22. Iterator it = clickstreams.keySet().iterator();   
  23. int count = 0;   
  24. while (it.hasNext()) {   
  25.    String key = (String)it.next();   
  26.    Clickstream stream = (Clickstream)clickstreams.get(key);   
  27.   if (showbots.equals("false") && stream.isBot()) {   
  28.     continue;   
  29.    }else if (showbots.equals("true") && !stream.isBot()) {   
  30.     continue;   
  31.    }   
  32.    count++;   
  33.   try {   
  34. %>   
  35.   
  36. <%= count %>.   
  37. <a href="viewstream.jsp?sid=<%= key %>"><b>   
  38. <%= (stream.getHostname() != null && !stream.getHostname().equals("") ?   
  39.       stream.getHostname() : "Stream") %>   
  40. </b></a> <font size="-1">[<%= stream.getStream().size() %> reqs]</font><br>   
  41.   
  42. <%   
  43.    }catch (Exception e) {   
  44. %>   
  45.    An error occurred - <%= e %><br>   
  46. <%   
  47.    }   
  48. }   
  49. %>  

WEB-INF/classes下,將JSP文件放到Web應用路徑下,按幫助修改web.xml文件。爲防止在這些工做前的爭論,你能夠從這個包很容易從OpenSymphony下載並安裝。將Java文件編譯並放在html

http://www.javaworld.com/jw-06-2001/Filters/clickstream.war處找到打好包的WAR文件,注意:要把jdk目錄下的包rt.jar解壓,並拷貝java包到classes下,否則會報沒法編譯的錯誤,而且還要修改jsp頁面中對class的引用(改變一下class的目錄,不要直接放在classes下)。
爲能讓此過濾器能在 Tomcat 4.0 beta 5下工做,我發現我不得不作一些輕微的改動。我作的改動顯示了一些在servlet和過濾器的可移植性中一般容易犯的錯誤,因此我將他們列在下面:
·我不得不將在 JSP中添加一個額外的導入語句:。在Java中你並不須要導入在同一包下的類,而在服務器上JSP被編譯到默認包中,你並不須要這句導入行。但在像Tomcat這樣的服務器上,JSP被編譯到一個自定義的包中,你不得不明確地從默認包中導入類。
·我不得不將 <listener></listener> 元素移動到web.xml文件中的<filter></filter>和<filter-mapping></filter-mapping>元素以後,就像部署描述DTD要求的那樣。並非全部服務器對元素都要求固定的順序。但Tomcat必需要。
·我不得不將 web.xml中的映射由/*.html和/*.jsp改爲正確的*.html和*.jsp。一些服務器會忽略開頭的/,但Tomcat強硬的規定開頭不能有/。
·最後,我得將 ClickstreamFilter類升級到最新的生命週期API,將setFilterConfig()改爲新的init()和destory()方法。
可下載的 WAR文件已經包含了這些修改並能經過服務器在包外運行,雖然我並無普遍的進行測試。
壓縮響應

第三個過濾器是自動壓縮響應輸出流,以提升帶寬利用率並提供一個很好的包裝響應對象的示例。這個過濾器是由來自SUN的Amy Roh編寫的,他爲Tomcat 4.0 的「examples」Web程序作出過貢獻。你將從webapps/examples/WEB-INF/classes/compressionFilters下找到原始代碼。這裏的例子代碼以及WAR下的都已經爲了更清晰和更簡單而編輯過了。java

CompressionFilter類的策略是檢查請求頭以斷定客戶端是否支持壓縮,若是支持,則將響應對象用自定義的響應來打包,它的getOutputStream()和getWriter()方法已經被定義爲能夠利用壓縮過的輸出流。使用過濾器容許如此簡單而有效的解決問題。
咱們將從 init()開始看代碼:
  1. public void init(FilterConfig filterConfig) {   
  2.     config = filterConfig;   
  3.     compressionThreshold = 0;   
  4.    if (filterConfig != null) {   
  5.       String str = filterConfig.getInitParameter("compressionThreshold");   
  6.      if (str != null) {   
  7.         compressionThreshold = Integer.parseInt(str);   
  8.       }   
  9.      else {   
  10.         compressionThreshold = 0;   
  11.       }   
  12.     }   
  13. }  
注意在檢索請求頭前必須把 request轉化爲HttpServletRequest,就想在第一個例子裏那樣。過濾器使用wrapper類CompressResponseWrapper,一個從
HttpServletResponseWrapper類繼承下來的自定義類。這個wrapper的代碼相對比較簡單:
  1. public class CompressionResponseWrapper extends HttpServletResponseWrapper {   
  2.   
  3. protected ServletOutputStream stream = null;   
  4. protected PrintWriter writer = null;   
  5. protected int threshold = 0;   
  6. protected HttpServletResponse origResponse = null;   
  7.   
  8. public CompressionResponseWrapper(HttpServletResponse response) {   
  9.     super(response);   
  10.      origResponse = response;   
  11. }   
  12.   
  13. public void setCompressionThreshold(int threshold) {   
  14.     this.threshold = threshold;   
  15. }   
  16.   
  17. public ServletOutputStream createOutputStream() throws IOException {   
  18.     return (new CompressionResponseStream(origResponse));   
  19. }   
  20.   
  21. public ServletOutputStream getOutputStream() throws IOException {   
  22.     if (writer != null) {   
  23.       throw new IllegalStateException("getWriter() has already been " +   
  24.                                       "called for this response");   
  25.      }   
  26.   
  27.     if (stream == null) {   
  28.        stream = createOutputStream();   
  29.      }   
  30.      ((CompressionResponseStream) stream).setCommit(true);   
  31.      ((CompressionResponseStream) stream).setBuffer(threshold);   
  32.     return stream;   
  33. }   
  34.   
  35. public PrintWriter getWriter() throws IOException {   
  36.     if (writer != null) {   
  37.       return writer;   
  38.      }   
  39.   
  40.     if (stream != null) {   
  41.       throw new IllegalStateException("getOutputStream() has already " +   
  42.                                       "been called for this response");   
  43.      }   
  44.   
  45.      stream = createOutputStream();   
  46.      ((CompressionResponseStream) stream).setCommit(true);   
  47.      ((CompressionResponseStream) stream).setBuffer(threshold);   
  48.      writer = new PrintWriter(stream);   
  49.     return writer;   
  50. }   
  51. }   
全部調用 getOutputStream() 或者getWriter()都返回一個使用
CompressResponseStream類的對象。CompressionResponseStrteam類沒有顯示在這個例子中,由於它繼承於ServletOutputStream並使用java.util.zip.GZIPOutputStream類來壓縮流。
Tomcat的」examples」Web程序中已經預先配置了這個壓縮過濾器並加載了一個示例servlet。示例servlet響應/CompressionTestURL(肯定先前的路徑是/examples)。使用我製做的有用的 WAR文件,你能夠用/servlet/compressionTest(再次提醒,別忘了適當的前導路徑)訪問此測試servlet。你可使用以下的web.xml片斷來配置這個測試:
<filter></filter>
xml 代碼
  1. <filter>  
  2.     <filter-name>compressionFilterfilter-name>  
  3.     <filter-class>CompressionFilterfilter-class>  
  4.     <init-param>  
  5.       <param-name>compressionThresholdparam-name>  
  6.       <param-value>10param-value>  
  7.     init-param>  
  8. filter>  
  9.   
  10. <filter-mapping>  
  11.     <filter-name>compressionFilterfilter-name>  
  12.     <servlet-name>compressionTestservlet-name>  
  13. filter-mapping>  
  14.   
  15. <servlet>  
  16.   <servlet-name>  
  17.      compressionTest   
  18.   servlet-name>  
  19.   <servlet-class>  
  20.      CompressionTestServlet   
  21.   servlet-class>  
  22. servlet>  
CompressionTestServlet(這裏沒有顯示)輸出壓縮是否可用,若是可用,則輸出壓縮響應成功!
相關文章
相關標籤/搜索