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