java struts 2 使用拦截器完成权限控制

来源:互联网 发布:网络机房改造方案 编辑:程序博客网 时间:2024/05/16 17:22

java struts 2 使用拦截器完成权限控制

    博客分类: 
  • Struts2.0
JavaStruts应用服务器浏览器JSP

这段时间在学习一本新书——《struts2权威指南》(李刚著),现在看到“使用拦截器完成权限控制”,就仿照着做了一个例子,以巩固知识。如下: 

1 实现权限控制拦截器 
本示例应用要求用户登陆,且必须为指定用户名才可以查看系统中某个视图资源;否则,系统直接转入登陆页面。对于上面的需求,可以在每个Action的执行实际处理逻辑之前,先执行权限检查逻辑,但这种做法不利于代码复用。因为大部分Action里的权限检查代码都大同小异,故将这些权限检查的逻辑放在拦截器中进行将会更加优雅。 

检查用户是否登陆,通常都是通过跟踪用户的Session来完成的,通过ActionContext即可访问到Session中的属性,拦截器的intercepte(ActionInvocation invocation)方法的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(); 
//取出名为user的Session属性 
String user = (String)session.get("user"); 
//如果没有登陆,或者登陆所用的用户名不是scott,都返回重新登陆 
if (user != null && user.equals("scott") ) 

return invocation.invoke(); 

//没有登陆,将服务器提示设置成一个HttpServletRequest属性 
ctx.put("tip" , "您还没有登陆,请输入scott,tiger登陆系统"); 
//直接返回login的逻辑视图 
return Action.LOGIN; 
    } 

上面拦截器代码非常简单,先通过ActionInvocation参数取得用户的Session实例的引用,然后从中取出user属性,通过判断该属性值来确定用户是否登陆系统,从而判断是否需要转入登陆页面。 

package articles.action.interceptor; 
import java.util.Map; 
import articles.domain.User; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 
@SuppressWarnings("serial") 
public class SessionInterceptor extends AbstractInterceptor { 
private static final Object LOGIN_KEY = "user"; 
public static final String LIGIN_PAGE = "loginPage"; 
@SuppressWarnings("unchecked") 
@Override 
public String intercept(ActionInvocation actionInvocation) throws Exception { 
  // TODO Auto-generated method stub 
  Map session = actionInvocation.getInvocationContext().getSession(); 
  User user = (User) session.get(LOGIN_KEY); 
  if(user != null) 
   return actionInvocation.invoke(); 
  return LIGIN_PAGE; 



2 配置权限控制拦截器 

注意:默认拦截器是在不设置任何拦截器的时候,给予默认设置的,当只要设置任何一个拦截器就会覆盖掉默认拦截器, 
故此,我们需要手动设置 

一旦实现了上面的权限检查拦截器,就可以在所有需要实现权限控制的Action中复用上面的拦截器。 
为了使用该拦截器,首先在struts.xml文件中定义该拦截器,定义拦截器的配置片段如下: 
<!-- 用户拦截器定义在该元素下 --> 
<interceptors> 
<!-- 定义了一个名为authority的拦截器 --> 
<interceptor name="authority" class="lee.AuthorityInterceptor"/> 
</interceptors> 
定义了该拦截器之后,可以在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> 

上面名为viewBook的Action,没有指定class属性,默认使用ActionSupport类,配置该Action时,只是指定了一个Result,指定返回success字符串时,系统将转入/WEB-INF/jsp/viewBook.jsp页面。但并为未配置login视图对应的JSP页面。 
考虑到这个拦截器的重复使用,可能在多个Action都需要跳转到login逻辑试图,故将login Result定义成一个全局Result。下面是配置login Result的配置片段: 
<!-- 定义全局Result --> 
<global-results> 
<!-- 当返回login视图名时,转入/login.jsp页面 --> 
<result name="login">/login.jsp</result> 
</global-results> 

经过上面的配置,如果浏览者在浏览器中直接发送viewBook请求,将会转入如图所示的页面。 
这种通过拦截器进行权限控制的方式,显然具有更好的代码复用。 
如果为了简化struts.xml文件的配置,避免在每个Action中重复配置该拦截器,可以将该拦截器配置成一个默认拦截器栈(这个默认拦截器栈应该包括default-stack拦截器栈和权限检查拦截器)。 
定义自己的默认拦截器栈的配置片段如下: 
<interceptors> 
<!-- 定义权限检查拦截器 --> 
<interceptor name="authority" class="lee.AuthorityInterceptor"/> 
<!-- 定义一个包含权限检查的拦截器栈 --> 
<interceptor-stack name="mydefault"> 
<!-- 定义拦截器栈包含default-stack拦截器栈 --> 
<interceptor-ref name="default-stack"/> 
<!-- 定义拦截器栈包含authority拦截器 --> 
<interceptor-ref name=" authority"/> 
</interceptor- stack > 
</interceptors> 

一旦定义了上面的mydefault拦截器栈,这个拦截器栈包含了权限检查拦截器和系统默认的拦截器栈。如果将这个拦截器栈定义成默认拦截器,则可以避免在每个Action需要重复定义权限检查拦截器。 
下面是定义默认拦截器的配置片段: 
<default-interceptor-ref name="mydefault"/> 
一旦在某个包下定义了上面的默认拦截器栈,在该包下的所有Action都会自动增加权限检查功能。对于那些不需要使用权限控制的Action,将它们定义在另外的包中——这个包中依然使用系统原来的默认拦截器栈,将不会有权限控制功能。


http://yido5566.iteye.com/blog/340690