Servlet過濾器基礎及使用場景


Servlet過濾器詳解

  一、過濾器基礎

  1.Servlet過濾器是Servlet的一種特殊用法,主要用來完成一些通用的操作。比如編碼的過濾,判斷用戶的登陸狀態等等。Servlet過濾器的適用場合: 

    A.認證過濾
    B.登錄和審核過濾
    C.圖像轉換過濾
    D.數據壓縮過濾
    E.加密過濾
    F.令牌過濾
    G.資源訪問觸發事件過濾
  2.Servlet過濾器接口的構成:
  所有的Servlet過濾器類都必須實現javax.servlet.Filter接口。這個接口含有3個過濾器類必須實現的方法:
  方法 說明
  init(FilterConfig cfg) 這是Servlet過濾器的初始化方法,性質等同與servlet的init方法。
  doFilter(ServletRequest,ServletResponse,FilterChain) 完成實際的過濾操作,當請求訪問過濾器關聯的URL時,Servlet容器將先調用過濾器的doFilter方法。FilterChain參數用於訪問后續過濾器
  destroy() Servlet容器在銷毀過濾器實例前調用該方法,這個方法中可以釋放Servlet過濾器占用的資源。,性質等同與servlet的destory()方法。
  3.Servlet過濾器的創建步驟:
    A.實現javax.servlet.Filter接口的servlet類
    B.實現init方法,讀取過濾器的初始化函數
    C.實現doFilter方法,完成對請求或過濾的響應
    D.調用FilterChain接口對象的doFilter方法,向后續的過濾器傳遞請求或響應
    F.在web.xml中配置Filter
  二、使用過濾器處理中文問題
  當用用戶登陸頁面輸入帳號時,如果輸入是中文,后台servlet再次輸出這個內容時,可能就會是亂碼,這是因為serlvet中默認是以ISO-8859-1格式編碼的,如果后台有多個Servlet,多個參數,這樣就不合適,這個問題,我們可以通過一個過濾器統一解決,使后台的輸出輸出都支持中文!將ISO-8859-1轉碼為GBK的那段代碼!
  三、使用過濾器認證用戶
  每個過濾器也可以配置初始化參數,可以將不需要過濾的地址配置到這個Filter的配置參數中,過濾時,如果請求地址在配置參數中,則放行,這樣 就避免了在程序中硬編碼。每個Filter中初始化時,都可以得到配置對象,在Filter中配置二個不需要過濾的地址,一個是登陸頁面,一個是執行登陸 認證的servlet;
  四、Servlet監聽器
  類似與Swing界面應用開發,Servlet也可以創建監聽器,以對Servlet容器,或Servlet中以象的事件做出反應。Servlet監聽器主要有以下幾種:
    ServletRequestListener ,ServletRequestAttributeListener,
    HttpSessionActivationListener ,HttpSessionBindingListener ,
    HttpSessionAttributeListener,HttpSessionListener,
    ServletContextListener等等。
  這些監聽器主要用來監聽session,request,application這三個對象里存取數據的變化。

 

   五、五個有用的過濾器

  1、使瀏覽器不緩存頁面的過濾器    

 

import javax.servlet.*;    
import javax.servlet.http.HttpServletResponse;    
import java.io.IOException;    
   
/** 
* 用於的使 Browser 不緩存頁面的過濾器 
*/   
public class ForceNoCacheFilter implements Filter {    
   
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException    
{    
    ((HttpServletResponse) response).setHeader("Cache-Control","no-cache");    
    ((HttpServletResponse) response).setHeader("Pragma","no-cache");    
    ((HttpServletResponse) response).setDateHeader ("Expires", -1);    
    filterChain.doFilter(request, response);    
}    
   
public void destroy()    
{    
}    
   
     public void init(FilterConfig filterConfig) throws ServletException    
{    
}    
}   

 

  2、檢測用戶是否登陸的過濾器   

import javax.servlet.*;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
import javax.servlet.http.HttpSession;    
import java.util.List;    
import java.util.ArrayList;    
import java.util.StringTokenizer;    
import java.io.IOException;    
   
