Struts2使用拦截器处理会话超时 [英] Struts2 handle session timeout using Interceptor

查看:189
本文介绍了Struts2使用拦截器处理会话超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用拦截器在我的struts2应用程序中处理会话超时请求.以下是与此相关的文件:

I am trying to handle session timeout requests in my struts2 application using an Interceptor. Below are the files related to this:

Web.xml:

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
    <session-timeout>1</session-timeout>
</session-config>

Struts.xml:

<package name="default" extends="struts-default">
<interceptors>
    <interceptor name="sessionInterceptor"
        class="com.platform.web.security.SessionInterceptor" />
</interceptors>
<action name="doLogin"
    class="com.platform.web.action.LoginAction">
    <result name="input">/login/login.jsp</result>
    <result name="error">/login/login.jsp</result>
    <result type="chain">menuAction</result>
</action>

<action name="menuAction"
    class="com.platform.web.action.MenuAction">
    <interceptor-ref name="sessionInterceptor"/> //Interceptor included here
    <result name="SUCCESS">/jsp/main.jsp</result>
    <result name="ERROR">/login/login.jsp</result>
    <result name="input">/jsp/myFavourite.jsp</result>
</action>

拦截器类别:

public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
/**
 * 
 */
private static final long serialVersionUID = 1L;

@Override
public String intercept(ActionInvocation invocation) throws Exception {

final ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context
    .get(HTTP_REQUEST);
HttpSession session = request.getSession(false);

// Is there a "user" object stored in the user's HttpSession?
//Object user = session.getAttribute("User");
if (session == null) {
    // The user has not logged in yet.

    // Is the user attempting to log in right now?
    //String loginAttempt = request.getParameter(LOGIN_ATTEMPT);

    /* The user is attempting to log in. */
    /*if (!StringUtils.isBlank(loginAttempt)) {
    return invocation.invoke();
    }*/
    return "timeout";
 } else {
    return invocation.invoke();
 }
 }
}

登录操作:

public class LoginAction extends MesActionSupport implements ServletRequestAware {
@Override
public String execute() throws Exception {
setActionNameForAudit("execute123");
FILE_LOGGER.debug("Entering into execute() ... ");
String strSessionId = "";

if (isValidUser == true) {
    user = getUser();

    strSessionId = request.getSession(true).getId();
    setServletRequest(request);
    session.put("SessionId", strSessionId);

    setSession(session, user);

    ServletActionContext.getRequest().getSession().setAttribute("User", user);

    FILE_LOGGER.debug("Exit from  LoginAction.execute() ... ");
    return SUCCESS;
} else {
    return ERROR;
}
 }

MenuAction:

public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
@Override
public String execute() throws Exception {
setActionNameForAudit("execute ");
User user = null; // To store current user
Map<String, ArrayList<String>> category = null; // To store all Menu
// Categories.
StringBuffer menu = new StringBuffer(""); // To store Menu String
StringBuffer dashboardMenu = new StringBuffer("");

// user = (User)(request.getSession().getAttribute("User")==null ? null : request.getSession().getAttribute("User")); //Request object IS NULL HERE!!
user = (User) (mapSession.get("User") == null ? null : mapSession
    .get("User")); // mapSession object IS NULL HERE
FILE_LOGGER.debug("user is " + user == null);

if (user != null) {
    menu = menuView.getMenu(user);
    mapSession.put("Menu", menu.toString());
    mapSession.put("dbMenu", dashboardMenu.toString());
    ret = "SUCCESS";
} else if (user == null) {
    ret = ERROR;
} else {
    ret = SUCCESS;
}
return ret;
}

流程是这样的: 1.登录屏幕打开 2.用户输入凭据并提交 3.调用LoginAction,对用户进行身份验证 4.如果有效用户-调用MenuAction.否则重定向到Login.jsp

Flow is like this: 1. Login screen opens 2. User enters credentials and submits 3. LoginAction is called, user is authenticated 4. If valid user - MenuAction is called. Else redirect to Login.jsp

根据上面的代码,会话在LoginAction中创建,控件到达Interceptor,在其中检查会话对象.如果会话存在,则控件到达MenuAction.

According to the above code, the session gets created in the LoginAction, control reaches the Interceptor where the session object is checked. If session exists the control reaches MenuAction.

但是,当发生这种情况时,request对象将重置为NULL!早些时候,当我不使用拦截器时,LoginAction和MenuAction之间的流程完全正常.

But when this happens, the request object gets reset to NULL! Earlier when I was not using an interceptor, the flow was working completely fine between LoginAction and MenuAction.

拦截器是否重置HTTPRequest?因此会议?结果是我无法继续.

Does the interceptor resets the HTTPRequest? and hence the Session? As a result I am not able to proceed.

有帮助吗?

推荐答案

我对此代码/配置有很多评论,有些琐碎,有些没有.

I have many comments on this code/configuration, some trivial, some not.

