• session 之session混乱解决方法(转)


    知道了session混乱产生的原因之后,也就知道了问题的根源。同时也引出了很多的问题:

    1、如何记录住在线人员(这里只有帐号的系统用户,不包括访客);

    2、如何限制同一个帐号在同一时间段内只能够登陆一次系统?

    3、如何限制不同的用户在同一台机器上登陆系统?

    4、管理员如何踢人?

    我们首先来分析上面的问题:

    首先在服务器端当用户通过身份验证成功登陆系统之后,我们将此用户的信息记录住(OnLineUserManager.java),包括帐号、登陆日期、机器的IP地址、session的IDsession对象。(记住session的ID极其重要,因为服务器识别session是根据id,只要id相同,服务器就认为是同一个用户);

    (上面解决了问题1)

    这样当用户登陆系统的时候我们首先根据帐号判断用户是否登陆了,如果已经登陆,提示用户;(这样就解决了问题2)

    如果未登陆,判断用户的session的id是否已经在用户的信息OnLineUserManager里面了,如果是提示用户

    关闭当前窗口,重新点击IE打开一个新的浏览器窗口。(这样session就不会混乱了)。

    如果要限制不同的用户在同一台机器上登陆系统?这个就要根据IP地址来判断了。如果OnLineUserManager中

    有通过这个机器登陆系统的用户,那么就提示用户同一台机器只能够一个帐号登陆;

    (问题3也就解决了,注意:如果用户使用了代理服务器,那么此方法失效。这个方法适用于管理规范的用户,客户在局域网内使用,每个客户有固定的ip。

    问题4如何踢人?你想想OnLineUserManager中记录了用户session对象,只要根据用户的帐号找到对应的

    session对象,然后session.invalidate();这样就可以彻底的将捣乱的人提出系统了。

    ===============需要注意的是OnLineUserManager必须是线程安全的=我的实现如下==============

    [java] view plaincopy
     
    1. package com.work.qxgl.login;  
    2.   
    3.   
    4.   
    5. import java.util.Vector;  
    6.   
    7.   
    8.   
    9. import org.apache.commons.logging.Log;  
    10.   
    11. import org.apache.commons.logging.LogFactory;  
    12.   
    13.   
    14.   
    15. import com.work.util.DateUtil;  
    16.   
    17.   
    18.   
    19. /** 
    20.  
    21.  * 统计在线用户数。前提是登录的时候限制一个用户只能够在系统中登录一次。 有了这个功能,管理员就可以管理在线用户,如果谁不服从管理,就可以从系统中踢出去。 
    22.  
    23.  * TODO 将jsp放到WEB-INF后面,然后所有的URL必须通过struts的action调用。 使用拦截器Interceptor来实现权限的控制! 
    24.  
    25.  * 或者通过web中的Filter来实现权限控制! 实现权限管理系统日志的记录! 
    26.  
    27.  *  
    28.  
    29.  * @author wangmingjie 
    30.  
    31.  *  
    32.  
    33.  */  
    34.   
    35. public class OnLineUserManager {  
    36.   
    37.     private static Log log = LogFactory.getLog(OnLineUserManager.class);  
    38.   
    39.     private Vector<OnLineUser> users = null;  
    40.   
    41.   
    42.   
    43.   
    44.   
    45.     private OnLineUserManager() {  
    46.   
    47.         users = new Vector<OnLineUser>();//在构造函数中初始化  
    48.   
    49.     }  
    50.   
    51.       
    52.   
    53.     static class SingletonHolder {  
    54.   
    55.         static OnLineUserManager instance = new OnLineUserManager();  
    56.   
    57.     }  
    58.   
    59.   
    60.   
    61.     /** 
    62.  
    63.      * 单例模式。这样简单而且能够保证线程安全。 
    64.  
    65.      *  
    66.  
    67.      * @return 
    68.  
    69.      */  
    70.   
    71.     public static OnLineUserManager getInstance() {  
    72.   
    73.         return SingletonHolder.instance;  
    74.   
    75.     }  
    76.   
    77.   
    78.   
    79.     /** 
    80.  
    81.      * 获取到登录用户的数量。 
    82.  
    83.      *  
    84.  
    85.      * @return 
    86.  
    87.      */  
    88.   
    89.     public synchronized int getCount() {  
    90.   
    91.         users.trimToSize();  
    92.   
    93.         return users.capacity();  
    94.   
    95.     }  
    96.   
    97.   
    98.   
    99.     /** 
    100.  
    101.      * 通过用户帐号判断该用户是否存在! 必须保证是线程安全的。 
    102.  
    103.      *  
    104.  
    105.      * @param userAccount 
    106.  
    107.      * @return 
    108.  
    109.      */  
    110.   
    111.     public synchronized boolean existUser(String userAccount) {  
    112.   
    113.         users.trimToSize();  
    114.   
    115.         boolean existUser = false;  
    116.   
    117.         for (int i = 0; i < users.capacity(); i++) {  
    118.   
    119.             if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
    120.   
    121.                 existUser = true;  
    122.   
    123.                 break;  
    124.   
    125.             }  
    126.   
    127.         }  
    128.   
    129.         return existUser;  
    130.   
    131.     }  
    132.   
    133.       
    134.   
    135.     /** 
    136.  
    137.      * @param sessionid 
    138.  
    139.      * @return 
    140.  
    141.      */  
    142.   
    143.     public synchronized boolean existSession(String sessionid) {  
    144.   
    145.         users.trimToSize();  
    146.   
    147.         boolean existUser = false;  
    148.   
    149.         for (int i = 0; i < users.capacity(); i++) {  
    150.   
    151.             if (sessionid.equals(((OnLineUser) users.get(i)).getSessionId())) {  
    152.   
    153.                 existUser = true;  
    154.   
    155.                 break;  
    156.   
    157.             }  
    158.   
    159.         }  
    160.   
    161.         return existUser;  
    162.   
    163.     }  
    164.   
    165.       
    166.   
    167.   
    168.   
    169.     /** 
    170.  
    171.      * 删除用户 
    172.  
    173.      *  
    174.  
    175.      * @param userAccount 
    176.  
    177.      * @return 
    178.  
    179.      */  
    180.   
    181.     public synchronized boolean deleteUser(String userAccount) {  
    182.   
    183.         users.trimToSize();  
    184.   
    185.         if (existUser(userAccount)) {  
    186.   
    187.             int currUserIndex = -1;  
    188.   
    189.             for (int i = 0; i < users.capacity(); i++) {  
    190.   
    191.                 if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
    192.   
    193.                     currUserIndex = i;  
    194.   
    195.                     break;  
    196.   
    197.                 }  
    198.   
    199.             }  
    200.   
    201.             if (currUserIndex != -1) {  
    202.   
    203.                 users.remove(currUserIndex);  
    204.   
    205.                 users.trimToSize();  
    206.   
    207.                 log.debug("用户" + userAccount + "退出系统"  
    208.   
    209.                         + DateUtil.getCurrentDateTime());  
    210.   
    211.                 log.debug("在线用户数为:" + getCount());  
    212.   
    213.                 return true;  
    214.   
    215.             }  
    216.   
    217.         }  
    218.   
    219.         return false;  
    220.   
    221.     }  
    222.   
    223.       
    224.   
    225.     /** 
    226.  
    227.      * 根据用户帐号,获取在线用户信息 
    228.  
    229.      * @param userAccount 
    230.  
    231.      * @return 
    232.  
    233.      */  
    234.   
    235.     public synchronized OnLineUser getUser(String userAccount) {  
    236.   
    237.         users.trimToSize();  
    238.   
    239.         if (existUser(userAccount)) {  
    240.   
    241.             int currUserIndex = -1;  
    242.   
    243.             for (int i = 0; i < users.capacity(); i++) {  
    244.   
    245.                 if (userAccount.equals(((OnLineUser) users.get(i)).getUserAccount())) {  
    246.   
    247.                     currUserIndex = i;  
    248.   
    249.                     break;  
    250.   
    251.                 }  
    252.   
    253.             }  
    254.   
    255.             if (currUserIndex != -1) {  
    256.   
    257.                 return  users.get(currUserIndex);  
    258.   
    259.             }  
    260.   
    261.         }  
    262.   
    263.         return null;  
    264.   
    265.     }  
    266.   
    267.   
    268.   
    269.     /** 
    270.  
    271.      * 获取到在线用户的信息。 
    272.  
    273.      *  
    274.  
    275.      * @return 
    276.  
    277.      */  
    278.   
    279.     public synchronized Vector<OnLineUser> getOnLineUser() {  
    280.   
    281.         return users;  
    282.   
    283.     }  
    284.   
    285.   
    286.   
    287.     public synchronized void addUser(OnLineUser onLineUser) {  
    288.   
    289.         users.trimToSize();  
    290.   
    291.         if (!existUser(onLineUser.getUserAccount())) {  
    292.   
    293.             users.add(onLineUser);  
    294.   
    295.             log.debug(onLineUser.getUserAccount() + "/t登录到系统/t" + DateUtil.getCurrentDateTime());  
    296.   
    297.             // 通过request才能够获取到用户的ip等信息  
    298.   
    299.         } else {  
    300.   
    301.             log.debug(onLineUser.getUserAccount() + "已经存在");  
    302.   
    303.         }  
    304.   
    305.         log.debug("在线用户数为:" + getCount());  
    306.   
    307.     }  
    308.   
    309.   
    310.   
    311. }  

     ==================OnLineUser.java============================

    [java] view plaincopy
     
    1. package com.work.qxgl.login;  
    2.   
    3.   
    4.   
    5. import java.io.Serializable;  
    6.   
    7.   
    8.   
    9. import javax.servlet.http.HttpSession;  
    10.   
    11.   
    12.   
    13. /** 
    14.  
    15.  * @author wangmingjie 
    16.  
    17.  * @date 2008-6-30下午04:56:37 
    18.  
    19.  */  
    20.   
    21. public class OnLineUser implements Serializable {  
    22.   
    23.   
    24.   
    25.     /** 
    26.  
    27.      *  
    28.  
    29.      */  
    30.   
    31.     private static final long serialVersionUID = 5461473880667036331L;  
    32.   
    33.       
    34.   
    35.     private String userId; //用户id  
    36.   
    37.     private String userAccount; //用户帐号  
    38.   
    39.     private String userName; //用户名称   
    40.   
    41.       
    42.   
    43.     private String loginTime; //登陆时间戳  
    44.   
    45.       
    46.   
    47.     private String sessionId; //session的ID  
    48.   
    49.     private String userIp ;//ip地址  
    50.   
    51.       
    52.   
    53.     private HttpSession session; //记住session对象,测试能否用来将人员踢出系统  
    54.   
    55.       
    56.   
    57.   
    58.   
    59.     public String getUserId() {  
    60.   
    61.         return userId;  
    62.   
    63.     }  
    64.   
    65.   
    66.   
    67.     public void setUserId(String userId) {  
    68.   
    69.         this.userId = userId;  
    70.   
    71.     }  
    72.   
    73.   
    74.   
    75.     public String getUserAccount() {  
    76.   
    77.         return userAccount;  
    78.   
    79.     }  
    80.   
    81.   
    82.   
    83.     public void setUserAccount(String userAccount) {  
    84.   
    85.         this.userAccount = userAccount;  
    86.   
    87.     }  
    88.   
    89.   
    90.   
    91.     public String getUserName() {  
    92.   
    93.         return userName;  
    94.   
    95.     }  
    96.   
    97.   
    98.   
    99.     public void setUserName(String userName) {  
    100.   
    101.         this.userName = userName;  
    102.   
    103.     }  
    104.   
    105.   
    106.   
    107.     public String getSessionId() {  
    108.   
    109.         return sessionId;  
    110.   
    111.     }  
    112.   
    113.   
    114.   
    115.     public void setSessionId(String sessionId) {  
    116.   
    117.         this.sessionId = sessionId;  
    118.   
    119.     }  
    120.   
    121.   
    122.   
    123.     public String getUserIp() {  
    124.   
    125.         return userIp;  
    126.   
    127.     }  
    128.   
    129.   
    130.   
    131.     public void setUserIp(String userIp) {  
    132.   
    133.         this.userIp = userIp;  
    134.   
    135.     }  
    136.   
    137.   
    138.   
    139.     public HttpSession getSession() {  
    140.   
    141.         return session;  
    142.   
    143.     }  
    144.   
    145.   
    146.   
    147.     public void setSession(HttpSession session) {  
    148.   
    149.         this.session = session;  
    150.   
    151.     }  
    152.   
    153.   
    154.   
    155.     public String getLoginTime() {  
    156.   
    157.         return loginTime;  
    158.   
    159.     }  
    160.   
    161.   
    162.   
    163.     public void setLoginTime(String loginTime) {  
    164.   
    165.         this.loginTime = loginTime;  
    166.   
    167.     }  
    168.   
    169.     public String toString(){  
    170.   
    171.         return  "OnLineUser{userId="+userId+",userAccount="+userAccount  
    172.   
    173.         +",userName"+userName+",loginTime="+loginTime+",userIp="+userIp+",sessionId="+sessionId+"}";  
    174.   
    175.     }  
    176.   
    177.       
    178.   
    179.     //===============下面的数据只有在系统登陆日期中记录==================================  
    180.   
    181. //  private String logoutTime;//退出时间戳;  
    182.   
    183. //  private String logoutType;//退出方式 “session超时退出”;“1主动退出”  
    184.   
    185. //  private String lastAccessedTime;// 最后访问时间  
    186.   
    187.   
    188.   
    189. }  
  • 相关阅读:
    BZOJ 2594: [Wc2006]水管局长数据加强版
    BZOJ 2049: [Sdoi2008]Cave 洞穴勘测
    html5 canvas ( 贝塞尔曲线, 一片星空加绿地 ) quadraticCurveTo, bezierCurveTo
    c#.net 接收 base64 格式的数据并解析为图片
    html5 canvas ( 绘制一轮弯月, 星空中的弯月 )
    html5 canvas ( 圆和切点曲线的绘制 ) arc, arcTo
    html5 canvas ( 图片填充样式 ) fillStyle, createPattern
    html5 canvas ( 径向渐变, 升级版的星空 ) fillStyle, createRadialGradient
    html5 canvas ( 线性渐变, 升级版的星空 ) fillStyle, createLinearGradient, addColorStop
    html5 canvas ( 图形变换矩阵 ) transform, setTransform
  • 原文地址:https://www.cnblogs.com/yxnchinahlj/p/4247880.html
Copyright © 2020-2023  润新知