/** 
* 用於檢測用戶是否登陸的過濾器,如果未登錄,則重定向到指的登錄頁面 


* 配置參數 


* checkSessionKey 需檢查的在 Session 中保存的關鍵字 

* redirectURL 如果用戶未登錄,則重定向到指定的頁面,URL不包括 ContextPath 

* notCheckURLList 不做檢查的URL列表,以分號分開,並且 URL 中不包括 ContextPath 

*/   
public class CheckLoginFilter    
implements Filter    
{    
     protected FilterConfig filterConfig = null;    
     private String redirectURL = null;    
     private List notCheckURLList = new ArrayList();    
     private String sessionKey = null;    
   
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException    
{    
    HttpServletRequest request = (HttpServletRequest) servletRequest;    
    HttpServletResponse response = (HttpServletResponse) servletResponse;    
   
     HttpSession session = request.getSession();    
   if(sessionKey == null)    
    {    
     filterChain.doFilter(request, response);    
    return;    
    }    
   if((!checkRequestURIIntNotFilterList(request)) && session.getAttribute(sessionKey) == null)    
    {    
     response.sendRedirect(request.getContextPath() + redirectURL);    
    return;    
    }    
    filterChain.doFilter(servletRequest, servletResponse);    
}    
   
public void destroy()    
{    
    notCheckURLList.clear();    
}    
   
private boolean checkRequestURIIntNotFilterList(HttpServletRequest request)    
{    
    String uri = request.getServletPath() + (request.getPathInfo() == null ? "" : request.getPathInfo());    
   return notCheckURLList.contains(uri);    
}    
   
public void init(FilterConfig filterConfig) throws ServletException    
{    
   this.filterConfig = filterConfig;    
    redirectURL = filterConfig.getInitParameter("redirectURL");    
    sessionKey = filterConfig.getInitParameter("checkSessionKey");    
   
    String notCheckURLListStr = filterConfig.getInitParameter("notCheckURLList");    
   
   if(notCheckURLListStr != null)    
    {    
     StringTokenizer st = new StringTokenizer(notCheckURLListStr, ";");    
     notCheckURLList.clear();    
    while(st.hasMoreTokens())    
     {    
      notCheckURLList.add(st.nextToken());    
     }    
    }    
}    
}  

  3、字符編碼的過濾器 

 

 1 import javax.servlet.*;    
 2 import java.io.IOException;    
 3    
 4 /** 
 5 * 用於設置 HTTP 請求字符編碼的過濾器,通過過濾器參數encoding指明使用何種字符編碼,用於處理Html Form請求參數的中文問題 
 6 */   
 7 public class CharacterEncodingFilter    
 8 implements Filter    
 9 {    
10 protected FilterConfig filterConfig = null;    
11 protected String encoding = "";    
12    
13 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException    
14 {    
15          if(encoding != null)    
16            servletRequest.setCharacterEncoding(encoding);    
17           filterChain.doFilter(servletRequest, servletResponse);    
18 }    
19    
20 public void destroy()    
21 {    
22     filterConfig = null;    
23     encoding = null;    
24 }    
25    
26      public void init(FilterConfig filterConfig) throws ServletException    
27 {    
28           this.filterConfig = filterConfig;    
29          this.encoding = filterConfig.getInitParameter("encoding");    
30    
31 }    
32 }  

 

  4、資源保護過濾器   

 1 import javax.servlet.Filter;    
 2 import javax.servlet.FilterConfig;    
 3 import javax.servlet.ServletRequest;    
 4 import javax.servlet.ServletResponse;    
 5 import javax.servlet.FilterChain;    
 6 import javax.servlet.ServletException;    
 7 import javax.servlet.http.HttpServletRequest;    
 8 import java.io.IOException;    
 9 import java.util.Iterator;    
