小编典典

使用拦截器来验证用户访问权限

java

我正在尝试使用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>

为什么是sessionnull以及如何解决?

是我使用的参考。)


阅读 174

收藏
2020-09-28

共1个答案

小编典典

Struts Session只是Map<String,Object>底层的包装HttpSession

虽然实现SessionAware接口是在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">
2020-09-28