loginform.jsp
<body>
<center>
用户登录<br><br>
<form action="logincheck.jsp" method="post">
姓名<input type="text" name="username"><br><br>
密码<input type="text" name="password"><br><br>
<input type="submit" value="登录">
</form>
</center>
</body>
logincheck.jsp
<body>
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
if(username.equals("jack") && password.equals("123456")){
session.setAttribute("username",username);
request.getRequestDispatcher("loginsuccess.jsp").forward(request,response);
}
else if(username.equals("jam") && password.equals("123456")){
session.setAttribute("username",username);
request.getRequestDispatcher("loginsuccess.jsp").forward(request,response);
}
else if(username.equals("jad") && password.equals("123456")){
session.setAttribute("username",username);
request.getRequestDispatcher("loginsuccess.jsp").forward(request,response);
}
else{
request.getRequestDispatcher("loginfailure.jsp").forward(request,response);
}
%>
</body>
loginsuccess.jsp
<body>
<%= session.getAttribute("username")%>,欢迎登陆
<a href="logout.jsp">点此注销</a><br><br><br>
当前在线人数:<%=OnLine.getSum() %>
</body>
loginfailure.jsp
<body>
登录失败<a href="loginform.jsp">返回继续登录</a>
</body>
logout.jsp
<body>
<%
session.invalidate();//销毁session
request.getRequestDispatcher("loginform.jsp").forward(request,response);
%>
</body>
统计类OnLine.java
package online;
public class OnLine {
private long sum = 0;
private OnLine(){}
public static OnLine ol = null;
public static OnLine getIns(){
if(ol==null){
synchronized(OnLine.class){
if(null == ol){
ol = new OnLine();
}
}
}
return ol;
}
public void raise(){
ol.sum++;
}
public void reduce(){
ol.sum--;
}
public static long getSum(){
return ol.sum;
}
}
监听器MyListener.java
package listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import online.OnLine;
public class MyListener implements HttpSessionListener , HttpSessionAttributeListener{
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("新session已创建");
}
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("session已经销毁,在线人数减一");
OnLine.getIns().reduce();
}
public void attributeAdded(HttpSessionBindingEvent arg0) {
System.out.println("用户已经登陆,在线人数加一");
OnLine.getIns().raise();
}
public void attributeRemoved(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
}
public void attributeReplaced(HttpSessionBindingEvent arg0) {
// TODO Auto-generated method stub
}
}
web.xml
<listener>
<listener-class>listener.MyListener</listener-class>
</listener>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/loginsuccess.jsp</url-pattern>
</filter-mapping>
说明:所有的jsp都直接位于webroot下。
分析:访问loginform.jsp的时候创建新session会调用listener实现的HttpSessionListener的sessionCreated方法,在这里不能对在线人数+1,因为一般点击注销应该跳转到
登录页面,这时又会创建新的session,所以在线人数会先-1又+1,会出现用户注销了但在线人数没有发生变化的问题。所以应该在用户登录成功后,把用户名存到session中
后,session的Attribute产生变化会触发session实现的HttpSessionAttributeListener的attributeAdded方法,这时对在线人数+1,这样注销时在线人数会-1,但产生新session
在线人数也不会增加。也就是说:用户名存到session以后对在线人数+1,session注销时在线人数-1。另外,注销时调用session的invalidate,session会立即销毁,如果采
用关闭浏览器的方式,session仍会存活一段才销毁,所以在线人数不会瞬时发生改变,应该采用注销的方式。
补充:
将MyListener.java的attributeReplaced改为:
public void attributeReplaced(HttpSessionBindingEvent arg0) {
System.out.println("session中的用户名被替换,人数不变");
}
开两次火狐浏览器登录,控制台会打印出"session中的用户名被替换,人数不变",说明第二次打开的火狐与第一次共享一个session。将用户名添加到session时会替换掉第一
添加的值。