欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

struts2 拦截器实现登录权限控制

程序员文章站 2022-05-28 15:33:23
...

使用struts2的拦截器实现简单的登录权限拦截,非常简单。

首先在登录action给session设置username或者其他表示登录用户的值,作为在拦截器中判断是否登录的根据。

比如我的loginAction,重点是session.put("username", thisUser.getUsername());在session中这是一个username的值为当前登录用户的用户名。只要在拦截器中判断session中的username是否为空就可以判断是否登录了。

public String login() throws Exception {
        //查出数据库中此用户
        User thisUser = (User) beanDao.getBean(user);
        if(thisUser != null)
        {
            String md5Pass = Md5Util.getMD5Str(user.getPassword());
            if (md5Pass.equals(thisUser.getPassword())) {
                session.put("username", thisUser.getUsername());
                session.put("id", thisUser.getId());
                return SUCCESS;
            } else {
                addActionMessage("密码错误!");
                return ERROR;
            }
        } else {
            addActionMessage("该用户未注册!");
            return ERROR;
        }
    }

然后编写拦截器,在这里如果用户没有登录返回一个Action.LOGIN,它是struts中预置的一个字符串即“login”,如同ERROR值为error一样,所以你可以返回任何你自定义的逻辑视图名。

...
public class LoginInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        ActionContext ctx = actionInvocation.getInvocationContext();
        Map session = ctx.getSession();
        String user = (String) session.get("username");
        //登录名不为空则为已登录
        if (user != null) {
            //执行原Action
            return actionInvocation.invoke();
        }
        ctx.put("tip", "请先登录");
        return Action.LOGIN;
    }
}

因为用户未登录时拦截器返回login(即Action.LOGIN的值),所以需要在action中定义一个名为login的result,最好定义为全局rsult,如下

        <global-results>
            <result name="login">index.jsp</result>
        </global-results>

至于这个全局result在哪个包中,需要根据你的拦截范围确定,可以放在父级包中被继承,需要登录验证的放在一个继承自它所在包的包中,不需要拦截的action所在的包不要继承这个包。

 

然后就要在xml中注册拦截器了,在每个action中都引用这个拦截器不符合代码复用,所以定义成一个拦截器栈,然后在需要拦截的包中经这个栈定义为默认拦截器就可以了,这里需要注意的是,最好将默认的拦截器栈 defaultStack定义在你的拦截器后面,因为有一些像输入校验的拦截器在这个默认拦截器栈用,而struts2的拦截器执行顺序又取决于你的注册顺序,所以那些进行输入校验的视图会首先执行输入校验拦截器,它会提前返回input退出,而不是你希望的自定义拦截器中的结果,因为它根本在后面没有执行,所以最好放在defaultStack之前

<interceptors>
    <interceptor name="loginJudge" class="com.hims.interceptor.LoginInterceptor">                        </interceptor>
    <!--定义默认拦截器栈-->
    <interceptor-stack name="himsDefault">
       <interceptor-ref name="loginJudge"></interceptor-ref>
       <interceptor-ref name="defaultStack"></interceptor-ref>
    </interceptor-stack>
</interceptors>

在需要拦截的包中

    <package name="page" namespace="/" extends="default">
        <!--使用默认拦截器栈-->
        <default-interceptor-ref name="himsDefault"></default-interceptor-ref>
        ...
    </package>

这样便可以实现简单的登录拦截了。