`

servlet filter

阅读更多
filter功能:使用户可以改变一个request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).一个filter 包括:
1. 在servlet被调用之前截获;
2. 在servlet被调用之前检查servlet request;
3. 根据需要修改request头和request数据;
4. 根据需要修改response头和response数据;
5. 在servlet被调用之后截获.

你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用.几个实用的filter 包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等.

一个filter必须实现javax.servlet.Filter接口并定义三个方法:
1.void setFilterConfig(FilterConfig config) //设置filter 的配置对象;
2. FilterConfig getFilterConfig() //返回filter的配置对象;
3. void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) //执行filter 的工作.

服务器每次只调用setFilterConfig方法一次准备filter 的处理;调用doFilter方法多次以处理不同的请求.FilterConfig接口有方法可以找到filter名字及初始化参数信息.服务器可以设置FilterConfig为空来指明filter已经终结.
每一个filter从doFilter()方法中得到当前的request及response.在这个方法里,可以进行任何的针对request及response的操作.(包括收集数据,包装数据等).filter调用chain.doFilter()方法把控制权交给下一个filter.一个filter在doFilter()方法中结束.如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下一个filter.

一个filter可以包装request 或response以改变几个方法和提供用户定制的属性.Api2.3提供了HttpServletRequestWrapper 和HttpServletResponseWrapper来实现.它们能分派最初的request和response.如果要改变一个方法的特性,必须继承wapper和重写方法.下面是一段简单的日志filter用来记录所有request的持续时间.

public class LogFilter implements Filter { 
FilterConfig config; 

public void setFilterConfig(FilterConfig config) { 
this.config = config; 
} 

public FilterConfig getFilterConfig() { 
return config; 
} 

public void doFilter(ServletRequest req, 
ServletResponse res, 
FilterChain chain) { 
ServletContext context = getFilterConfig().getServletContext(); 
long bef = System.currentTimeMillis(); 
chain.doFilter(req, res); // no chain parameter needed here 
long aft = System.currentTimeMillis(); 
context.log("Request to " + req.getRequestURI() 
+ ": " + (aft-bef)); 
} 
} 

 


当server调用setFilterConfig(),filter保存config信息.在doFilter()方法中通过config信息得到servletContext.如果要运行这个filter,必须去配置到web.xml中.以tomcat4.01为例:
<filter> 
    <filter-name> 
         log //filter 名字 
   </filter-name> 
    <filter-class> 
       LogFilter //filter class(上例的servlet) 
    </filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>log</filter-name> 
    <servletname>servletname</servlet-name> 
</filter-mapping> 

<servlet> 
     <servlet-name>servletname</servletname> 
     <servletclass>servletclass</servlet-class> 
</servlet> 
<servlet-mapping> 
      <servlet-name>servletname</servlet-name> 
      <url-pattern>*</url-pattern> 
</servlet-mapping> 
 
把这个web.xml放到web-inf中(详请参考tomcat帮助文档).
当每次请求一个request时(如index.jsp),先到LogFilter中去并调用doFilter()方法,然后才到各自的servlet中去.如果是一个简单的servlet(只是一个页面,无任何输出语句),那么可能的输出是:
Request to /index.jsp: 10







参考:

http://www.cngr.cn/article/54/67/2006/2006071928420.shtml

http://blog.csdn.net/li_jinjian2005/archive/2008/08/28/2844501.aspx

 

 

参考:http://www.iteye.com/topic/211147

五个有用的过滤器

一、使浏览器不缓存页面的过滤器
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 { 
} 
} 
 
二、检测用户是否登陆的过滤器

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()); 
			} 
		} 
	} 
} 
 
三、字符编码的过滤器
import javax.servlet.*; 
import java.io.IOException; 

/** 
* 用于设置 HTTP 请求字符编码的过滤器,通过过滤器参数encoding指明使用何种字符编码,用于处理Html Form请求参数的中文问题 
*/ 
public class CharacterEncodingFilter implements Filter 
{ 
	protected FilterConfig filterConfig = null; 
	protected String encoding = ""; 

	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException 
	{ 
		if(encoding != null) 
			servletRequest.setCharacterEncoding(encoding); 
		filterChain.doFilter(servletRequest, servletResponse); 
	} 

	public void destroy() 
	{ 
		filterConfig = null; 
		encoding = null; 
	} 

	public void init(FilterConfig filterConfig) throws ServletException 
	{ 
		this.filterConfig = filterConfig; 
		this.encoding = filterConfig.getInitParameter("encoding"); 
	} 
} 
 
四、资源保护过滤器

package catalog.view.util; 
import javax.servlet.Filter; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import java.io.IOException; 
import java.util.Iterator; 
import java.util.Set; 
import java.util.HashSet; 
// 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

/** 
* This Filter class handle the security of the application. 
* 
* It should be configured inside the web.xml. 
* 
* @author Derek Y. Shen 
*/ 
public class SecurityFilter implements Filter { 
	//the login page uri 
	private static final String LOGIN_PAGE_URI = "login.jsf"; 

	//the logger object 
	private Log logger = LogFactory.getLog(this.getClass()); 

	//a set of restricted resources 
	private Set restrictedResources; 

	/** 
	* Initializes the Filter. 
	*/ 
	public void init(FilterConfig filterConfig) throws ServletException { 
		this.restrictedResources = new HashSet(); 
		this.restrictedResources.add("/createProduct.jsf"); 
		this.restrictedResources.add("/editProduct.jsf"); 
		this.restrictedResources.add("/productList.jsf"); 
	} 

	/** 
	* Standard doFilter object. 
	*/ 
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
		this.logger.debug("doFilter"); 
		String contextPath = ((HttpServletRequest)req).getContextPath(); 
		String requestUri = ((HttpServletRequest)req).getRequestURI(); 
		this.logger.debug("contextPath = " + contextPath); 
		this.logger.debug("requestUri = " + requestUri); 

		if (this.contains(requestUri, contextPath) && !this.authorize((HttpServletRequest)req)) { 
			this.logger.debug("authorization failed"); 
			((HttpServletRequest)req).getRequestDispatcher(LOGIN_PAGE_URI).forward(req, res); 
		} else { 
			this.logger.debug("authorization succeeded"); 
			chain.doFilter(req, res); 
		} 
	} 

	public void destroy() {} 
	
	private boolean contains(String value, String contextPath) { 
		Iterator ite = this.restrictedResources.iterator(); 
		while (ite.hasNext()) { 
			String restrictedResource = (String)ite.next(); 
			if ((contextPath + restrictedResource).equalsIgnoreCase(value)) { 
				return true; 
			} 
		} 

		return false; 
	} 

	private boolean authorize(HttpServletRequest req) { 

	//处理用户登录 
	/* UserBean user = (UserBean)req.getSession().getAttribute(BeanNames.USER_BEAN); 

	if (user != null && user.getLoggedIn()) { 
	//user logged in 
		return true; 
	} 
	else { 
		return false; 
	}*/ 
	} 
} 
 

五 利用Filter限制用户浏览权限

在一个系统中通常有多个权限的用户。不同权限用户的可以浏览不同的页面。使用Filter进行判断不仅省下了代码量,而且如果要更改的话只需要在Filter文件里动下就可以。
以下是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> 
 
在web.xml中加入Filter的配置,如下:
<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> 
 
要传递参数的时候最好使用form进行传参,如果使用链接的话当中文字符的时候过滤器转码是不会起作用的,还有就是页面上

form的method也要设置为post,不然过滤器也起不了作用。

 

另:参考  
众所周知,如果没有对页面进行权限控制,用户只要输入URL就能进入任何页面。下面就演示一下最基本的使用Fiter来控制页面的权限。 
1.写一个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.HttpServlet;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
import javax.servlet.http.HttpSession;    
   
import org.apache.log4j.Logger;    
   
import com.kiral.action.UserAction;    
import com.kiral.model.User;    
   
/*******************************************************************************   
 * 在过滤器中实现权限控制类,用来检验用户是否有权限进入当前页面   
 *    
 * @作者:kiral   
 * @日期:2006-6-24   
 * @版本: 1.0   
 ******************************************************************************/   
public class FilterServlet extends HttpServlet implements Filter {    
    private static final long serialVersionUID = 5162189625393315379L;    
   
    private static Logger LOG = Logger.getLogger(FilterServlet.class);    
   
    /**   
     * 配置允许的角色   
     */   
    private String allowRole = null;    
   
    /**   
     * 重定向的URL   
     */   
    private String redirectURl = null;    
   
    public void init(FilterConfig filterConfig) throws ServletException {    
        // 得到允许的角色,这个参数是由web.xml里的allowRole所指定    
        allowRole = filterConfig.getInitParameter("allowRole");    
        // 指定要重定向的页面    
        redirectURl = "/locker/index.html";    
    }    
   
    /**   
     * 在过滤器中实现权限控制   
     */   
    public void doFilter(ServletRequest sRequest, ServletResponse sResponse,    
            FilterChain filterChain) throws IOException, ServletException {    
        HttpServletRequest request = (HttpServletRequest) sRequest;    
        HttpServletResponse response = (HttpServletResponse) sResponse;    
        HttpSession session = request.getSession();    
   
        // 如果回话中的用户为空,页面重新定向到登陆页面    
        if (session.getAttribute(UserAction.CURRENT_USER) == null) {    
            response.sendRedirect(redirectURl);    
        }    
        // 会话中存在用户,则验证用户是否存在当前页面的权限    
        else {    
            User user = (User) session.getAttribute(UserAction.CURRENT_USER);    
            try {    
                // 如果用户没有当前页的权限,页面重新定向到登陆页面    
                if ("0".equals(allowRole) || user.hasPower(allowRole)) {    
                    filterChain.doFilter(sRequest, sResponse);    
                } else {    
                    // 过滤器经过过滤后,过滤链继续传递请求和响应    
                    response.sendRedirect(redirectURl);    
                }    
            } catch (Throwable e) {    
                LOG.error("权限过滤时候出现错误", e);    
                throw new RuntimeException("权限过滤时候出现错误", e);    
            }    
        }    
    }    
   
    public void destroy() {    
    }    
   
}   
 

在web.xml中配置 要过滤的页面和能进入当前页面的角色

<filter>   
        <filter-name>UserAdminfilter-name>   
           
        <filter-class>com.emap.web.FilterServletfilter-class>   
           
        <init-param>   
               
            <param-name>allowRoleparam-name>   
            <param-value>1param-value>   
        <init-param>   
</filter>   
<filter-mapping>   
        <filter-name>UserAdmin</filter-name>   
        <url-pattern>/jsp/security/*</url-pattern>   
</filter-mapping>   
 

上面配置的意思是说,当用户进入/jsp/security文件夹下的页面的时候,程序会进入FilterServlet 里的doFilter方法里,进行权限判断。

 其他的页面权限控制:

  1.你可以在filter里判断用户是否登录,然后需要特殊权限能访问的页面,在页面里进行判断。

  2.推荐使用开源框架ACEGI来进行权限控制。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics