Filter:JSP系統設置多個過濾器

設置編碼過濾器、用戶在線驗證(session檢測)過濾器、記錄訪問時間過濾器,在web.xml的<web-app>標籤裏面,設置多個<filter>,添加的代碼如下。

<filter>
		<filter-name>encodeFilter</filter-name>
		<filter-class>com.demo.filter.EncodeFilter</filter-class>
		<init-param>
			<param-name>encode</param-name>
			<param-value>utf-8</param-value>
		 	</init-param>
		<init-param>
			<param-name>ignore</param-name>
			<param-value>false</param-value>
		</init-param>
   	</filter>
   	<filter-mapping>
       	<filter-name>encodeFilter</filter-name>
       	<url-pattern>/*</url-pattern>			<!-- "/*"即對所有的請求進行過濾 -->
   	</filter-mapping>
   	
   	<filter>
		<filter-name>loginFilter</filter-name>
		<filter-class>com.demo.filter.LoginFilter</filter-class>
		<init-param>
			<param-name>gotoUrl</param-name>
			<param-value>/login.jsp</param-value>
		</init-param>
		<init-param>
			<param-name>ignore</param-name>
			<param-value>false</param-value>
		</init-param>
	</filter>        
	<filter-mapping>
		<filter-name>loginFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
	
	<filter>
		<filter-name>countTimeFilter</filter-name>
		<filter-class>com.demo.filter.CountTimeFilter</filter-class>
	</filter>        
	<filter-mapping>
		<filter-name>countTimeFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

可以看到設置了三個過濾器:編碼過濾器、用戶在線驗證(session檢測)過濾器、記錄訪問時間過濾器。過濾器(Filter)的執行順序爲:encodeFilter--loginFilter--countTimeFilter,對於一個MVC系統,整個過程順序應該是這樣的:‘V’--‘Filter’--‘C’--‘M’--‘Filter’--‘V’,見過有一張圖片很形象描述出整個過程順序的,有興趣的可以找找。在每個過濾器(Filter的子類)的doFilter()方法,都會帶有“chain.doFilter(request,response);”這樣一行代碼,意味:本過濾器主要方法執行完了下一個過濾器來的猛烈些吧,注意,此時過濾器沒關掉,過濾器是每當用戶訪問時,是最先被調用的(在”過程順序“的開頭),也是最後才關閉的(在”過程順序“的結尾)。下面分別對每個過濾器做介紹。

(1)編碼過濾器的路徑爲:com.demo.filter.EncodeFilter,詳細介紹見上一篇文章,這裏附上其部分的代碼:

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		if (!ignore) {
			if (null == request.getCharacterEncoding()) {
				request.setCharacterEncoding(encode);
			}
		}
		wordFiltering(request,response);
		chain.doFilter(request,response);
	}

(2)用戶在線驗證(session檢測)過濾器的路徑爲com.demo.filter.LoginFilter。該過濾器要注意其在web.xml的映射設置,若設置爲<url-pattern>/*</url-pattern>,則頁面從服務器傳到瀏覽器時將只有文字,頁面的圖片、樣式等等元素都被過濾了,結果大吃一斤有木有,當時我就大吃兩斤了,後來參考網上的資料,改成<url-pattern>*.jsp</url-pattern>就解決了問題,“/*”的用法還是講技巧的。當用戶訪問頁面時,每個操作都會檢測用戶的session是否存在,若用戶沒有正常登陸則不會執行用戶的操作並轉到登陸頁面,當然,改過濾器對某些頁面設置了放行,放行的頁面參見類的成員變量permitUrlList。另外,過濾器也設置了訪問ip過濾、特殊用戶過濾,訪問ip過濾參見類的成員變量permitUrlList,特殊用戶過濾參見類的成員變量userBlockList。該類的代碼如下。

package com.demo.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

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;
import javax.servlet.http.HttpServletResponse;

/*
 * 限制IP訪問
 * 限制用戶訪問
 * 限制離線操作
 */
public class LoginFilter implements Filter{
	private boolean ignore = false;
	private String gotoUrl = null;
	private List<String> ipBlockList = new ArrayList<String>(); 
	private List<String> userBlockList = new ArrayList<String>(); 
	private List<String> permitUrlList = new ArrayList<String>();

	public void init(FilterConfig filterConfig) throws ServletException {
		String ignore = filterConfig.getInitParameter("ignore");
		String gotoUrl = filterConfig.getInitParameter("gotoUrl");
		if ("1".equals(ignore) || "true".equals(ignore)) {
			this.ignore = true;
		}
		this.gotoUrl = gotoUrl;   
		this.ipBlockList.add("222.2");
		//this.ipBlockList.add("127.0");
		this.userBlockList.add("test1");
		this.userBlockList.add("test2");
		this.permitUrlList.add("group.jsp");
		this.permitUrlList.add("login.jsp");
		this.permitUrlList.add("register.jsp");
	}
	
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse)response;
		if(!ignore){
			if(checkIP(request,response)){					//限制IP訪問
				String username = (String)req.getSession().getAttribute("username");
				if(username!=null){							//限制離線操作
					for(String userBlock : userBlockList){	//限制用戶訪問
						if(username.equals(userBlock)){
							PrintWriter out = response.getWriter();
							out.println("<h3>Sorry for your Permission...</h3>");
							out.flush();
							return;
						}
					}
					chain.doFilter(request, response);
			   }else{
				   String uri = req.getRequestURI();
				   System.out.print(uri);
				   for(String permitUrl : permitUrlList){
					   if(uri.indexOf(permitUrl)>0){
							chain.doFilter(request, response);
							return;
					   }
				   }
				   resp.sendRedirect(req.getContextPath() + gotoUrl);
			   }
			}
		}
	}
	private boolean checkIP(ServletRequest request, ServletResponse response) throws IOException, ServletException {
		String addr = request.getRemoteAddr();
		for(String a:ipBlockList){
			if(addr.indexOf(a)==0){
				PrintWriter out = response.getWriter();
				out.println("<h3>Sorry for your IPaddress...</h3>");
				out.flush();
				return false;
			}
		}
		return true;
	}

	public void destroy() {
		ignore = false;
		gotoUrl = null;
	}
	
}

(3)訪問時間記錄過濾器的路徑爲com.demo.filter.CountTimeFilter,實現的方法比較簡單,代碼如下所示。

package com.demo.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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;

import org.apache.commons.logging.LogFactory;

import sun.security.krb5.Config;

/*
 *記錄用戶的訪問時間 
 */
public class CountTimeFilter implements Filter{
	private long startTime;
	private long endTime;
	private FilterConfig filterConfig = null;

	public void init(FilterConfig config) throws ServletException {
		this.filterConfig = config;
	}
	
	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		String username = (String)req.getSession().getAttribute("username");
		String uri = req.getRequestURI();
		startTime = System.currentTimeMillis();
		chain.doFilter(request, response);
		endTime = System.currentTimeMillis();
		long countTime = endTime-startTime;
		filterConfig.getServletContext().log("CountTimeFilter:'"+username+"' visited '"+uri+"' in "+ countTime +"ms");
	}
}
如有其它的意見歡迎補充~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章