简体   繁体   English

验证登录页面时,Struts2拦截器会话获取空值

[英]Struts2 interceptor session get null value when authenticate login page

I am a beginner in Struts2 and I'm trying to do this scenario on my own web project : 我是Struts2的初学者,我正在尝试在自己的Web项目中进行以下操作:

  • When user access login page, server will authenticate whether that he/she has login as "admin" / "user" by accessing the session using interceptor, If the user has no privilege data (it's null) inside the session, they will be passed to login page. 当用户访问登录页面时,服务器将通过使用拦截器访问会话来验证他/她是否以“ admin” /“ user”身份登录。如果用户在会话中没有特权数据(它为null),则将通过登录页面。
  • If the user has login as "admin", user will be redirected to "admin" page. 如果用户以“ admin”身份登录,则用户将被重定向到“ admin”页面。
  • If the user has login as "user", user will be redirected to "user" page. 如果用户以“用户”身份登录,则该用户将被重定向到“用户”页面。

I was trying these codes, If i don't use interceptor, I can access the session, but if i use the interceptor what I get is, the session is still null and giving error 500 instead with NPE. 我正在尝试这些代码,如果我不使用拦截器,则可以访问该会话,但是如果使用拦截器,则该会话仍然为 ,并使用NPE给出错误500。 I don't know what is wrong with it. 我不知道这是怎么回事。

Thanks for any of you who help me. 谢谢任何帮助我的人。

struts.xml 在struts.xml

<struts>
    <constant name="struts.action.extension" value=","/>
    <constant name="struts.custom.i18n.resources" value="global" />
    <constant name="struts.devMode" value="true" />
    <!-- Configuration for the default package. -->
    <include file="strutsconf/struts-user.xml"/>

</struts>

struts-pageauth.xml 在struts-pageauth.xml

<struts>
    <package name="struts-pageauth" namespace="/" extends="struts-default">
        <interceptors>

            <interceptor name="loginpageauth" class="control.intercept.UserAuthenticationLogin"/>

            <interceptor-stack name="loginauth">
                <interceptor-ref name="createSession"/>
                <interceptor-ref name="loginpageauth"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>

        </interceptors>
    </package>
</struts>

strusts-user.xml strusts-user.xml

<struts>
    <constant name="struts.custom.i18n.resources" value="prop-user" />

    <include file="strutsconf/struts-pageauth.xml"/>

    <package name="struts-user" namespace="/" extends="struts-default, struts-pageauth">

        <action name="login" method="login" class="control.action.Login">

            <interceptor-ref name="loginauth"/>
            <result name="admin">/main/admin/Admin.jsp</result>
            <result name="user">/main/user/User.jsp</result>
            <result name="error">/Login.jsp</result>
        </action>

        <action name="logout" method="logout" class="control.action.Login">
            <result name="success">/Login.jsp</result>
            <result name="error">/Login.jsp</result>
        </action>

    </package>
</struts>

UserAuthenticationLogin.java UserAuthenticationLogin.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control.intercept;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.Interceptor;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;

public class UserAuthenticationLogin extends ActionSupport implements SessionAware, Interceptor {

    public void setSession(Map<String, Object> map) {
        this.sessionMap = map;
    }

    public void destroy() {
        System.out.println("UserAuthentication Interceptor destroy() called");
    }

    public void init() {
        System.out.println("UserAuthentication Interceptor init() called");
    }

    public String intercept(ActionInvocation ai) throws Exception {
        System.out.println("=========================DEBUG========================");
        System.out.println("UserAuthentication Interceptor intercept() called");
        System.out.println(getText("auth.privilage")); // I can access this properties
        System.out.println(this.sessionMap); // It gets NULL ??
//        System.out.println(this.sessionMap.get(getText("auth.privilage")));
        if(this.sessionMap.get(getText("auth.privilage"))==null) {
            return ai.invoke();
        }
        else if(this.sessionMap.get(getText("auth.privilage")).equals("admin")) {
            return "admin";
        }
        else if(this.sessionMap.get(getText("auth.privilage")).equals("user")) {
            return "user";
        }
        else {
            return "login";
        }
    }

    private String id;
    private String password;
    private String admin;
    private Map<String, Object> sessionMap;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAdmin() {
        return admin;
    }

    public void setAdmin(String admin) {
        this.admin = admin;
    }

    public Map<String, Object> getSessionMap() {
        return sessionMap;
    }

    public void setSessionMap(Map<String, Object> sessionMap) {
        this.sessionMap = sessionMap;
    }
}

Login.java Login.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control.action;

import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;

public class Login extends ActionSupport implements SessionAware {

    public void setSession(Map<String, Object> map) {
        this.sessionMap = map;
    }

    public String login() throws Exception {
        if(id.equals("admin") && password.equals("admin")) {
            this.sessionMap.put("id", "admin");
            this.sessionMap.put("priv", "admin");
            return "admin";
        }
        if(id.equals("user") && password.equals("user")) {
            this.sessionMap.put("id", "user");
            this.sessionMap.put("priv", "user");
            return "user";
        }
        else {
            setErr_msg(super.getText("error.login"));
            return super.ERROR;
        }
    }

    public String logout() throws Exception {
        this.sessionMap.remove("id");
        this.sessionMap.remove("priv");
        return super.SUCCESS;
    }

    private String id;
    private String password;
    private String err_msg;
    private String admin;
    private Map<String, Object> sessionMap;

    public Map<String, Object> getSessionMap() {
        return sessionMap;
    }

    public void setSessionMap(Map<String, Object> sessionMap) {
        this.sessionMap = sessionMap;
    }

    public String getAdmin() {
        return admin;
    }

    public void setAdmin(String admin) {
        this.admin = admin;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getErr_msg() {
        return err_msg;
    }

    public void setErr_msg(String err_msg) {
        this.err_msg = err_msg;
    }

}

The sessionMap is injected by ServletConfigInterceptor in Actions implementing the SessionAware interface, not Interceptors. sessionMap是由ServletConfigInterceptor在实现SessionAware接口的Actions中注入的,而不是Interceptor。

The right way to get the Session Map in an Interceptor is: 在拦截器中获取会话映射的正确方法是:

Map<String, Object> session = ActionContext.getContext().getSession();

Note: be careful in messing with Actions and Interceptors together: it's strange to see an Interceptor implementing ActionSupport... It's not a problem with your code because you are using declarative xml configuration, but Convention Plugin would scan the packages (luckily you have a package with an unmatching name) for classes extending ActionSupport and would detect it as an Action, making it ThreadLocal, that is not what an Interceptor has meant to be. 注意:要小心地将Actions和Interceptor混在一起:看到一个Interceptor实现了ActionSupport是很奇怪的。您的代码没有问题,因为您使用的是声明性xml配置,但是Convention Plugin会扫描软件包(幸运的是,您有包(具有不匹配的名称)),用于扩展ActionSupport的类,并将其检测为Action,使其成为ThreadLocal,这并不是Interceptor的本意。 Then you have to remember to be careful upgrading your code in the future to avoid unexpected result. 然后,您必须记住以后要小心升级代码,以免发生意外结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM