平台默认提供的在线用户列表中没有记录用户登录的终端,因此要分别控制pc和mobile一个用户只能登录一次,需要自己记录用户登录的终端等信息
第一步:可以定义一个全局的map,在登录后把登录的用户名和终端作为key,登录产生的session做为value存储到map中
第二步:在登录前获取到当前登录的用户名和终端,判断map中是否有,如果有说明已经登录过了,可以抛出异常不让登录
第三步:当注销和session超时应该删除map中的信息,可以监听session失效实现
定义全局的map和监听session失效,可以在BusinessServer下创建servlet和listener实现,具体实现如下:
在\runtime\BusinessServer\WEB-INF下创建src
在src下创建servlet:/com/justep/user/OnLineMap.java,注意有包名目录/com/justep/user
package com.justep.user;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServlet;
public class OnLineMap extends HttpServlet {
//定义一个mapping存在登录者的相关信息
public static Map<String, Object> OnLineMaps = new HashMap<String, Object>();
}
创建listener:/com/justep/user/SessionListener.java,注意有包名目录/com/justep/user
package com.justep.user;
import java.util.Map.Entry;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionListener implements HttpSessionListener {
public void sessionDestroyed(HttpSessionEvent event) {
//session失效时获取map中value为此session的信息,并且map中删除
HttpSession session = event.getSession();
String user = "";
for (Entry<String, Object> entry : OnLineMap.OnLineMaps.entrySet()) {
HttpSession userSession = (HttpSession) entry.getValue();
if(session.equals(userSession)){
user = entry.getKey();
}
}
OnLineMap.OnLineMaps.remove(user);
}
public void sessionCreated(HttpSessionEvent arg0) {
// TODO 自动生成的方法存根
}
}
最终运行是执行的java编译的class文件,可以在studio中切换到java视图,然后把\runtime\BusinessServer导入
直接复制上面的java代码在WEB-INF/src上粘贴就可以生产对应的java类和对应的class文件
在\runtime\BusinessServer\WEB-INF\web.xml中配置servlet和listener
注意:servlet和listener的配置要放到平台默认配置的前面
如下,com.justep.x.loader.NativeLoaderListener这个配置就是平台默认的:
<listener>
<listener-class>com.justep.user.SessionListener</listener-class>
</listener>
<servlet>
<servlet-name>getOnLine</servlet-name>
<servlet-class>com.justep.user.OnLineMap</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>getOnLine</servlet-name>
<url-pattern>/getOnLine</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.justep.x.loader.NativeLoaderListener</listener-class>
</listener>
<listener>
登录后和登录前的操作可以在loginAction的执行前后事件中操作,通过扩展空间在/BIZ/SA_X/OPM/system/system.process.m的loginAction上添加事件
注意:事件默认生成的java的名字是System,需要自己修改一下名字,对应的procedure中配置的java的名字也需要修改,本案例用的是SystemTest
import java.util.Map;
import javax.servlet.http.HttpSession;
import com.justep.system.context.*;
import com.justep.user.*;
public class SystemTest {
public static void systemProcessBeforeLoginAction() throws Exception {
String user = ((String) ContextHelper.getActionContext().getParameter("name"));
Map<Object, Object> options = (Map<Object, Object>) ContextHelper.getActionContext().getParameter("options");
String deviceType = (String) options.get("DeviceType");
String userDeviceType = user+":"+deviceType;
//获取登录输入的name和设备类型,判断map中是否存在
if (OnLineMap.OnLineMaps.containsKey(userDeviceType)) {
throw new Exception("此用户已经在当前终端类型登录,请切换其他用户登录");
}
}
public static void systemProcessAfterLoginAction() {
String user = ((String) ContextHelper.getActionContext().getParameter("name"));// 获取登录输入的name
// 获取设备类型
Map<Object, Object> options = (Map<Object, Object>) ContextHelper.getActionContext().getParameter("options");
String deviceType = (String) options.get("DeviceType");
HttpSession session = ContextHelper.getSessionContext().getSession();//获取登录产生的session
String userDeviceType = user+":"+deviceType;
// 把name和设备类型拼接做为key,session做为value放到Map中
OnLineMap.OnLineMaps.put(userDeviceType, session);
}
}
用map存储的这个方案可用于非集群的环境,如果集群的环境要控制,把map修改为数据库表,把登录人员的信息存储的数据库表中操作
评一波