使用Interceptor验证用户访问权限 [英] Using Interceptor to validate user access privilege

查看:126
本文介绍了使用Interceptor验证用户访问权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use an Interceptor to restrict users from performing certain actions.

ContainsKeyInterceptor

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 会话中找到

It is supposed to redirect the user to the index page if currentId is found in the session.

但是,我得到一个 NullPointerException ,说 session 为null,由if-check验证。

However, I am getting a NullPointerException, saying session is null, as verified by the if-check.

struts.xml

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>

为什么会话 null以及如何解决?

Why is the session null and how to resolve?

是我使用的参考。)

推荐答案

Struts会话只是一个 Map< String,Object> 包装底层的 HttpSession

Struts Session is just a Map<String,Object> wrapping the underlying HttpSession.

实现SessionAware接口时是在动作中获取它的正确方法,如果你想从拦截器中获取它,你需要执行以下操作:

While implementing the SessionAware interface is the correct way to get it in an Action, if you want to get it from within an Interceptor, you need to do the following:

获取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();

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

That said, the reason you are not getting session (nor any other parameter, object and so on) in your Actions, is because you are falling in a common mistake: applying only one Interceptor (your) instead of applying an entire Interceptor Stack (that should contain your):

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

You can define it twice in every action:

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

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

or, much better, define it once in a custom stack, and use always the stack:

<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定义它以避免为该包的每个操作配置写入它:

and eventually define it with default-interceptor-ref to avoid writing it for every action config of that package:

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

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

这篇关于使用Interceptor验证用户访问权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