Struts2使用Interceptor处理会话超时

Dar*_*Fan 1 session struts2 httprequest session-timeout interceptor

我试图使用Interceptor处理我的struts2应用程序中的会话超时请求.以下是与此相关的文件:

web.xml中:

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
    <session-timeout>1</session-timeout>
</session-config>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

拦截器类:

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();
 }
 }
}
Run Code Online (Sandbox Code Playgroud)

在LoginAction:

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;
}
 }
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

有帮助吗?

Dav*_*ton 16

我对这个代码/配置有很多评论,有些是微不足道的,有些则不是.

  1. 创建自己的会话是没有理由的; 别.

  2. 在动作配置中声明拦截器时,必须声明所有拦截器.配置时,运行会话拦截器menuAction.

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

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

  5. 显然,拦截器没有"将请求设置为null",这甚至没有意义.

  6. 我不知道你LoginAction应该做什么.有什么意图像线setServletRequest(request);setSession(session, user);?这两条看起来不正确的线条没什么.

  7. 命名您的成功和错误的结果只是,"success""error"(小写),如果你要使用ActionSupport.SUCCESSActionSupport.ERROR常量.如果您没有在此代码中使用这些常量,我建议您使用其他名称,因为它会让任何实际使用过Struts 2的人感到困惑.

  8. 发布代码示例时,请删除不相关的内容.特别是当您没有明确设置语法突出显示时,它会使事情变得更加难以阅读.

  9. 不要使用代码if (isValidUser == true),使用if (isValidUser).

  10. 注意你的条件:像if (user == null) ... else if (user != null) ... else ...零感一样的东西.用户为空,或者不是:没有第三个选项.

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

  12. 像这样User user = null; // To store current user的评论完全没有价值.是不是很明显是什么User user?一个用户.不够明显?怎么样User currentUser???

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

  14. 不要将变量声明远离它们使用的地方; 这很令人困惑.

  15. 将JSP页面置于WEB-INF某个地方以禁止直接客户端访问.

  16. 避免不必要的语言结构,比如if分支返回时,else不是绝对必要的,而IMO则会增加噪声.同样,一旦你知道你正在回来,就考虑回来.后者更具争议性,但我认为人们已经开始意识到在短方法中有多个返回点是可以的,而且IMO更容易思考.

  17. 用较少的代码来说话.创建一些小实用程序方法来包含简单的功能,因此它不会污染主线代码.

  18. 几乎从不使用动作链.

还有更多,但现在已足够了.这是清理过的实际相关代码.其中一些实际上并不相关,但无论如何我都把它留了下来.


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

<session-config>
  <session-timeout>1</session-timeout>
</session-config>
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
 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();
    }
}
Run Code Online (Sandbox Code Playgroud)
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;
    }
}
Run Code Online (Sandbox Code Playgroud)
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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 挖掘彻底! (3认同)