使用Interceptor验证用户访问权限

时间:2014-12-30 08:21:49

标签: java struts2 interceptor

我正在尝试使用Interceptor来限制用户执行某些操作。

ContainsKeyInterceptor

public class ContainsKeyInterceptor extends AbstractInterceptor implements SessionAware {
    private static final long serialVersionUID = 1L;

    private Map<String, Object> session;

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        if(session == null) {
            System.out.println("session is null");
        }

        if(session.containsKey("currentId")) {
            return "index";
        }

        String result = actionInvocation.invoke();

        return result;
    }

    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }
}

如果在currentId中找到session,则应将用户重定向到索引页。

但是,我收到NullPointerException,说session为空,正如if-check验证的那样。

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.devMode" value="false" />

    <!-- actions available to guests -->
    <package name="guest" extends="struts-default">
        <interceptors>
            <interceptor name="containskeyinterceptor" class="com.mypackage.interceptor.ContainsKeyInterceptor" />
        </interceptors>

        <action name="index" class="com.mypackage.action.IndexAction">
            <interceptor-ref name="containskeyinterceptor" />
            <result type="redirect">/index.jsp</result>
            <result name="index" type="redirect">/index.jsp</result>
        </action>

        <action name="login" class="com.mypackage.action.LoginAction">
            <interceptor-ref name="containskeyinterceptor" />
            <result type="redirect">/index.jsp</result>
            <result name="input">/login.jsp</result>
            <result name="index" type="redirect">/index.jsp</result>
        </action>       
    </package>

    <!-- actions available to members -->
    <package name="member" extends="struts-default">
        <action name="logout" class="com.mypackage.action.LogoutAction">
            <result type="redirectAction">
                <param name="actionName">index</param>
            </result>
        </action>
    </package>
</struts>

为什么session为空以及如何解决?

This是我使用的参考。)

2 个答案:

答案 0 :(得分:2)

基于this我不认为拦截器本身可以/需要能够识别会话。

您可以这样访问此媒体资源:

final ActionContext context = actionInvocation.getInvocationContext();  
this.session = context.getSession();  

可能有一种方法可以自动获取此设置,我对struts2不太熟悉,但可能是sessionaware仅适用于特定的对象子集,而且由于某种原因,这个拦截器不是其中之一。 (未被扫描,被排除在扫描之外,类型错误)

答案 1 :(得分:2)

Struts Session只是Map<String,Object>包装基础HttpSession

在实现SessionAware接口is the correct way to get it in an Action时,如果要从Interceptor中获取它,则需要执行以下操作:

获取Struts 会话地图

@Override
public String intercept(ActionInvocation ai) throws Exception {
    final ActionContext context = ai.getInvocationContext();

    // Struts Session
    Map<String, Object> session = context.getSession();

获取真正的 HttpSession对象

@Override
public String intercept(ActionInvocation ai) throws Exception {
    final ActionContext context = ai.getInvocationContext();

    HttpServletRequest request = (HttpServletRequest)context.get(StrutsStatics.HTTP_REQUEST);

    // Http Session
    HttpSession session = request.getSession();

那就是说,你在动作中没有获得会话(也没有任何其他参数,对象等)的原因是因为你遇到了一个常见的错误:只应用一个拦截器(你的)而不是应用整个拦截器堆栈(应该包含你的):

您可以在每个操作中定义两次:

<action name="login" class="ph.edu.iacademy.action.LoginAction">
    <interceptor-ref name="defaultStack" /> <!-- this is missing -->
    <interceptor-ref name="containskeyinterceptor" />

或更好的是,在自定义堆栈中定义一次,并始终使用堆栈:

<interceptors>
    <interceptor-stack name="yourStack">                
       <interceptor-ref name="defaultStack"/>
       <interceptor-ref name="containskeyinterceptor"/>
    </interceptor-stack>
</interceptors>

<action name="login" class="ph.edu.iacademy.action.LoginAction">
    <interceptor-ref name="yourStack" />

并最终使用default-interceptor-ref定义它,以避免为该包的每个操作配置写入它:

<default-interceptor-ref name="yourStack"/>

<action name="login" class="ph.edu.iacademy.action.LoginAction">