10 import java.util.Set;    
11 import java.util.HashSet;    
12 //    
13 import org.apache.commons.logging.Log;    
14 import org.apache.commons.logging.LogFactory;    
15    
16 /** 
17 * This Filter class handle the security of the application. 
18 * 
19 * It should be configured inside the web.xml. 
20 * 
21 * @author Derek Y. Shen 
22 */   
23 public class SecurityFilter implements Filter {    
24 //the login page uri    
25 private static final String LOGIN_PAGE_URI = "login.jsf";    
26    
27 //the logger object    
28 private Log logger = LogFactory.getLog(this.getClass());    
29    
30 //a set of restricted resources    
31 private Set restrictedResources;    
32    
33 /** 
34    * Initializes the Filter. 
35    */   
36 public void init(FilterConfig filterConfig) throws ServletException {    
37   this.restrictedResources = new HashSet();    
38   this.restrictedResources.add("/createProduct.jsf");    
39   this.restrictedResources.add("/editProduct.jsf");    
40   this.restrictedResources.add("/productList.jsf");    
41 }    
42    
43 /** 
44    * Standard doFilter object. 
45    */   
46 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)    
47    throws IOException, ServletException {    
48   this.logger.debug("doFilter");    
49       
50    String contextPath = ((HttpServletRequest)req).getContextPath();    
51    String requestUri = ((HttpServletRequest)req).getRequestURI();    
52       
53   this.logger.debug("contextPath = " + contextPath);    
54   this.logger.debug("requestUri = " + requestUri);    
55       
56   if (this.contains(requestUri, contextPath) && !this.authorize((HttpServletRequest)req)) {    
57    this.logger.debug("authorization failed");    
58     ((HttpServletRequest)req).getRequestDispatcher(LOGIN_PAGE_URI).forward(req, res);    
59    }    
60   else {    
61    this.logger.debug("authorization succeeded");    
62     chain.doFilter(req, res);    
63    }    
64 }    
65    
66 public void destroy() {}    
67    
68 private boolean contains(String value, String contextPath) {    
69    Iterator ite = this.restrictedResources.iterator();    
70       
71   while (ite.hasNext()) {    
72     String restrictedResource = (String)ite.next();    
73        
74    if ((contextPath + restrictedResource).equalsIgnoreCase(value)) {    
75     return true;    
76     }    
77    }    
78       
79   return false;    
80 }    
81    
82 private boolean authorize(HttpServletRequest req) {    
83    
84               //處理用戶登錄    
85        /* UserBean user = (UserBean)req.getSession().getAttribute(BeanNames.USER_BEAN); 
86    
87    if (user != null && user.getLoggedIn()) { 
88     //user logged in 
89     return true; 
90    } 
91    else { 
92     return false; 
93    }*/   
94 }    
95 }   

 

  5、利用Filter限制用戶瀏覽權限  

   

import java.io.IOException;    

   
import javax.servlet.Filter;    
import javax.servlet.FilterChain;    
import javax.servlet.FilterConfig;    
import javax.servlet.ServletException;    
import javax.servlet.ServletRequest;    
import javax.servlet.ServletResponse;    
import javax.servlet.http.HttpServletRequest;    
   
public class RightFilter implements Filter {    
   
    public void destroy() {    
            
     }    
   
    public void doFilter(ServletRequest sreq, ServletResponse sres, FilterChain arg2) throws IOException, ServletException {    
        // 獲取uri地址    
         HttpServletRequest request=(HttpServletRequest)sreq;    
         String uri = request.getRequestURI();    
         String ctx=request.getContextPath();    
         uri = uri.substring(ctx.length());    
        //判斷admin級別網頁的瀏覽權限    
        if(uri.startsWith("/admin")) {    
            if(request.getSession().getAttribute("admin")==null) {    
                 request.setAttribute("message","您沒有這個權限");    
                 request.getRequestDispatcher("/login.jsp").forward(sreq,sres);    
                return;    
             }    
         }    
        //判斷manage級別網頁的瀏覽權限    
        if(uri.startsWith("/manage")) {    
            //這里省去    
             }    
         }    
        //下面還可以添加其他的用戶權限,省去。    
   
     }    
   
    public void init(FilterConfig arg0) throws ServletException {    
            
     }    
   
} 
<!-- 判斷頁面的訪問權限 -->   
  <filter>   
     <filter-name>RightFilter</filter-name>   
      <filter-class>cn.itkui.filter.RightFilter</filter-class>   
  </filter>   
  <filter-mapping>   
      <filter-name>RightFilter</filter-name>   
      <url-pattern>/admin/*</url-pattern>   
  </filter-mapping>   
  <filter-mapping>   
      <filter-name>RightFilter</filter-name>   
      <url-pattern>/manage/*</url-pattern>   
  </filter-mapping>   

  ps:過濾器在web.xml中的配置

<filter>   

        <filter-name>EncodingAndCacheflush</filter-name>   
        <filter-class>EncodingAndCacheflush</filter-class>   
        <init-param>   
            <param-name>encoding</param-name>   
            <param-value>UTF-8</param-value>   
        </init-param>   
    </filter>   
    <filter-mapping>   
        <filter-name>EncodingAndCacheflush</filter-name>   
        <url-pattern>/*</url-pattern>   
    </filter-mapping>   

六、使用filter生效的注意事項

 

  要傳遞參數的時候最好使用form進行傳參,如果使用鏈接的話當中文字符的時候過濾器轉碼是不會起作用的,還有就是頁面上

 

form的method也要設置為post,不然過濾器也起不了作用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM