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
我对这个代码/配置有很多评论,有些是微不足道的,有些则不是.
创建自己的会话是没有理由的; 别.
在动作配置中声明拦截器时,必须声明所有拦截器.配置时,只运行会话拦截器menuAction.
这意味着不会填充任何参数,因为没有其他拦截器正在运行.
通常,仅用于SessionAware访问会话.有非常很少需要直接访问请求.
显然,拦截器没有"将请求设置为null",这甚至没有意义.
我不知道你LoginAction应该做什么.有什么意图像线setServletRequest(request);或setSession(session, user);?这两条看起来不正确的线条没什么.
命名您的成功和错误的结果只是,"success"和"error"(小写),如果你要使用ActionSupport.SUCCESS和ActionSupport.ERROR常量.如果您没有在此代码中使用这些常量,我建议您使用其他名称,因为它会让任何实际使用过Struts 2的人感到困惑.
发布代码示例时,请删除不相关的内容.特别是当您没有明确设置语法突出显示时,它会使事情变得更加难以阅读.
不要使用代码if (isValidUser == true),使用if (isValidUser).
注意你的条件:像if (user == null) ... else if (user != null) ... else ...零感一样的东西.用户为空,或者不是:没有第三个选项.
避免使用不必要的,令人困惑的逻辑,比如User currentUser = (User) (mapSession.get("User") == null ? null : mapSession.get("User"));基本上说"如果它为null,请使用null,否则返回刚刚获得的值,但再次获取它." 为什么???
像这样User user = null; // To store current user的评论完全没有价值.是不是很明显是什么User user?一个用户.不够明显?怎么样User currentUser???
将复数(例如,集合)命名为复数.列表中的类别名称映射不是单个类别.
不要将变量声明远离它们使用的地方; 这很令人困惑.
将JSP页面置于WEB-INF某个地方以禁止直接客户端访问.
避免不必要的语言结构,比如if分支返回时,else不是绝对必要的,而IMO则会增加噪声.同样,一旦你知道你正在回来,就考虑回来.后者更具争议性,但我认为人们已经开始意识到在短方法中有多个返回点是可以的,而且IMO更容易思考.
用较少的代码来说话.创建一些小实用程序方法来包含简单的功能,因此它不会污染主线代码.
几乎从不使用动作链.
还有更多,但现在已足够了.这是清理过的实际相关代码.其中一些实际上并不相关,但无论如何我都把它留了下来.
<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)