<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 241,  comments - 116,  trackbacks - 0
    那么我們應(yīng)該怎樣去實(shí)現(xiàn)同一用戶只能有一個(gè)在線這樣的一個(gè)小功能呢?
    有人可能就會(huì)這樣設(shè)想了:"這不是很簡(jiǎn)單嗎?只要在數(shù)據(jù)庫(kù)中用一個(gè)字段來(lái)標(biāo)記用戶的狀態(tài)就行了,比如如果用戶登陸了就將狀態(tài)設(shè)為1,退出了就將這個(gè)用戶的狀態(tài)設(shè)為0,OK,搞定。"

    但是,實(shí)際上是不是這樣呢?其實(shí)不全是。為什么這樣說(shuō)呢?其實(shí)如果你的想法跟上面那樣或相似的話,應(yīng)該說(shuō)是犯了一個(gè)比較嚴(yán)重的錯(cuò)誤。我還是舉個(gè)例 子來(lái)說(shuō)明吧。現(xiàn)在絕大多數(shù)的網(wǎng)站中都有登陸和退出兩項(xiàng)功能吧?好了,上面的設(shè)想僅僅是針對(duì)這兩項(xiàng)功能來(lái)說(shuō)使用。但是你有沒(méi)有想過(guò)?假如現(xiàn)在有一個(gè)用戶正常 登陸上了,但是這回情況有點(diǎn)特殊了,這個(gè)用戶登陸上但是這個(gè)用戶就偏偏不點(diǎn)退出,然后就走了或者離開(kāi)了或者忙別的事情去了,反正這個(gè)用戶登陸上就不管別的 了,他就掛在那里。這種情況是允許發(fā)生了,而且也是比較常見(jiàn)的一種情況。那如果是這種情況,上面的那種設(shè)想你還認(rèn)為是正確的嗎?那就不正確了!對(duì) session有過(guò)一點(diǎn)了解的人員應(yīng)該都知道,在java中session的默認(rèn)的銷毀時(shí)間是大于或等于30分鐘,如果你對(duì)session的生命周期不做 任何配置的話,按照上面的設(shè)想,那么只要用戶登陸上之后,這時(shí)該用戶的狀態(tài)設(shè)置為1,在大于30分鐘的時(shí)間內(nèi)如果該用戶沒(méi)有向服務(wù)器端發(fā)起任何請(qǐng)求的話, 那么這個(gè)session就會(huì)被銷毀掉,注意了,這時(shí)session生命周期結(jié)束以后自動(dòng)銷毀的,并不是用戶點(diǎn)退出按鈕來(lái)銷毀的,那這樣就不能觸發(fā)用戶退出 事件,那這個(gè)用戶的狀態(tài)你就沒(méi)法改變了,也就是說(shuō),如果按照上面的設(shè)想,你想想,如果遇到這樣的情況,那這個(gè)用戶的狀態(tài)就一直都是1了,那這個(gè)用戶以后再 想登陸就再也登陸不上了。很明顯,這樣是不對(duì)的。

    那應(yīng)該怎樣來(lái)解決這個(gè)問(wèn)題呢?大家看到我這篇文章的標(biāo)題就應(yīng)該知道了的吧。可以使用java的監(jiān)聽(tīng)器來(lái)解決這個(gè)問(wèn)題。在編程的開(kāi)始你應(yīng)該有這樣一個(gè)了解:

    當(dāng)用戶通過(guò)網(wǎng)絡(luò)來(lái)訪問(wèn)一個(gè)網(wǎng)站的時(shí)候,如果是首次訪問(wèn),那么在這個(gè)網(wǎng)站的服務(wù)器端都會(huì)創(chuàng)建一個(gè)session來(lái)保存一些屬于這個(gè)用戶的信息。在創(chuàng) 建session的時(shí)候其實(shí)是會(huì)觸發(fā)一個(gè)sessionCreated事件的,同樣的,當(dāng)用戶正常退出或者是用戶登陸了不退出并當(dāng)session生命周期 結(jié)束的時(shí)候,就會(huì)觸發(fā)一個(gè)sessionDestroyed事件。這兩個(gè)事件我們可以通過(guò)HttpSessionListener監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)到并可以把 它捕捉。那這樣問(wèn)題就好解決了。

    我話說(shuō)的也有點(diǎn)多了,朋友們不要介意哈。好了,下面來(lái)看一下代碼

    注:為了演示簡(jiǎn)單,我就不對(duì)用戶做封裝了,也不使用數(shù)據(jù)庫(kù)了,同樣的我也不添加任何的SSH框架支持了,我知道你們都懂的。不懂的可以給我留言。 在這里我就直接用servlet來(lái)模擬了。我直接將用戶登陸后的信息保存到一個(gè)ServletContext對(duì)象中。順便我也簡(jiǎn)單說(shuō)一下 ServletContext吧,怕有人對(duì)ServletContext不了解的。ServletContext對(duì)象是在你項(xiàng)目第一次啟動(dòng)服務(wù)器的時(shí)候被 創(chuàng)建的,這個(gè)對(duì)象是只被創(chuàng)建一次,是唯一的,你可以用ServletContextListener這個(gè)監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)的到。
    下面來(lái)看實(shí)現(xiàn)吧:

    我先做jsp吧,這里我需要三個(gè)jsp頁(yè)面:一個(gè)登陸login.jsp,一個(gè)首頁(yè)home.jsp,一個(gè)錯(cuò)誤提示error.jsp。我盡量將jsp寫(xiě)的簡(jiǎn)單些,下面來(lái)開(kāi)代碼,我就不多解釋了,一看就懂的

    login.jsp:
    <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>
      <head>
        <title>用戶登錄</title>
      </head>
     
      <body>
        [align=center]<br/><br/>
         <form action="/SingleOnline/servlet/LoginServlet" method="post">
          <table>
            <tr>
              <td>用戶昵稱:</td>
              <td><input type="text" name="username" /></td>
            </tr>
            <tr>
              <td>用戶密碼:</td>
              <td><input type="password" name="userpssw" size="21" /></td>
            </tr>
            <tr>
              <td> </td>
              <td><input type="submit" value=" 登陸 " /></td>
            </tr>
          </table>
         </form>
        [/align]
      </body>
    </html>
    home.jsp:
    <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>
      <head>
        <title>用戶主頁(yè)</title>
      </head>
     
      <body>
        <!-- ${user}是EL表達(dá)式,如果用戶登陸成功就將用戶名字顯示出來(lái) -->
        用戶 ${user} 登陸成功!<BR/>
        [url=/SingleOnline/servlet/LogoutServlet]安全退出[/url]
      </body>
    </html>
    error.jsp:
    <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <html>
      <head>
        <title>error page</title>
        
        <script type="text/javascript">
        
          function warn(){
              alert('您已經(jīng)登陸在線,不能重復(fù)登陸!');
          }
          
        </script>
        
      </head>
     
      <body onload="warn()">
     
             您已經(jīng)登陸在線,不能重復(fù)登陸! <br>
       [url=/SingleOnline/home.jsp]返回主頁(yè)[/url]
             
      </body>
    </html>
    下面來(lái)看一下登陸的servlet
    LoginServlet:
    package com.servlet;

    import java.io.IOException;
    import java.util.ArrayList;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class LoginServlet extends HttpServlet {

        private static final long serialVersionUID = 1L;

        public LoginServlet() {
            super();
        }

        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

            doPost(request, response);
        }

        @SuppressWarnings("unchecked")
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

            String uname = request.getParameter("username");
            @SuppressWarnings("unused")
            String upssw = request.getParameter("userpssw");
            String url   = "/SingleOnline/home.jsp";
            try {
                uname = new String(uname.getBytes("ISO-8859-1"));
            } catch (Exception e) {e.printStackTrace();}
            ServletContext context = this.getServletContext();    //獲取ServletContext
            ArrayList<String> users = (ArrayList<String>)context.getAttribute("users");    //獲取用戶列表,第一次獲取時(shí)候?yàn)榭?br />        if(users == null){    //第一個(gè)用戶登錄時(shí)候:
                users = new ArrayList<String>();    
                users.add(uname);
                context.setAttribute("users", users);    //將第一個(gè)用戶的名字保存到ServletContext對(duì)象中
            }else{    //非第一個(gè)用戶登錄:
                for(int i=0;i<users.size();i++){
                    String username = (String)users.get(i);聰明女人與笨女人~!                if(username.equals(uname)){        //如果該用戶已經(jīng)登錄,請(qǐng)求error.jsp不讓其再登錄
                        url = "/SingleOnline/error.jsp";
                        break;
                    }
                }
                users.add(uname);    //如果該用戶沒(méi)經(jīng)登錄,就將該用戶的名字保存到ServletContext對(duì)象中
            }
            request.getSession().setAttribute("user", uname);    //保存一下該用戶信息以備后用
            response.sendRedirect(url);
        }
    }
    接下來(lái)是用戶點(diǎn)擊安全退出需要的servlet:

    LogoutServlet:
    package com.servlet;

    import java.io.IOException;
    import java.util.ArrayList;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class LogoutServlet extends HttpServlet {

        private static final long serialVersionUID = 1L;

        public LogoutServlet() {
            super();
        }

        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

            doPost(request, response);
        }

        @SuppressWarnings("unchecked")
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

            String user = (String)request.getSession().getAttribute("user");    //獲取用戶信息
            ArrayList<String> users = (ArrayList<String>)this.getServletContext().getAttribute("users");    //    獲取用戶列表
            for(int i=0;i<users.size();i++){
                String username = (String)users.get(i);
                if(username.equals(user)){    
                    users.remove(i);    //將這個(gè)用戶從ServletContext對(duì)象中移除
                    break;
                }
            }
            request.getSession().invalidate();    //將session設(shè)置成無(wú)效
            response.sendRedirect("/SingleOnline/login.jsp");
        }

    }
    最后就是監(jiān)聽(tīng)器了,寫(xiě)監(jiān)聽(tīng)器類也是很簡(jiǎn)單的,只要實(shí)現(xiàn)相應(yīng)的監(jiān)聽(tīng)器接口并實(shí)現(xiàn)未實(shí)現(xiàn)的方法就行了。下面我寫(xiě)一個(gè)SessionListener,它實(shí)現(xiàn)了HttpSessionListener接口:
    package com.listener;

    import java.util.ArrayList;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;

    public class SessionListener implements HttpSessionListener {

        //session創(chuàng)建時(shí),該方法被調(diào)用
        //為了給朋友們看的清楚一些,我在兩個(gè)方法中都打印了一下信息
        public void sessionCreated(HttpSessionEvent arg0) {
            
            System.out.println("Session被創(chuàng)建!");
        }

        //session銷毀時(shí)候被調(diào)用(1.用戶安全退出;2.session生命周期結(jié)束)
        @SuppressWarnings("unchecked")
        public void sessionDestroyed(HttpSessionEvent arg0) {
            
            HttpSession session = arg0.getSession();    //獲取session
            String user = (String)session.getAttribute("user");        //獲取用戶信息
            ArrayList<String> users = (ArrayList<String>)session.getServletContext().getAttribute("users");    //獲取用戶列表
            for(int i=0;i<users.size();i++){
                String username = (String)users.get(i);
                if(username.equals(user)){
                    users.remove(i);    //將這個(gè)用戶從ServletContext對(duì)象中移除
                    break;
                }
            }
            session.invalidate();    //將session設(shè)置成無(wú)效
            System.out.println("一個(gè)Session被銷毀了!");
        }
    }
    posted on 2011-11-01 15:14 墻頭草 閱讀(608) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    人人游戲網(wǎng) 軟件開(kāi)發(fā)網(wǎng) 貨運(yùn)專家
    主站蜘蛛池模板: 麻豆狠色伊人亚洲综合网站 | 精品多毛少妇人妻AV免费久久| 亚洲黑人嫩小videos| 亚洲人成网站色在线入口| 在线观看免费人成视频色| 国产成人精品一区二区三区免费| 人妻18毛片a级毛片免费看| 亚洲成a∨人片在无码2023| 亚洲一区二区三区免费观看| 亚洲大片在线观看| 久久91亚洲人成电影网站| 亚洲伊人久久成综合人影院| 免费在线观看中文字幕| free哆啪啪免费永久| 日本免费一区二区三区| 国产精品白浆在线观看免费| 免费看少妇高潮成人片| 西西人体免费视频| 中文字幕免费在线播放| 国产高潮流白浆喷水免费A片 | 猫咪免费人成网站在线观看入口| 亚洲成av人片在线天堂无| 亚洲AV无码专区在线观看成人| 久久精品国产亚洲av麻豆图片| 亚洲成a人片在线网站| 亚洲国产亚洲片在线观看播放 | 一级毛片**不卡免费播| 国产午夜不卡AV免费| 成全高清在线观看免费| 免费国产成人午夜在线观看| 最近更新免费中文字幕大全| 大地影院MV在线观看视频免费| 国产成人免费ā片在线观看老同学 | 免费真实播放国产乱子伦| 国产精品九九久久免费视频 | 精品国产日韩亚洲一区| 亚洲精品无码99在线观看 | 91在线免费视频| 人妻免费一区二区三区最新| 性xxxx视频免费播放直播| jjizz全部免费看片|