設置編碼過濾器、用戶在線驗證(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");
}
}
如有其它的意見歡迎補充~