js
使用者登入和退出日誌
當使用者登入系統時,在日誌表中插入一條記錄,記錄使用者登入的時間,在使用者退出系統時記錄使用者退出系統的時間。
我們利用HttpSessionBindingListener介面來完成記錄登入和退出日誌的功能,該介面中定義了兩個方法:
·valueBound(HttpSessionBindingEvent event)
·valueUnbound(HttpSessionBindingEvent event)
如果一個類實現了HttpSessionBindingListener介面,當對象通過session.setAttribute()被綁定到Session中時,則對象的介面方法valueBound()被自動調用,當對象從session中移出時(通過調用session.invalidate()、session.removeAttribute()或session自動到期時),valueUnbound()方法將被自動調用。
下面我們使User.java類實現HttpSessionBindingListener介面,調整後的代碼如下所示:
代碼清單 18 實現了HttpSessionBindingListener的User.java
1. package bookstore;
2. import javax.servlet.http.HttpSessionBindingListener;
3. import javax.servlet.http.HttpSessionBindingEvent;
4. import java.sql.*;
5. import java.text.SimpleDate表單at;
6. import java.util.Date;
7.
8. public class User implements HttpSessionBindingListener
9. {
10. …
11. private String loginDatetime;//使用者登入時間
12. …
13. public void valueBound(HttpSessionBindingEvent event)
14. {
15. Connection conn = null;
16. String sqlStr = "insert into T_LOGIN_LOG(ID, USER_ID, DT_LOGIN) " +
17. " values(SEQ_LOGIN_LOG_ID.NEXTVAL,?,? )";
18. try
19. {
20. conn = DBConnection.getConnection();
21. PreparedStatement pStat = conn.prepareStatement(sqlStr);
22. loginDatetime = getCurrDatetimeStr(); //目前時間串
23. pStat.setString(1, userId);
24. pStat.setString(2, loginDatetime);
25. pStat.executeUpdate();
26.
27. } catch (SQLException e)
28. {
29. throw new RuntimeException(
30. "使用者登陸日誌寫入出錯");
31. } finally
32. {
33. try
34. {
35. if (conn != null)
36. {
37. conn.close();
38. }
39. } catch (SQLException ex)
40. {
41. ex.printStackTrace();
42. }
43. }
44. }
45.
46. public void valueUnbound(HttpSessionBindingEvent event)
47. {
48. Connection conn = null;
49. String sqlStr = " update T_LOGIN_LOG set DT_LONOUT = ? " +
50. " where USER_ID=? and DT_LOGIN = ?";
51. try
52. {
53. conn = DBConnection.getConnection();
54. PreparedStatement pStat = conn.prepareStatement(sqlStr);
55. pStat.setString(1, getCurrDatetimeStr());
56. pStat.setString(2, userId);
57. pStat.setString(3, loginDatetime);
58. pStat.executeUpdate();
59.
60. } catch (SQLException e)
61. {
62. throw new RuntimeException(
63. "使用者退出日誌寫入出錯");
64. } finally
65. {
66. try
67. {
68. if (conn != null)
69. {
70. conn.close();
71. }
72. } catch (SQLException ex)
73. {
74. ex.printStackTrace();
75. }
76. }
77. }
78.
79. //擷取目前時間字串,以yyyyMMddHHmmss格式返回,如20050505010101
80. private static String getCurrDatetimeStr()
81. {
82. SimpleDate表單at sdf = new SimpleDate表單at("yyyyMMddHHmmss");
83. return sdf.表單at(new Date());
84. }
85. }
valueBound()方法向T_LOGIN_LOG表插入一條登入日誌,在valueUnbound()方法中更新日誌表的退出時間,此外第80~84行提供了一個擷取目前時間串的方法getCurrDatetimeStr(),通過該方法擷取登入和退出時間點的時間字串。
下面通過描述使用者登入系統直到退出時所經曆的步驟說明程式如何記錄使用者的登入和退出時間的:
1.使用者通過login.jsp輸入密碼登入後,程式轉向switch.jsp控制頁面。
2.在switch.jsp中,我們通過session.setAttribute("ses_userBean", userBean)方法將User.java類的對象userBean綁定到session中。
3.此時userBean對象的HttpSessionBindingListener介面方法valueBound()被調用,向T_LOGIN_LOG表插入一條登入日誌。
4.switch.jsp轉向welcome.jsp頁面。
5.使用者點擊welcome.jsp頁面中的連結退出系統時,轉向quit.jsp頁面。
6.quit.jsp調用session.invalidate()方法,userBean對象從session中清除。
7.此時userBean對象的HttpSessionBindingListener介面方法valueUnbound()方法被調用,更新日誌的退出時間,關閉瀏覽器視窗。
HttpSessionBindingListener介面是Web容器的事件介面,實現介面的類在某個事件發生時自動被調用,Web容器有多個這樣的事件介面,它們分別是:
·ServletContextListener 介面:Web容器啟動和銷毀的事件處理介面,介面中定義了兩個方法。
·ServletContextAttributeListener介面:Web內容屬性發生更改時的事件處理介面。
·HttpSessionListener介面:Session建立和銷毀事件的事件處理介面。
·HttpSessionAttributeListener介面:Session會話中屬性對象更改的事件處理介面,該介面和我們在前面使用的HttpSessionBindingListener介面相似。
此外在J2EE1.4中還提供了另外兩個事件處理介面,它們是:
·ServletRequestListener介面:Request請求對象建立和銷毀事件處理介面。
·ServletRequestAttributeListener介面:更改Request中屬性對象時的事件處理介面。
程式部署
在Web程式開發完成後,我們開始著手程式部署的工作,我們希望將這個Web應用程式部署到Tomcat5.0的Web應用伺服器中。
首先我們設定Web應用程式的預設首頁,然後再將整個Web程式打成一個WAR檔案檔案包。
1.設定預設訪問的頁面,雙擊工程窗格中的webModule節點,JBuilder在內容窗格顯示如下的頁面:
圖 26 設定Web程式預設訪問的頁面
點擊Welcome files列表右邊的Add…按鈕,在彈出的對話方塊中錄入login.jsp並按確定按鈕,將login.jsp頁面作為預設頁面,這樣web.xml部署描述檔案中將新增以下粗體的部署資訊:
代碼清單 19 Web應用程式預設頁面
1. …
2. <web-app>
3. <display-name>webModule</display-name>
4. <welcome-file-list>
5. <welcome-file>login.jsp</welcome-file>
6. </welcome-file-list>
7. …
8. </web-app>
當使用者在URL中沒有指定具體的訪問檔案名稱時,Web容器自動查看URI下是否有login.jsp檔案,如果直接調出這個檔案。
2.在工程窗格中的資源樹中右擊webModule節點,Properties…->Build->在Build設定面中,將Build Web archive設定為When building project or module選項,如下圖所示:
圖 27 設定在Rebuild工程或Web模組時建立WAR檔案檔案
3.在工程窗格中右擊chapter13.jpx,在彈出的菜單中選擇Rebuild編譯整個工程。
4.編譯完成後,在工程根目錄下將產生一個webModule.war檔案。
5.拷貝webModule.war檔案至<JBuilder2005安裝目錄>/thirdparty/jakarta-tomcat-5.0.27/webapps目錄下。
這樣就完成Web應用程式的部署了,下面我們啟動Tomcat 5.0 Web應用程式伺服器,並訪問剛才部署的webModule.war應用程式。
1.雙擊<JBuilder2005安裝目錄>/thirdparty/jakarta-tomcat-5.0.27/bin下的startup.bat啟動Tomcat 5.0 Web應用伺服器(請保證這時JBuilder中沒有運行Web應用程式,以免衝突)。
2.開啟IE,鍵入http://localhost:8080/webModule,將正確訪問到剛才部署的Web應用程式,如下圖所示:
圖 28 部署後login.jsp的訪問效果
Tomcat 伺服器預設工作於8080連接埠,所以在機器名後需要添加連接埠號碼,可以通過更改Tomca位於conf目錄下的server.xml設定檔可以更改這個連接埠號碼。
由於我們的web應用程式的WAR檔案名稱為webModule.war,web伺服器啟動後,會自動將WAR檔案解壓到webModule目錄下,所以必須通過http://localhost:8080/webModule訪問。此外,由於預設訪問頁面為login.jsp,所以沒有指定具體的頁面時,login.jsp頁面被調用訪問。