Structs过滤器

Structs过滤器

一、工作目的

有时候我们希望在action执行之前,能捕获用户发出的请求,进行一些预处理的工作。例如:假设某系统设计,只有该系统的用户才能访问*.jsp页面,那么非系统用户如果直接在浏览器中输入*.jsp的访问路径,如何拒绝其访问呢?可以通过过滤器,判断是否存在该用户登录保存的session,进而实现访问的控制。在本次试验中,将首先介绍一些关于Filter的基础知识,然后根据程序演示过滤器的具体实现。

二、详细内容

Filter用于拦截用户请求,在服务器作出响应前,修改拦截下的request和response,以实现很多开发者想得到的功能。Filter是一个可以传送请求或修改响应的对象。过滤器并不是servlet,他们并不实际创建新的请求。而是请求到达一个servlet前的预处理程序,或响应离开servlet后的后处理程序。它是随你的web应用启动而启动的,只初始化一次,只有当你的web应用停止或重新部署的时候才销毁。过滤器需要实现java.servlet.Filter接口,并定义它的三个方法:

1. void init(): 在过滤器执行服务前被调用,以设置过滤器的配置对象。

2. void destroy():在过滤器执行服务后被调用。

3.void doFilter(): 执行实际的过滤工作。

服务器调用一次init(FilterConfig)为服务准备过滤器,然后在请求需要使用过滤器的时候调用doFilter()。FilterConfig接口检索过滤器名、初始化参数以及活动的servlet上下文。服务器调用destory()以指出过滤器已结束服务。在doFilter()方法中,每个过滤器都接受当前的请求和响应,可以对请求和响应做它想做的一切。过滤器调用chain.doFilter()将控制权传送给下一过滤器。当此调用返回后,过滤器可以在它的doFilter()方法的最后对响应做些其他的工作;例如:记录响应的信息。如果过滤器想要终止请求的处理或得对响应的完全控制,则他可以不调用下一个过滤器。

①在web.xml中配置filter

<filter>
  	<filter-name>requestCheck</filter-name>
  	<filter-class>filter.requestFilter</filter-class> 	
  </filter>
  <filter-mapping>
		<filter-name>requestCheck</filter-name>
		<url-pattern>/web/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
		<filter-name>requestCheck</filter-name>
		<url-pattern>*.jsp</url-pattern>
  </filter-mapping>

filter-name:申明一过滤器名字。

filter-class:指定该过滤器的实现类。

filter-mapping:用来声明Web应用中的过滤器映射,过滤器可被映射到一个servlet或一个URL模式。

url-pattern:表示filter拦截用户请求的类型。如上配置的过滤所有url中带”web/”以及所有的jsp页面。

②实现上面配置过滤器的类requeFilter.java

        public void destroy() {
		}
	public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
	    HttpServletResponse resp = (HttpServletResponse) response;
	    HttpSession session = req.getSession(false);
	    String uri = req.getRequestURI();
	    try{
	    	if (!uri.contains("/login.jsp")) {
	    	  String tag=(String) session.getAttribute("tag");
	  	  if ((session == null)||(tag==null)) {
	  	      resp.sendRedirect(req.getContextPath() + "/login.jsp");
	  	        return;}
	  	    }
	  	    chain.doFilter(request, response);
	    }catch(Exception e){
	    	resp.sendRedirect(req.getContextPath() + "/login.jsp");
	    }
	}
	public void init(FilterConfig filterConfig) throws ServletException {
        }

doFilter实现的功能是对所有非登录页面的请求执行过滤操作,如果tomcat容器保存有当面用户登录的session则放行,否则通过response重定向到系统的login.jsp页面。

③structs.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE struts PUBLIC  
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
    "http://struts.apache.org/dtds/struts-2.3.dtd">  
  
<struts>  
    <constant name="struts.i18n.encoding" value="UTF-8" /> 
 	<package name="default" namespace="/web" extends="struts-default">
       <action name="login" class="action.loginAction"  method="login">
               <result name="success">/success.jsp</result>
               <result name="error">/fail.jsp</result>
       </action>
    </package>
</struts> 

通过登录页面找到处理该action的实现类及方法,验证成功后跳转到success.jsp页面,否则跳转到fail.jsp页面。

处理登录的简单实现:

