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時會替換掉第一
添加的值。