Сеанс перехватчика Struts2 получает нулевое значение при аутентификации страницы входа

Я новичок в Struts2, и я пытаюсь реализовать этот сценарий в своем собственном веб-проекте:

  • Когда пользователь получает доступ к странице входа в систему, сервер аутентифицирует, имеет ли он / она вход в систему как «администратор» / «пользователь», получая доступ к сеансу с помощью перехватчика. Если у пользователя нет данных о привилегиях (это значение null) внутри сеанса, они будут переданы на страницу входа.
  • Если пользователь имеет логин «admin», пользователь будет перенаправлен на страницу «admin».
  • Если пользователь имеет логин как «пользователь», пользователь будет перенаправлен на страницу «пользователь».

Я пробовал эти коды. Если я не использую перехватчик, я могу получить доступ к сеансу, но если я использую перехватчик, я получаю, что сеанс по-прежнему null и вместо этого выдает ошибку 500 с NPE . Я не знаю, что с ним не так.

Спасибо всем, кто мне помогает.

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>
    <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

<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

/*
 * 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;
    }
}

Логин.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;
    }

}

person poring91    schedule 27.06.2014    source источник
comment
Проверьте журналы сервера и опубликуйте трассировку стека.   -  person Roman C    schedule 27.06.2014


Ответы (1)


SessionMap внедряется ServletConfigInterceptor в действиях, реализующих интерфейс SessionAware, а не перехватчики.

Правильный способ получить карту сеанса в перехватчике:

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

Примечание: будьте осторожны, связываясь с действиями и перехватчиками вместе: странно видеть, что перехватчик реализует ActionSupport... Это не проблема с вашим кодом, потому что вы используете декларативную конфигурацию xml, но подключаемый модуль соглашения будет сканировать пакеты (к счастью у вас есть пакет с несовпадающим именем) для классов, расширяющих ActionSupport, и он обнаружит его как действие, сделав его ThreadLocal, а это не то, чем должен быть Interceptor. Затем вы должны помнить об осторожности при обновлении кода в будущем, чтобы избежать непредвиденных результатов.

person Andrea Ligios    schedule 27.06.2014
comment
спасибо за вашу помощь и совет, теперь это работает, но использовать ActionSupport.getText(name.of.properties.value) для доступа к значению внутри файла свойств, это нормально, если я создам объект ActionSupport вместо этого внутри метода перехвата? или есть ли лучший способ? - person poring91; 27.06.2014