  1. 创建您自己的会话的原因为零;

  1. There's zero reason to create your own session; don't.

在动作配置中声明拦截器时,必须声明 all 拦截器.按照配置,仅 会话拦截器正在为menuAction运行.

When you declare an interceptor in an action configuration you must declare all interceptors. As configured, only the session interceptor is running for menuAction.

这意味着不会填充任何参数,因为没有其他拦截器正在运行.

That means no parameters will be filled, since no other interceptors are running.

通常,仅使用SessionAware来访问会话. 非常很少需要直接访问请求.

In general, only use SessionAware to access the session. There is very rarely a need to access the request directly.

很明显,拦截器不会将请求设置为null",甚至没有任何意义.

Obviously the interceptor doesn't "set the request to null", that doesn't even make sense.

我不知道您的LoginAction应该做什么. setServletRequest(request);setSession(session, user);等行的意图是什么?这两行看起来都没错.

I have no idea what your LoginAction is supposed to be doing. What's the intent of lines like setServletRequest(request); or setSession(session, user);? There's nothing about those two lines that look correct.

如果要使用ActionSupport.SUCCESSActionSupport.ERROR常量,则将成功和错误的结果命名为"success""error"(小写).如果您在代码中使用这些常量,我建议为其使用其他名称,因为这会使以前实际使用过Struts 2的人感到困惑.

Name your success and error results just that, "success" and "error" (lower case), if you're going to use the ActionSupport.SUCCESS and ActionSupport.ERROR constants. If you're not using those constants in this code, I'd recommend using other names for them, because it will confuse anybody that has actually used Struts 2 before.

发布代码示例时,请删除不相关的内容.尤其是当您没有明确设置语法高亮时,它会使内容很多更加难以阅读.

When posting code samples please remove stuff that isn't relevant. Particularly when you don't explicitly set syntax highlighting it makes things much more difficult to read.

请勿使用if (isValidUser == true)之类的代码,而应使用if (isValidUser).

Don't use code like if (isValidUser == true), use if (isValidUser).

请注意您的条件:if (user == null) ... else if (user != null) ... else ...之类的东西的含义为零.用户为null,否则为空:没有第三种选择.

Mind your conditionals: stuff like if (user == null) ... else if (user != null) ... else ... makes zero sense. The user is null, or it isn't: there's no third option.

避免不必要的,令人困惑的逻辑,例如User currentUser = (User) (mapSession.get("User") == null ? null : mapSession.get("User"));,该逻辑基本上说如果为null,则使用null,否则返回您刚得到的值,但再次获得它."为什么?

Avoid unnecessary, confusing logic, like User currentUser = (User) (mapSession.get("User") == null ? null : mapSession.get("User")); which basically says "If it's null, use null, otherwise return the value you just got, but get it again." WHY???

User user = null; // To store current user这样的注释是完全没有价值的. 显而易见是什么User user吗?一个用户.还不够明显? User currentUser ???

Comments like User user = null; // To store current user are completely worthless. Isn't it obvious what User user is? A user. Not obvious enough? How about User currentUser???

将复数形式(例如集合)命名为复数形式.类别名称到列表的映射不是单个类别.

Name plurals (e.g., collections) as something plural. A map of category names to lists isn't a single category.

不要在使用变量的地方声明变量;这非常令人困惑.

Don't declare variables far away from where they're used; it's very confusing.

将您的JSP页面放在WEB-INF下的某个位置,以禁止直接客户端访问.

Put your JSP pages under WEB-INF somewhere to disallow direct client access.

避免使用不必要的语言构造,例如当if分支返回时,else并非绝对必要,而IMO会增加噪音.同样,在您知道要返回时,请考虑立即返回.后者更具争议性,但我认为人们逐渐意识到可以在短方法中具有多个返回点是可以的,而IMO则更容易考虑.

Avoid unnecessary language constructs, like when an if branch returns, an else isn't strictly necessary, and IMO, it adds noise. Similarly, consider returning as soon as you know you're returning. The latter is a bit more controversial, but I think people are coming around to realizing it's okay to have multiple return points in short methods, and IMO it's easier to think about.

使用更少的代码说话.创建小的实用程序方法来包装琐碎的功能,以免污染主线代码.

Use less code to say things. Create little utility methods to wrap up trivial functionality so it doesn't pollute the mainline code.

几乎从不使用动作链接.

Use action chaining almost never.

还有更多,但到目前为止已经足够.这是实际的相关代码,已清理.其中一些实际上并不相关,但我还是把它留了下来.

There's more, but that's enough for now. Here's the actual relevant code, cleaned up. Some of it isn't actually relevant but I left it in anyway.

<filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<session-config>
  <session-timeout>1</session-timeout>
</session-config>

<package name="default" extends="struts-default">
  <interceptors>
    <interceptor name="sessionInterceptor" class="com.platform.web.security.SessionInterceptor" />
  </interceptors>

