こんばんは、
テストJSF2.0Webアプリで、アクティブなセッションの数を取得しようとしていますが、HttpSessionListenerのsessionDestroyedメソッドに問題があります。実際、ユーザーがログインすると、アクティブなセッションの数は1増加しますが、ユーザーがログオフすると、同じ数がそのまま残り(デクリメントは発生しません)、さらに悪いことに、同じユーザーが再度ログインすると(彼がセッションを検証しなかったとしても)、同じ数が増加します。別の言葉で言えば:
1-ログインすると、アクティブなセッション数が1ずつ増加します。2-Iログアウト(セッションが検証されなくなります)3-再度ログインすると、セッション数が1ずつ増加します。表示は=2です。4-繰り返します。ログインしているユーザーが1人だけである間、セッション数は増加し続けます。
そのため、メソッドsessionDestroyedが適切に呼び出されないか、WEB.XMLのパラメーターであるセッションタイムアウト(私の場合は60分)の後に効果的に呼び出されると思いました。これはセッションリスナーであり、私のクラスには何の問題もないので、それは奇妙です。
誰かが手がかりを持っていますか?
package mybeans;
import entities.Users;
import java.io.*;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import jsf.util.JsfUtil;
/**
* Session Listener.
* @author TOTO
*/
@ManagedBean
public class SessionEar implements HttpSessionListener {
public String ctext;
File file = new File("sessionlog.csv");
BufferedWriter output = null;
public static int activesessions = 0;
public static long creationTime = 0;
public static int remTime = 0;
String separator = ",";
String headtext = "Session Creation Time" + separator + "Session Destruction Time" + separator + "User";
/**
*
* @return Remnant session time
*/
public static int getRemTime() {
return remTime;
}
/**
*
* @return Session creation time
*/
public static long getCreationTime() {
return creationTime;
}
/**
*
* @return System time
*/
private String getTime() {
return new Date(System.currentTimeMillis()).toString();
}
/**
*
* @return active sessions number
*/
public static int getActivesessions() {
return activesessions;
}
@Override
public void sessionCreated(HttpSessionEvent hse) {
// Insert value of remnant session time
remTime = hse.getSession().getMaxInactiveInterval();
// Insert value of Session creation time (in seconds)
creationTime = new Date(hse.getSession().getCreationTime()).getTime() / 1000;
if (hse.getSession().isNew()) {
activesessions++;
} // Increment the session number
System.out.println("Session Created at: " + getTime());
// We write into a file information about the session created
ctext = String.valueOf(new Date(hse.getSession().getCreationTime()) + separator);
String userstring = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
// If the file does not exist, create it
try {
if (!file.exists()) {
file.createNewFile();
output = new BufferedWriter(new FileWriter(file.getName(), true));
// output.newLine();
output.write(headtext);
output.flush();
output.close();
}
output = new BufferedWriter(new FileWriter(file.getName(), true));
//output.newLine();
output.write(ctext + userstring);
output.flush();
output.close();
} catch (IOException ex) {
Logger.getLogger(SessionEar.class.getName()).log(Level.SEVERE, null, ex);
JsfUtil.addErrorMessage(ex, "Cannot append session Info to File");
}
System.out.println("Session File has been written to sessionlog.txt");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
// Desincrement the active sessions number
activesessions--;
// Appen Infos about session destruction into CSV FILE
String stext = "\n" + new Date(se.getSession().getCreationTime()) + separator;
try {
if (!file.exists()) {
file.createNewFile();
output = new BufferedWriter(new FileWriter(file.getName(), true));
// output.newLine();
output.write(headtext);
output.flush();
output.close();
}
output = new BufferedWriter(new FileWriter(file.getName(), true));
// output.newLine();
output.write(stext);
output.flush();
output.close();
} catch (IOException ex) {
Logger.getLogger(SessionEar.class.getName()).log(Level.SEVERE, null, ex);
JsfUtil.addErrorMessage(ex, "Cannot append session Info to File");
}
}
} // END OF CLASS
この方法でアクティブなセッション番号を取得しています。
<h:outputText id="sessionsfacet" value="#{UserBean.activeSessionsNumber}"/>
別のmanagedBeanから:
public String getActiveSessionsNumber() {
return String.valueOf(SessionEar.getActivesessions());
}
私のログアウト方法は次のとおりです。
public String logout() {
HttpSession lsession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (lsession != null) {
lsession.invalidate();
}
JsfUtil.addSuccessMessage("You are now logged out.");
return "Logout";
}
// end of logout