關鍵字: filter
過濾器Filter也具有生命週期:init()->doFilter()->destroy(),由部署檔案中的filter元素驅動。在servlet2.4中,過濾器同樣可以用於請求指派器,但須在web.xml中聲明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>該元素位於filter-mapping中。
一、大量設定請求編碼
Java代碼
- public class EncodingFilter implements Filter {
-
- private String encoding = null;
-
- public void destroy() {
- encoding = null;
- }
-
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- String encoding = getEncoding();
- if (encoding == null){
- encoding = "gb2312";
- }
- request.setCharacterEncoding(encoding);// 在請求裡設定上指定的編碼
- chain.doFilter(request, response);
- }
-
- public void init(FilterConfig filterConfig) throws ServletException {
- this.encoding = filterConfig.getInitParameter("encoding");
- }
-
- private String getEncoding() {
- return this.encoding;
- }
-
- }
public class EncodingFilter implements Filter { private String encoding = null; public void destroy() { encoding = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String encoding = getEncoding(); if (encoding == null){ encoding = "gb2312"; } request.setCharacterEncoding(encoding);// 在請求裡設定上指定的編碼 chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { this.encoding = filterConfig.getInitParameter("encoding"); } private String getEncoding() { return this.encoding; }}
Xml代碼
- <filter>
- <filter-name>EncodingFilter</filter-name>
- <filter-class>com.logcd.filter.EncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>gb2312</param-value>
- </init-param>
- </filter>
-
- <filter-mapping>
- <filter-name>EncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
<filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.logcd.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>gb2312</param-value> </init-param></filter><filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
二、用filter控制使用者存取權限
Java代碼
- public void doFilter(ServletRequest request,
- ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
-
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
-
- HttpSession session = req.getSession();
- if (session.getAttribute("username") != null) {//登入後才能訪問
- chain.doFilter(request, response);
- } else {
- res.sendRedirect("../failure.jsp");
- }
- }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; HttpSession session = req.getSession(); if (session.getAttribute("username") != null) {//登入後才能訪問 chain.doFilter(request, response); } else { res.sendRedirect("../failure.jsp"); }}
Xml代碼
- <filter>
- <filter-name>SecurityFilter</filter-name>
- <filter-class>com.logcd.filter.SecurityFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>SecurityFilter</filter-name>
- <url-pattern>/admin/*</url-pattern>
- </filter-mapping>
<filter> <filter-name>SecurityFilter</filter-name> <filter-class>com.logcd.filter.SecurityFilter</filter-class></filter><filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/admin/*</url-pattern></filter-mapping>
三、過濾鏈
兩個過濾器,EncodingFilter負責設定編碼,SecurityFilter負責控制許可權,伺服器會按照web.xml中過濾器定義的先後循序組裝成一條鏈,然後一次執行其中的doFilter()方法。執行的順序就如所示,執行第一個過濾器的chain.doFilter()之前的代碼,第二個過濾器的chain.doFilter()之前的代碼,請求的資源,第二個過濾器的chain.doFilter()之後的代碼,第一個過濾器的chain.doFilter()之後的代碼,最後返迴響應。
執行的代碼順序是:
- 執行EncodingFilter.doFilter()中chain.doFilter()之前的部分:request.setCharacterEncoding("gb2312");
- 執行SecurityFilter.doFilter()中chain.doFilter()之前的部分:判斷使用者是否已登入。
- 如果使用者已登入,則訪問請求的資源:/admin/index.jsp。
- 如果使用者未登入,則頁面重新導向到:/failure.jsp。
- 執行SecurityFilter.doFilter()中chain.doFilter()之後的部分:這裡沒有代碼。
- 執行EncodingFilter.doFilter()中chain.doFilter()之後的部分:這裡也沒有代碼。
過濾鏈的好處是,執行過程中任何時候都可以打斷,只要不執行chain.doFilter()就不會再執行後面的過濾器和請求的內容。而在實際使用時,就要特別注意過濾鏈的執行順序問題,像EncodingFilter就一定要放在所有Filter之前,這樣才能確保在使用請求中的資料前設定正確的編碼。