  <action name="doLogin" class="com.platform.web.action.LoginAction">
    <result name="input">/WEB-INF/jsp/login/login.jsp</result>
    <result name="error">/WEB-INF/jsp/login/login.jsp</result>
    <result type="redirectAction">menuAction</result>
  </action>

  <action name="menuAction" class="com.platform.web.action.MenuAction">
    <interceptor-ref name="sessionInterceptor"/>
    <result name="success">/WEB-INF/jsp/main.jsp</result>
    <result name="input">/WEB-INF/jsp/myFavourite.jsp</result>
  </action>

 public class SessionInterceptor extends AbstractInterceptor implements StrutsStatics {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
        HttpSession session = request.getSession(false);

        // session will almost *never* be null. Check for a valid user object.
        if (session == null) {
            return "timeout";
        }

        return invocation.invoke();
    }
}

public class LoginAction extends MesActionSupport implements ServletRequestAware {
    @Override
    public String execute() throws Exception {
        if (!isValidUser) {
            return ERROR;
        }

        user = getUser();

        String strSessionId = request.getSession(true).getId();
        setServletRequest(request);
        session.put("SessionId", strSessionId);

        setSession(session, user);

        ServletActionContext.getRequest().getSession().setAttribute("User", user);

        return SUCCESS;
    }
}

public class MenuAction extends MesActionSupport implements SessionAware, ParameterAware, RequestAware {
    @Override
    public String execute() throws Exception {
        User currentUser = (User) mapSession.get("User");
        if (currentUser == null) {
            return ERROR;
        }

        Map<String, List<String>> categories; // Left in for naming.

        StringBuffer menu = menuView.getMenu(user);
        mapSession.put("Menu", menu.toString());

        StringBuffer dashboardMenu = new StringBuffer("");
        mapSession.put("dbMenu", dashboardMenu.toString());

        return SUCCESS;
    }
}

这篇关于Struts2使用拦截器处理会话超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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