JBuilder2005实战JSP之日志和部署(7)
用户登录和退出日志
当用户登录系统时,在日志表中插入一条记录,记录用户登录的时间,在用户退出系统时记录用户退出系统的时间。
我们利用HttpSessionBindingListener接口来完成记录登录和退出日志的功能,该接口中定义了两个方法:
ⷶalueBound(HttpSessionBindingEvent event)
ⷶalueUnbound(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容器有多个这样的事件接口,它们分别是:
ⷓervletContextListener 接口:Web容器启动和销毁的事件处理接口,接口中定义了两个方法。
ⷓervletContextAttributeListener接口:Web上下文属性发生更改时的事件处理接口。
ⷈttpSessionListener接口:Session创建和销毁事件的事件处理接口。
ⷈttpSessionAttributeListener接口:Session会话中属性对象更改的事件处理接口,该接口和我们在前面使用的HttpSessionBindingListener接口相似。
此外在J2EE1.4中还提供了另外两个事件处理接口,它们是:
ⷓervletRequestListener接口:Request请求对象创建和销毁事件处理接口。
ⷓervletRequestAttributeListener接口:更改Request中属性对象时的事件处理接口。
程序部署
在Web程序开发完成后,我们开始着手程序部署的工作,我们希望将这个Web应用程序部署到Tomcat5.0的Web应用服务器中。
首先我们设置Web应用程序的默认首页,然后再将整个Web程序打成一个WAR档案文件包。
1.设置默认访问的页面,双击工程窗格中的webModule节点,JBuilder在内容窗格显示如下的页面:
图 28 部署后login.jsp的访问效果
Tomcat 服务器默认工作于8080端口,所以在机器名后需要添加端口号,可以通过更改Tomca位于conf目录下的server.xml配置文件可以更改这个端口号。
由于我们的web应用程序的WAR文件名为webModule.war,web服务器启动后,会自动将WAR文件解压到webModule目录下,所以必须通过:8080/webModule访问。此外,由于默认访问页面为login.jsp,所以没有指定具体的页面时,login.jsp页面被调用访问。