JBuilder2005Servlet開發之過濾器
過濾器可以在請求到達JSP或Servlet之前或響應返回客戶端之前添加一些額外的操作。如果有多個JSP頁面和Servlet都需要進行一個相同或相似的操作,我們可以把這個操作抽取到一個Servlet過濾器中,并通過匹配路徑截獲感興趣JSP或Servlet。
我們舉幾個典型的過濾器應用的例子,讀者可以推而廣之:
·編碼轉換
亂碼問題困擾了不少的Web應用程序開發者,這是因為基于Java的Web應用程序可能運行于不同的Web應用程序器、操作系統平臺或硬件服務器上,不同的環境有自己默認的編碼類型,在數據的轉換過程中不同的默認編碼是亂碼問題的始作俑者,所以在開發JSP時常常需要將數據進行編碼轉換。我們可以創建一個Servlet過濾器在請求進入服務程序前都進行編碼轉換。
·添加統一的標題或腳注
有些網頁需要添加統一的標題頭或腳注,可以通過Servlet過濾器在響應返回到客戶端前給網頁添加上統一的標題和腳注。
·進行安全的控制
登錄系統后,一般都會將用戶信息對象放入到session中,可以通過Servlet過濾器在請求進入JSP或Servlet前判斷session中是否有用戶信息對象,如果有,則說明用戶已經登錄,如果沒有,則說明用戶還沒有登錄,將請求重定向到登錄頁面。
本節所提供的Servlet過濾器就是為了實現安全控制,下面我們就來開發這個Servlet。
1.打開創建Servlet過濾器的向導。
通過File->New...->Web->雙擊Filter Servlet圖標啟動創建Servlet過濾器的向導,如下圖所示:
和創建標準的Servlet相似,在這步里指定過濾器的類名和包名。在Class name中輸入LoginCheckFilter,包名依就為bookstore.servlet。按Next到下一步。
2.指定過濾器的路徑匹配模式
·Name:logincheckfilter,指定過濾器的名字
·URL pattern:/*,指定過濾器路徑匹配模式,這里我們使過濾器對所有的請求都進行過濾。
按Finish創建此過濾器。
打開向導創建的LoginCheckFilter.java文件,并錄入粗體所示的代碼,如下所示:
代碼清單 4 LoginCheckFilter.java代碼
由于login.jsp是用戶登錄頁面,而switch.jsp是用戶登錄處理頁面,在訪問這兩個頁面時用戶信息對象都還沒有產生,所以應該將這兩個頁面排除在過濾器檢驗規則這外。我們通過判斷請求路徑獲知是否是login.jsp和switch.jsp,如第18'19行所示。
如果不是這兩個頁面,則都必須進行檢驗,判斷頁面的session對象中是否包含以ses_userBean命名的對象(第20行)。如果沒有包含以ses_userBean命名的對象,重定向到登錄頁面(第29行),否則將請求傳給請求的目標程序(第26行)。
打開web.xml,你將看到有關LoginCheckFilter過濾器的部署描述配置信息,如下粗體所示:
代碼清單 5 過濾器的部署描述配置信息
<filter-name>配置過濾器的名字和實現類,而<filter-mapping>配置過濾器的路徑匹配模式。
我們舉幾個典型的過濾器應用的例子,讀者可以推而廣之:
·編碼轉換
亂碼問題困擾了不少的Web應用程序開發者,這是因為基于Java的Web應用程序可能運行于不同的Web應用程序器、操作系統平臺或硬件服務器上,不同的環境有自己默認的編碼類型,在數據的轉換過程中不同的默認編碼是亂碼問題的始作俑者,所以在開發JSP時常常需要將數據進行編碼轉換。我們可以創建一個Servlet過濾器在請求進入服務程序前都進行編碼轉換。
·添加統一的標題或腳注
有些網頁需要添加統一的標題頭或腳注,可以通過Servlet過濾器在響應返回到客戶端前給網頁添加上統一的標題和腳注。
·進行安全的控制
登錄系統后,一般都會將用戶信息對象放入到session中,可以通過Servlet過濾器在請求進入JSP或Servlet前判斷session中是否有用戶信息對象,如果有,則說明用戶已經登錄,如果沒有,則說明用戶還沒有登錄,將請求重定向到登錄頁面。
本節所提供的Servlet過濾器就是為了實現安全控制,下面我們就來開發這個Servlet。
1.打開創建Servlet過濾器的向導。
通過File->New...->Web->雙擊Filter Servlet圖標啟動創建Servlet過濾器的向導,如下圖所示:
![]() 圖 7 指定Servlet過濾器的名字 |
和創建標準的Servlet相似,在這步里指定過濾器的類名和包名。在Class name中輸入LoginCheckFilter,包名依就為bookstore.servlet。按Next到下一步。
2.指定過濾器的路徑匹配模式
![]() 圖 8 指定過濾器的匹配路徑模式 |
·Name:logincheckfilter,指定過濾器的名字
·URL pattern:/*,指定過濾器路徑匹配模式,這里我們使過濾器對所有的請求都進行過濾。
按Finish創建此過濾器。
打開向導創建的LoginCheckFilter.java文件,并錄入粗體所示的代碼,如下所示:
代碼清單 4 LoginCheckFilter.java代碼
| 1. package bookstore.servlet; 2. … 3. public class LoginCheckFilter 4. extends HttpServlet implements Filter 5. { 6. … 7. public void doFilter(ServletRequest request, ServletResponse response 8. , FilterChain filterChain) 9. { 10. try 11. { 12. //進行請求和響應的類型轉換 13. HttpServletRequest httpRequest = (HttpServletRequest) request; 14. HttpServletResponse httpResponse = (HttpServletResponse) response; 15. 16. boolean isValid = true; 17. String uriStr = httpRequest.getRequestURI().toUpperCase(); 18. if (uriStr.indexOf("LOGIN.JSP") == -1 && 19. uriStr.indexOf("SWITCH.JSP") == -1 && 20. httpRequest.getSession().getAttribute("ses_userBean") == null) 21. { 22. isValid = false; 23. } 24. if (isValid) 25. { 26. filterChain.doFilter(request, response); 27. } else 28. { 29. httpResponse.sendRedirect("/webModule/login.jsp"); 30. } 31. 32. } catch (ServletException sx) 33. { 34. filterConfig.getServletContext().log(sx.getMessage()); 35. } catch (IOException iox) 36. { 37. filterConfig.getServletContext().log(iox.getMessage()); 38. } 39. } 40. … 41. } |
由于login.jsp是用戶登錄頁面,而switch.jsp是用戶登錄處理頁面,在訪問這兩個頁面時用戶信息對象都還沒有產生,所以應該將這兩個頁面排除在過濾器檢驗規則這外。我們通過判斷請求路徑獲知是否是login.jsp和switch.jsp,如第18'19行所示。
如果不是這兩個頁面,則都必須進行檢驗,判斷頁面的session對象中是否包含以ses_userBean命名的對象(第20行)。如果沒有包含以ses_userBean命名的對象,重定向到登錄頁面(第29行),否則將請求傳給請求的目標程序(第26行)。
打開web.xml,你將看到有關LoginCheckFilter過濾器的部署描述配置信息,如下粗體所示:
代碼清單 5 過濾器的部署描述配置信息
| 1. <web-app> 2. <display-name>webModule</display-name> 3. <filter> 4. <filter-name>logincheckfilter</filter-name> 5. <filter-class>bookstore.servlet.LoginCheckFilter</filter-class> 6. </filter> 7. <filter-mapping> 8. <filter-name>logincheckfilter</filter-name> 9. <url-pattern>/*</url-pattern> 10. </filter-mapping> 11. … 12. </web-app> |
<filter-name>配置過濾器的名字和實現類,而<filter-mapping>配置過濾器的路徑匹配模式。

