1、问题
l 在使用具体workArea login后,系统会锁定该workArea,以防止相同workArea的再次login
l 但是,在具体workArea login后,可能会出现非正常退出,如中途转移到其它网站,由于没有执行logout,导致锁定的workArea没有释放,使其不可重用
l 因此,需要通过某种途径执行logout,释放锁定的workArea
2、解决思路
通过Session失效时执行workArea的logout
l 设置Session的失效时间(参看《在APC中使用Session》中配置)
l 使用Session变量监听器来监听Session变量的移除事件
l 在workArea login时(此时已经创建session),设置workArea值到Session变量中
l 当Session失效时,会移除Session变量,产生移除事件
l 在移除事件回调函数中,通过Session变量获得workArea值,进行logout
l 对于Session失效后的所有操作,都重定向到首画面
l 可以通过Session变量值为null来判断Session失效
3、辅助类
l SessionUtil:对Session变量进行存取操作
package com.fujitsu.eFrame.eftool;
import javax.servlet.http.HttpSession;
import com.fujitsu.uji.DispatchContext;
import com.fujitsu.uji.http.HttpSessionProfile;
public class SessionUtil {
private static HttpSession getSession(DispatchContext context) {
return ((HttpSessionProfile)context.getSessionProfile()).getSession();
}
public static Object getAttribute(DispatchContext context, String name) {
try {
return getSession(context).getAttribute(name);
} catch (IllegalStateException ex){
return null;
}
}
public static void setAttribute(DispatchContext context, String name, Object value) {
getSession(context).setAttribute(name, value);
}
public static void setTimeout(DispatchContext context, int seconds) {
getSession(context).setMaxInactiveInterval(seconds);
}
}
l SessionAttributeListener:Session变量监听器,用来监听Session变量的移除事件(需要配置监听器,参看《在APC中使用Session》)
package com.fujitsu.eFrame.eftool;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class SessionAttributeListener implements HttpSessionAttributeListener {
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.print(event.getName()+" added!");
System.out.println(" value = "+event.getValue());
}
public void attributeRemoved(HttpSessionBindingEvent event) {
if (event.getName().equals("workArea")) {
System.out.println("workArea removed!");
String workArea = (String) event.getValue();
System.out.println("workArea = "+workArea);
if (workArea != null) {
workSpaceInf wsi = workSpace.getInstance();
wsi.logOut(workArea);
}
}
}
public void attributeReplaced(HttpSessionBindingEvent event) {
}
}
4、具体实现
(1)在workArea login时,设置workArea值到Session变量workArea中
... // 保存workArea值到name变量中
SessionUtil.setAttribute(context, "workArea", name);
(2)对每个动作(除首页面,见后面叙述),判断Session是否失效,如果失效,就重定向到首页面(推荐将该功能用一个方法封装)
...
eft_0115Bean eft_0115Bean = new eft_0115Bean();
String workArea= (String) SessionUtil.getAttribute(context, "workArea");
if (workArea == null) {
String userName = "";
ListBox lb = eft_0115Bean.getDirlist();
workSpaceInf wsi = workSpace.getInstance();
wsi.firstWS();
while (!wsi.isLastWS())
{
if (!wsi.isWSUsed())
{
userName = wsi.getWSName();
lb.add(userName);
}
wsi.nextWS();
}
System.out.println("redirect to first page!");
eft_0115Bean.setVerb("reqmode");
context.setResponseBean("body", eft_0115Bean);
return;
}
...
(3)首画面的处理
由于首画面不涉及到workArea的login和logout,所以需要使用其它的Session变量来判断Session的失效
l 在startup()方法中设置Session变量
SessionUtil.setAttribute(context, "firstPage", "yes");
l 对首画面的所有动作,使用前面类似的方法判断Session是否失效,如果失效,就重定向到首页面,区别:
Ø Session变量为firstPage而不是workArea
Ø 在重定向前需要重新设置firstPage的值