关闭

【Struts2】:Interceptor实战之权限控制

标签: interceptor权限控制
637人阅读 评论(3) 收藏 举报
分类:
        之前的博客介绍了拦截器的概念以及Struts2自带以及自定义拦截器的一些基础知识,但是拦截器究竟如何应用在实际项目里,或许你还很迷惑,那么本次博客我们就一起来实战一下,也算是对拦截器的一个总结和应用实践。
        我们在做任何的信息管理系统的时候,无可避免的要进行权限控制,对于登录用户的身份以及所拥有的权限进行验证,不让不合法的用户随意更改我们的数据和程序,以保证系统的安全性。这样一个非常普遍的功能,我们要使用Struts2的拦截器去实现权限检查,当浏览者需要请求执行某个操作时,应用系统需要先检查用户是否登录,以及是否有足够的权限来执行该操作。
        在这个Demo中,我们要求用户必须登录,并且必须为指定用户名的用户才可以查看系统中的某个视图资源,否则,系统直接转入登录页面。对于这样的需求,可以在每个Action执行实际的处理逻辑之前,先进行权限验证逻辑,但是这种做法不利于代码的复用,因为大部分Action里的权限验证代码都大同小异,故将这些权限验证的代码放在拦截器中将显得更加方便和灵活,也更为专业。
        检查用户是否登录,通常都是通过跟踪用户的Session来完成的,通过ActionContext即可访问到session中的属性,拦截器的intercept方法的invocation参数可以很容易地访问到请求相关的ActionContext实例。

        我们先来编写权限验证拦截器类的代码,具体代码如下

// 权限检查拦截器继承AbstractInterceptor类
public class AuthorityInterceptor
	extends AbstractInterceptor
{
	// 拦截Action处理的拦截方法
	public String intercept(ActionInvocation invocation)
		throws Exception
	{
		// 取得请求相关的ActionContext实例
		ActionContext ctx = invocation.getInvocationContext();
		Map session = ctx.getSession();
		// 取出Session里的user属性
		String user = (String)session.get("user");
		//如果没有登录,或者登录所用的用户名不是admin,都返回重新登录
		if (user != null && user.equals("admin") )
		{
			return invocation.invoke();
		}
		// 如果没有登录,将服务器提示放入ActionContext中
		ctx.put("tip" ,"您还没有登录,请输入管理员账号登录系统");
		// 返回login的逻辑视图
		return Action.LOGIN;
	}
}

        从上面的代码中可以看到,先通过ActionInvocation参数获取用户的Session实例的引用,然后从中取出user属性,通过判断该属性值来确定用户是否登录系统,从而判断是否需要转入登录页面。
        实现了上述的权限验证拦截器,就可以在配置文件中随意使用该拦截器对需要实现权限控制的Action进行配置,使之具有权限控制的功能。具体在struts.xml文件中如何定义和应用于Action中,请看如下具体配置:
<package name="lee" extends="struts-default">
		<!-- 用户拦截器定义在该元素下 -->
		<interceptors>
			<!-- 定义了一个名为authority的拦截器 -->
			<interceptor name="authority" 
				class="org.ljw.app.interceptor.AuthorityInterceptor"/>
		</interceptors>

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

		<action name="login" class="org.ljw.app.action.LoginAction">
			<result name="error">/WEB-INF/content//error.jsp</result>
			<result>/WEB-INF/content/welcome.jsp</result>
		</action>
		<!-- 定义一个名为viewBook的Action,其实现类为ActionSupport -->
		<action name="viewBook">
			<!-- 返回success视图名时,转入viewBook.jsp页面 -->
			<result>/WEB-INF/content/viewBook.jsp</result>
			<interceptor-ref name="defaultStack"/>
			<!-- 应用自定义拦截器 -->
			<interceptor-ref name="authority"/>
		</action>
		<action name="*">
			<result>/WEB-INF/content/{1}.jsp</result>
		</action>
	</package>
上面名为viewBook的Action,没有指定class属性,默认使用ActionSupport类,配置该Action时,只指定了一个结果映射,指定系统返回success字符串时,系统将转入viewBook页面,但并未配置login视图名对应的jsp页面。
        考虑到该拦截器的复用性问题,系统可能每个页面都需要进行权限控制,因此可以将login的结果映射定义为全局结果映射,具体配置方法看上面代码。如果要简化struts.xml文件的配置量,避免在每个Action中重复配置该拦截器,可以将该拦截器与Struts2默认的拦截器栈放在一起,定义成新的默认拦截器栈mydefaultstack,这样就不用在每个Action中重复定义权限验证拦截器了,默认已有,这体现了抽象—>封装的思想,跟我们编写代码时遇到重复代码就抽出来进行封装复用是一个道理。
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:306723次
    • 积分:11687
    • 等级:
    • 排名:第1349名
    • 原创:150篇
    • 转载:6篇
    • 译文:1篇
    • 评论:2140条
    公告
    在技术的海洋里遨游是一件十分有趣的事情,欢迎各位技术达人与我一同探讨,技术,职业,人生……
    博客专栏
    最新评论