SSH进阶(2)——用Struts拦截器实现登陆限制

  

  拦截器从字面意思来看就是限制。限制用户訪问某些网页。在Action提出请求之前用拦截器来做权限设置,让符合的用户跳入对应的界面中。近期做的一个商城项目中就用到了自己定义的拦截器,实现了一个简单的session推断。成功就登陆,不成功就跳转到门户。

 


【拦截器工作原理】


       Struts2拦截器是在訪问某个Action或Action的某个方法。字段之前或之后实施拦截,而且Struts2拦截器是可插拔的。拦截器是AOP的一种实现。AOP为Aspect Oriented Programming的缩写。意为:面向切面编程。通过预编译方式和执行期动态代理实现程序功能的统一维护的一种技术。

利用AOP能够对业务逻辑的各个部分进行隔离。从而使得业务逻辑各部分之间的耦合度减少,提高程序的可重用性,同一时候提高了开发的效率。

   我的理解是每个action请求都会在拦截器的内部,当发生请求的时候,Struts会找相应的配置文件。实例化相应的拦截器对象,如设置拦截器属性excludeMethods。

非常类似于过滤器的。可是过滤器的范围要大于拦截器。




【创建拦截器】


  第一种方法就是直接实现Interceptor接口。这种话,有个弊端。这里面的init()  destroy()  intercept()  方法都须要实现了。



  另外一种方法是继承自AbstractInterceptor抽象类。实现了Interceptor接口,而且对里面的init()和destroy()方法进行空实现,而把intercept()方法设置为抽象方法,让继承它的子类去实现,这种话。子类仅仅要实现这个intercept()方法就能够了。比上面的简单。


  第三种方法是继承自MethodFilterInterceptor(我以下就是用这种方法实现的),这个类叫做方法过滤拦截器,MethodFilterInterceptor继承自AbstractInterceptor,而且提供了一种机制,即能够指定对Action中某些方法进行拦截或者是不拦截,所谓拦截不拦截。指的就是拦截器中的intercept()方法是否被运行了,若没有运行,就是没有拦截,若运行了,就是拦截了。


  总的来说,相比之前的接口和抽象类,最后一个仅仅须要指定对Action中某些方法进行拦截是最简单的。

是通过includeMethods和excludeMethods这两个參数来设置那个方法须要拦截的,在Struts.xml中进行配置。


【拦截器实现登陆】


1>首先我们要自己定义一个拦截器类:


package cn.itcast.shop.interceptor;
import org.apache.struts2.ServletActionContext;
import cn.itcast.shop.adminuser.vo.AdminUser;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
/**
 * interceptor
 * @author Zhouzhou
 * @date 2016-1-25
 * @time 下午09:48:21
 */
/**
 * that class want to judge the session is null。it extends the class named : MethodFilterInterceptor,
 */
public class PrivilegeInterceptor extends MethodFilterInterceptor{
    
    /**
     * the method doIntercept is the main method of the MethodFilterInterceptor
     */
    @Override
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
        //judge login
        //
        AdminUser adminUser = (AdminUser) ServletActionContext.getRequest()
                .getSession().getAttribute("existAdminUser");
        if(adminUser != null){
            // is logined ,have the userinfo in the session
            return actionInvocation.invoke();
        }else{
            // is not login
            ActionSupport support = (ActionSupport) actionInvocation.getAction();
            support.addActionError("You are not logged in!No permission to access!");
            return ActionSupport.LOGIN;
        }
    }
}


2>然后在配置文件里去注冊这个拦截器,并在后台登陆的action中利用excludeMethods这个成员变量来绑定login这种方法被拦截。


struts.xml
    <!-- Configure: registered place interceptor -->
        <interceptors>
            <interceptor name="privilegeInterceptor" class="cn.itcast.shop.interceptor.PrivilegeInterceptor"/>            
        </interceptors> 
    <!-- 后台登录Action -->
        <action name="adminUser_*" class="adminUserAction" method="{1}">
            <result name="loginFail">/admin/index.jsp</result>
            <result name="loginSuccess" type="redirect">/admin/home.jsp</result>
            <interceptor-ref name="privilegeInterceptor">
                <param name="excludeMethods">login</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"/>
        </action>  



3>然后是在login 这种方法被调用的时候,就去验证session是不是空的,来推断是否有这个username和password的匹配,然后放入了session中。


/**
     * login method--azz
     */
    public String login() {
        User existUser = userService.login(user);
        // use the username and pwd check the user is exist
        if (existUser == null) {
            //login fail
            this.addActionError("error。your user or pwd is error, please login again...");
            return LOGIN;
        } else {
            // login success
            // set the user information into the session
            ServletActionContext.getRequest().getSession()
                    .setAttribute("existUser", existUser);
            // goto the struts.xml ↓
            //<result name="loginSuccess" type="redirect">/admin/home.jsp</result>
            return "loginSuccess";
        }
    
    } 


  这样一来就轻松实现了用户登陆时候,session是否为空的推断了。



【总结】


 1.拦截器定义了一种机制,能够让开发定义一些代码在action运行之前&后运行。


 2.提高了代码的复用。想想我们开发asp.net的时候总是写上if(session["username"]==null)之类的话在if(!Page。

ispostback)里面。

每一个页面都有去推断session。

在我们有了这个拦截器之后呢,我们仅仅须要在每一个action配置里面写上:

	<interceptor-ref name="拦截器名称"/>
        <interceptor-ref name="defaultStack"/>

这样就攻克了全部页面的权限验证问题了。

 

 3.当中includeMethods和excludeMethods是来决定这个action里面的方法是否须要被拦截。


posted @ 2017-07-06 19:37  llguanli  阅读(282)  评论(0编辑  收藏  举报