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");
	}
}
如有其它的意见欢迎补充~

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