public String login(){
		if(username!=null&&password!=null){
			if(username.equals("test")&&password.equals("123123")){
				HttpSession session=request.getSession();
				session.setAttribute("tag", "login");
				return SUCCESS;
			}else
				return ERROR;
		}
		return ERROR;
	}

测试结果一:

直接在浏览器输入:http://192.168.1.110:8080/filterDemo/success.jsp,由于之前并没有用户登录,因而按照处理逻辑,系统将跳转到login.jsp:

测试结果二:

直接在浏览器输入:http://192.168.1.110:8080/filterDemo/login.jsp,用户名:test,密码:123123,登录之后系统会自动跳转到success.jsp,此时在浏览器输入:http://192.168.1.110:8080/filterDemo/fail.jsp仍可访问:


说明session对象用于存储特定的用户会话所需的信息。当用户在应用程序的web之间跳转时,存储在session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当一个用户首次访问服务器上的一个jsp页面时,jsp引擎产生一个session对象,同时分配一个String类型的ID号,jsp引擎发送该ID到客户端,存放在cookie中。当用户再访问链接该服务器的其他页面时,不再分配新的session对象。直到浏览器关闭后,该session对象才取消,下次访问,再创建新的session对象。

然而有时候我们希望不过滤一些页面或者action请求,允许某些特定的页面不用过滤就可以直接访问,如:index.jsperror.jsp等,修改web.xml配置文件:

<span style="font-family:Microsoft YaHei;font-size:12px;"><filter>
  	<filter-name>requestCheck</filter-name>
  	<filter-class>filter.requestFilter</filter-class> 	
  	<init-param>
	<param-name>notCheck</param-name>
        <param-value>/error.jsp,/index.jsp,/login.jsp</param-value>
	</init-param>
  </filter>
  <filter-mapping>
		<filter-name>requestCheck</filter-name>
		<url-pattern>/web/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
		<filter-name>requestCheck</filter-name>
		<url-pattern>*.jsp</url-pattern>
  </filter-mapping></span>

可以看出与之前的配置文件相比,多了init-paramparam-nameparam-value等几项参数,用以初始化filter的参数,在实现该filterrequestFilter.java类中,可以方便的读出初始化的值,并进行随后的逻辑处理,修改后的filter实现类:

<span style="font-family:Microsoft YaHei;">public class requestFilter implements Filter{
	
	protected FilterConfig filterConfig = null;
	private List notCheckList = new ArrayList();

	public void destroy() {
		// TODO Auto-generated method stub
		notCheckList.clear();
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
	    HttpServletRequest req = (HttpServletRequest) request;
	    HttpServletResponse resp = (HttpServletResponse) response;
	    HttpSession session = req.getSession(false);
	    String uri = req.getRequestURI();
	    
	    try{
	    	if ((!notCheckRequest(req))&&(!uri.contains("/login.jsp"))) {
	    	  String tag=(String) session.getAttribute("tag");
	  	      if ((session == null)||(tag!=null)) {
	  	        resp.sendRedirect(req.getContextPath() + "/login.jsp");
	  	        return;
	  	      }
	  	    }
	  	    chain.doFilter(request, response);
	    }catch(Exception e){
	    	resp.sendRedirect(req.getContextPath() + "/login.jsp");
	    }
	}

	@SuppressWarnings("unchecked")
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		this.filterConfig = filterConfig;
		String notCheck = filterConfig.getInitParameter("notCheck");
		if (notCheck != null) {
			StringTokenizer st = new StringTokenizer(notCheck, ",");
			notCheckList.clear();
			while (st.hasMoreTokens()) {
				notCheckList.add(st.nextToken());
			}
		}
	}
	
	private boolean notCheckRequest(HttpServletRequest request) {
		String uri = request.getServletPath()
				+ (request.getPathInfo() == null ? "" : request.getPathInfo());
		return notCheckList.contains(uri);
	}
	
}</span>

FilterConfig对象提供对servlet环境及web.xml文件中指派的过滤器名的访问。它具有一个getInitParameter()方法,它能够访问部署描述符文件(web.xml)中分配的过滤器初始化参数。调用filterConfig.getInitParameter(“notCheck”);得到<param-value>/error.jsp,/index.jsp,/login.jsp
</
param-value>指定的值。然后将request中请求的路径与初始化值进行匹配,存在则放行,否者进入处理逻辑。

测试结果:

*工程所需jar


发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *