`

Struts 2 的拦截器(三)

阅读更多

 

六、 拦截器示例 : 实现权限控制

权限检查,当浏览者需要请求执行某个操作时,应用首先需要检查浏览者是否登录,以及是否有足够的权限来执行该操作

 

6.1 实现拦截器

在这里会实现所有例子,后面章节在一一解释

 

   本示例应用要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源: 否则,系统直接转入登录页面。

   对于上述的需求,可以在每个 Action 的执行实际处理逻辑之前,先执行权限检查逻辑,为了代码复用,可以使用拦截器。

 

   个人认为判断 session 用 过滤器比较好 如下:

web.xml

  <filter>
  	<filter-name>SessionInvalidate</filter-name>
  	<filter-class>com.sysoft.baselib.web.SessionCheckFilter</filter-class>
  	<init-param>
  		<param-name>checkSessionKey</param-name>
  		<param-value>APP_SESSION_TOKEN</param-value>
  	</init-param>
  	<init-param>
  		<param-name>redirectURL</param-name>
  		<param-value>/sessionInvalidate.jsp</param-value>
  	</init-param>
  	<init-param>
  		<param-name>notCheckURLList</param-name>
  		<param-value>/login.jsp,/logon.do,/logout.jsp,/Index2/index.jsp,/sessionInvalidate.jsp,/Index2/maintop.jsp,/html.jsp</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>SessionInvalidate</filter-name>
  	<url-pattern>*.do</url-pattern>  	
  </filter-mapping>
 <filter-mapping>
  	<filter-name>SessionInvalidate</filter-name>
  	<url-pattern>*.jsp</url-pattern>  	
  </filter-mapping>

 SessionCheckFilter.java

package com.sysoft.baselib.web;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

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;
import javax.servlet.http.HttpSession;
/**      
* 用于检测用户是否登陆的过滤器,如果未登录,则重定向到指的登录页面       
* 配置参数            
* checkSessionKey 需检查的在 Session 中保存的关键字      
* redirectURL 如果用户未登录,则重定向到指定的页面,URL不包括 ContextPath       
* notCheckURLList 不做检查的URL列表,以分号分开,并且 URL 中不包括 ContextPath  
*/    
public class SessionCheckFilter implements Filter {
	protected FilterConfig filterConfig = null;
	private String redirectURL = null;
	private Set notCheckURLList = new HashSet();
	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());
		String temp = request.getRequestURI();
		temp= temp.substring(request.getContextPath().length()+1);
		//System.out.println("是否包括:"+uri+";"+notCheckURLList+"=="+notCheckURLList.contains(uri));
		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){
			System.out.println(notCheckURLListStr);
			String[] params = notCheckURLListStr.split(",");
			for(int i=0;i<params.length;i++){
				notCheckURLList.add(params[i].trim());
			}
		}
		
	}
}
 

 

    检查用户是否登录,通常都是通过跟踪用户的 HTTPSession 来完成的,通过 ActionContext 即可访问到 Session 中的属性,拦截器的 intercepte(ActionInvocation invocation) invocation 参数可以访问到请求相关的 ActionContext 实例

 

权限查看拦截器的例子

 

AuthorityInterceptor.java

package js.authority;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import java.util.*;

public class AuthorityInterceptor extends AbstractInterceptor {
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext ctx = invocation.getInvocationContext();
        Map session = ctx.getSession();
        String user = (String) session.get("user");

        if (user != null && user.equals("crazyit")) {
            return invocation.invoke();
        }
        ctx.put("tip", "您还没有登录,请输入crazyit,leegang登录系统");

//直接返回 login 的逻辑视图
        return Action.LOGIN;
    }
}

 通过 ActionInvocation 参数取得 session 实例,然后取出 user ,来判断用户是否登录,从而判断是否需要转入登录页面

 

LoginAction.java

package js.authority;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;
import java.util.*;

public class LoginAction extends ActionSupport {
    private String username;

    private String password;

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

    public String execute() throws Exception {
        Thread.sleep(1500);
        if (getUsername().equals("crazyit") && getPassword().equals("leegang")) {
            ActionContext ctx = ActionContext.getContext();
            Map session = ctx.getSession();
            session.put("user", getUsername());
            return SUCCESS;
        } else {
            return ERROR;
        }
    }

}
 

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd">
<struts>
	<constant name="struts.custom.i18n.resources"
		value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>	
	<package name="js.authority"  extends="struts-default" namespace="/authority">
		<!-- 用户拦截器定义在该元素下 -->
		<interceptors>
			<!-- 定义了一个名为authority的拦截器 -->
			<interceptor name="authority" class="js.authority.AuthorityInterceptor"/>
		</interceptors>

		<!-- 定义全局Result -->
		<global-results>
			<!-- 当返回login视图名时,转入/login.jsp页面 -->
			<result name="login">/authority/login.jsp</result>
		</global-results>

		<action name="login" class="js.authority.LoginAction">
			<result name="error">/authority/error.jsp</result>
			<result name="success">/authority/welcome.jsp</result>
		</action>
		<!-- 定义一个名为viewBook的Action,其实现类为ActionSupport -->
		<action name="viewBook">
			<!-- 返回success视图名时,转入/WEB-INF/jsp/viewBook.jsp页面 -->
			<result>/WEB-INF/jsp/viewBook.jsp</result>
			<!-- 拦截器一般配置在result元素之后! -->
			<interceptor-ref name="defaultStack"/>
			<!-- 应用自定义拦截器 -->
			<interceptor-ref name="authority"/>
		</action>
		<action name="">
			<result>.</result>
		</action>
	</package>
</struts>
 

/authority/login.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
	<title>登录页面</title>
</head>
<body>
<div style="color:red" align="center">${requestScope.tip}</div>
<form action="login.action" method="post">
<table align="center">
	<caption><h3>用户登录</h3></caption>
	<tr>
	<td>用户名:<input type="text" name="username"/></td>
	</tr>
	<tr>
		<td>密码:<input type="text" name="password"/></td>
	</tr>
	<tr align="center">
		<td><input type="submit" value="登录"/>
			<input type="reset" value="重填" /></td>
	</tr>
</table>
</form>
<div align="center"><a href="viewBook.action">
	查看作者李刚出版的图书</a>
</div>
</body>
</html>
 

/authority/welcome.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>成功页面</title>
</head>
<body>
	您已经登录!<br />
	<a href="viewBook.action">查看作者李刚出版的图书</a>
</body>
</html>
 

/authority/error.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>错误页面</title>
</head>
<body>
您不能登录!<br />
	<a href="viewBook.action">查看作者李刚出版的图书</a>
</body>
</html>
 

/WEB-INF/jsp/viewBook.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>作者李刚已经出版的图书:</title>
</head>
<body>
	<h3>作者李刚已经出版的图书:</h3>
	疯狂Java讲义<br />
	轻量级Java EE企业实战<br />
	疯狂Ajax讲义<br />
</body>
</html>
 <s:a href="" onclick="newWin('authority/login.jsp');" cssStyle="cursor: hand;">authority/login.jsp</s:a>

 

 

6.2  配置权限控制拦截器

以下代码全部基于 6.1

 

   6.1struts.xml 中的 viewBook Action , 没有指定 class 属性,默认使用 ActionSupport 类,配置该 Action 时,只指定了一个结果映射,指定系统返回 success 字符串时,系统将转入 /WEB-INF/jsp/viewBook.jsp ,但未配置 login 视图名对应的 jsp

 

   考虑到这个拦截器的重复使用,可能多个 Action 都需要跳转到 login 逻辑视图,故将 login 的结果映射定义成一个全局结果映射

<!-- 定义全局Result -->
<global-results>
	<!-- 当返回login视图名时,转入/login.jsp页面 -->
	<result name="login">/authority/login.jsp</result>
</global-results>
 

为了简化 struts.xml 文件配置,避免在每个 Action 中重复配置该拦截器,可以将该拦截器配置成一个默认拦截器栈(这个默认拦截器栈应该包括 default-stack 拦截器栈和权限检查拦截器)

<!-- 用户拦截器定义在该元素下 -->
		<interceptors>
			<!-- 定义了一个名为authority的拦截器 -->
			<interceptor name="authority" class="js.authority.AuthorityInterceptor"/>
			<interceptor-stack name="mydefault">
				<interceptor-ref name="defaultStack"/>
				<interceptor-ref name="authority"/>
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="mydefault"/>

不过  6.1 的例子 不能使用默认拦截器,因为 login Action 不能被拦截,否则将永远不能登录


解决方法: 一旦在某个包下定义了上面的默认拦截器栈,在该包下的所有 Action 都会自动增加权限检查功能,对于那些不需要使用权限控制的 Action ,将它们定义在另一个包中,这个新的包中依然使用 Struts 2 原有的默认拦截器栈,将不会有权限控制功能。

 

 

 

 

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Struts2拦截器(Interceptor)

    Struts2拦截器(Interceptor) Struts2拦截器(Interceptor)

    Struts2拦截器及其用法详细说明

    在Struts2中,拦截器(Interceptors)扮演着核心角色,增强了框架的功能和灵活性。这篇文章将深入探讨Struts2拦截器的概念、工作原理以及如何在实际应用中使用它们。 **一、什么是Struts2拦截器** 拦截器是基于AOP...

    struts2 拦截器

    2. **拦截器链**:在Struts2中,多个拦截器可以形成一个拦截器链,每个拦截器按照定义的顺序依次执行。如果所有拦截器都允许Action执行,那么Action的结果将被传递到下一个拦截器,直到整个链执行完毕。 ### 二、...

    struts2 拦截器实例

    在Struts2中,拦截器(Interceptor)扮演着核心角色,它们允许开发者在Action执行前后插入自定义的逻辑,如日志、权限检查、事务管理等。现在我们将深入探讨Struts2的拦截器机制及其实例应用。 ### 一、Struts2拦截...

    详解Struts2拦截器

    ### Struts2拦截器详解 #### 一、Struts2拦截器概述 Struts2框架作为Java Web开发中的一种流行框架,其核心组件之一便是**拦截器**。拦截器不仅在Struts2中扮演着重要角色,更是整个框架灵活性与扩展性的基石。...

    Struts2拦截器.ppt

    Struts2拦截器.ppt Struts2拦截器.ppt Struts2拦截器.ppt

    struts2拦截器

    标题“struts2拦截器”指的是Struts2框架中的拦截器机制,这是一个关键的组件,可以让我们在不修改实际业务代码的情况下,实现对请求处理流程的扩展和定制。 描述中提到的“基于struts2的拦截器测试,实现了页面的...

    Struts2拦截器实现权限控制demo

    在这个“Struts2拦截器实现权限控制demo”中,我们将深入探讨如何利用拦截器来实现细粒度的用户权限管理。 首先,我们需要了解Struts2中的拦截器工作原理。拦截器是基于Java的动态代理模式实现的,它们按照配置的...

    Struts2 拦截器

    拦截器是Struts2框架的核心特性之一,它们扮演着处理请求、增强功能和实现业务逻辑的角色。在Struts2中,拦截器就像过滤器一样工作,通过链式调用在动作执行前后进行预处理和后处理。 首先,我们来理解一下拦截器的...

    struts2拦截器的使用方法

    #### 三、Struts2内置拦截器与自定义拦截器 Struts2提供了许多内置的拦截器,比如`defaultStack`拦截器堆栈,包含了多个常用的拦截器,如模型驱动(ModelDriven)、参数拦截器(Parameters)、验证器(Validation)...

    struts2拦截器应用小例子

    当请求到达控制器时,Struts2会依次调用这个栈中的拦截器,每个拦截器都有机会处理请求,然后决定是否将请求传递给下一个拦截器或直接返回响应。 创建一个简单的Struts2拦截器,你需要遵循以下步骤: 1. 创建拦截...

    Struts2拦截器原理分析

    拦截器是Struts2框架的核心组成部分,它们在请求处理流程中起到了关键的作用。在本文中,我们将深入探讨Struts2拦截器的工作原理。 ### 一、拦截器概念 拦截器是基于Java的动态代理机制实现的,它允许我们在Action...

    Struts2拦截器源程序

    在Struts2中,拦截器扮演着至关重要的角色,它们是实现MVC(Model-View-Controller)架构的关键组件之一。拦截器允许开发者在动作执行前后插入自定义逻辑,比如日志记录、权限检查、数据验证等,而无需修改核心业务...

    Struts2拦截器源码

    首先,理解拦截器的定义:拦截器是AOP(面向切面编程)的一个概念,在Struts2中,拦截器是基于Java的动态代理机制实现的。它们是一系列实现了`Interceptor`接口的类,可以在Action执行前后插入额外的行为。这些行为...

    struts2拦截器实现拦截不文明字迹

    拦截器是Struts2框架的一个重要组成部分,能够帮助开发者实现一些在请求处理前后执行的通用逻辑,如日志记录、权限验证、数据校验等。在本场景中,我们将探讨如何使用Struts2拦截器来实现对不文明字迹或者敏感词汇的...

    使用struts2拦截器对登陆权限验证

    在Struts2中,拦截器(Interceptor)扮演着至关重要的角色,它允许开发者在动作执行前后插入自定义逻辑,如日志记录、权限验证等。在本案例中,我们将深入探讨如何使用Struts2拦截器实现登录权限验证,同时结合...

    Struts2学习案例(拦截器)

    在本学习案例中,重点在于Struts2的拦截器(Interceptor)功能,这是Struts2的核心特性之一,它允许开发者在Action执行前后进行自定义处理,实现了灵活的业务逻辑控制和增强的功能。 首先,我们来理解一下什么是...

    创建自己struts2拦截器

    Struts2是一个强大的MVC框架,它通过使用拦截器(Interceptor)来实现业务逻辑与表现层的解耦,提供了一种灵活的扩展机制。在Struts2中,拦截器是AOP(面向切面编程)的一种实现,它可以监控、修改或增强方法调用的...

    struts2拦截器实现权限控制

    这篇博客文章“struts2拦截器实现权限控制”深入探讨了如何利用Struts2的拦截机制来执行用户访问权限的验证。 在Struts2中,拦截器是基于AOP(面向切面编程)的概念设计的,它们在Action调用前后执行,可以添加额外...

    struts2拦截器国际化

    在Struts2中,拦截器(Interceptor)是实现业务逻辑控制和增强功能的重要机制,而国际化(Internationalization,简称i18n)则能帮助我们构建支持多语言的Web应用。下面将详细解释这两个知识点以及它们如何在Struts2...

Global site tag (gtag.js) - Google Analytics