Я использовал кое-что как это.Сначала есть фильтр.Вот мой фильтр
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//Send request to server after each 1min
// httpServletResponse.setIntHeader("Refresh", 60);
//getSession(false), which returns null if no session already exists for the current client
HttpSession session = httpServletRequest.getSession(false);
if (session == null) {
//session timeout check.
if (httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid()) {
System.out.println("Session has expired");
/**
* getSession() (or, equivalently, getSession(true)) creates a new session if no
* session already exists.
*/
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0"); // public user
//httpServletResponse.sendRedirect("http://www.google.com");
httpServletResponse.sendRedirect(timeoutPage);
} else {
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0");
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
} else {
String isRegisteredUser = session.getAttribute("logedin").toString();
if (isRegisteredUser.equalsIgnoreCase(("1"))) {
Login login = (Login)session.getAttribute("login");
Enumeration e = session.getAttributeNames();
System.out.println("");
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else if (isRegisteredUser.equalsIgnoreCase(("0"))) {
Enumeration e = session.getAttributeNames();
filterChain.doFilter(httpServletRequest, httpServletResponse);
} //end of else if (isRegisteredUser.equalsIgnoreCase(("0")))
}
} //end of doFilter()
Теперь, когда пользователь вводит URL моего сайта, этот фильтр запускается.В первый раз он получает нулевую сессию, а затем проверяет время ожидания сессии.нет времени ожидания сеанса, поэтому он создает сеанс.Установите для атрибута logedin значение 0, это означает, что это публичный пользователь, и передайте запрос.Вот мой метод
//constructor
public Login() {
try {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletRequest httpServletRequest = (HttpServletRequest)externalContext.getRequest();
//getSession(false), which returns null if no session already exists for the current client.
HttpSession session =(HttpSession)externalContext.getSession(false);
if (session == null) {
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0");
session.setMaxInactiveInterval(-1);
System.out.println();
} else {
session.setAttribute("logedin", "0");
//No session timeout for public users
session.setMaxInactiveInterval(-1);
Enumeration e = session.getAttributeNames();
}
} catch (Exception e) {
System.out.println("Exception in session " + e.getMessage());
}
} //end of constructor
В первый раз, когда он получает сеанс, просто переопределите значения, чтобы не повредить этот же атрибут.Но здесь я просто хочу спросить одну вещь, это нормально, чтобы не устанавливать время сеанса для публичных пользователей?не повредит ли это моему приложению в какой-то момент, например, на моем сервере не хватает памяти и т. д.?Если да, то как я могу преодолеть это?
Теперь предположим, что мой пользователь вошел в систему. Затем мой фильтр запускается, на этот раз он получит сеанс, так что он дойдет до моей проверки isRegisterdUser и проверки значения.Он получает 0, просто передает запрос и затем мой действительный вызов пользовательского метода.
public String validUser() throws Exception {
String returnString = null;
ArrayList2d<Object> mainarray = new ArrayList2d<Object>();
mainarray.addRow();
mainarray.add(userName);
mainarray.add(password);
busBeans.usermanagement.users um = new busBeans.usermanagement.users();
ArrayList retrieveList = um.getValidUser(mainarray);
if (Integer.parseInt(retrieveList.get(0).toString()) == 0) {
ArrayList str = (ArrayList) retrieveList.get(1);
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//getSession(false), which returns null if no session already exists for the current client.
HttpSession session =(HttpSession)externalContext.getSession(false);
if (session == null) {
System.out.println();
} else {
Enumeration e = session.getAttributeNames();
}
System.out.println();
logedin=true;
//Set session attributes for login users
session.setAttribute("logedin", 1);
session.setAttribute("firstLastName", str.get(7).toString());
session.setAttribute("getusercredentials", str);
session.setAttribute("sessionUserId", str.get(0).toString());
session.setAttribute("sessionRoleId",str.get(1).toString());
session.setAttribute("registeredUser", "true");
/**
* set session timeout for login user
* 1 min = 60 sec
* 5 min = 60 * 5 sec = 300 sec
*/
session.setMaxInactiveInterval(300); //5min
firstLastName = session.getAttribute("firstLastName").toString();
}
return returnString=null;
} //end of validUser()
Я переопределяю значение атрибута logedin на 1, так что теперь пользователь становится действительным пользователем.Теперь, если действительный пользователь делает запрос, тогда мой фильтр вызывает, он получит сеанс, так что он приходит к моей проверке isRegisterdUser, на этот раз он получает значение 1, поэтому просто передайте запрос. Теперь, когда время сеанса истекло, и пользователь делает любой запрос, тогда мой фильтрвызвать и на этот раз он входит внутрь проверки
if (httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid()) {
System.out.println("Session has expired");
//httpServletResponse.sendRedirect("http://www.google.com");
httpServletResponse.sendRedirect(timeoutPage);
} else {
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0");
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
и перенаправить пользователя, сделав его публичным.Так вот как это я делаю.Я также получил идею, что через некоторое время я обновляю страницу, у меня есть sessionCreationTime, sessionLastAccessTime и sessionMaxTime.так что я могу сделать такую работу
String isRegisteredUser = session.getAttribute("logedin").toString();
if (isRegisteredUser.equalsIgnoreCase(("1"))) {
Login login = (Login)session.getAttribute("login");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String attr = (String)e.nextElement();
System.err.println("attr = "+ attr);
Object value = session.getAttribute(attr);
System.err.println("value = "+ value);
} //end of while
long sessionCreationTime = session.getCreationTime();
int sessionCreationTimeInSec = (int)(sessionCreationTime / 1000) % 60;
int sessionCreationTimeInMinutes = (int)((sessionCreationTime / (1000*60)) % 60);
long sessionLastAccessTime = session.getLastAccessedTime();
int sessionLastAccessTimeInSec = (int)(sessionLastAccessTime / 1000) % 60 ;
int sessionLastAccessTimeInMinutes = (int)((sessionLastAccessTime / (1000*60)) % 60 );
int sessionMaxTime = session.getMaxInactiveInterval();
int sessionMaxTimeInMinute = sessionMaxTime / 60 ;
if ((sessionCreationTimeInMinutes - sessionLastAccessTimeInMinutes) - 1 > sessionMaxTimeInMinute) {
System.out.println("Session is expiring in one minute");
}
System.out.println("");
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
Идея здесь в том, что если кто-то, как вы проверите, сколько времени осталось на тайм-аут сеанса, то вы можете аннулировать сеанс незадолго до истечения времени ожидания сеанса.Потому что, как только ваш сеанс истекает, вы получаете нулевой сеанс, и у вас нет атрибутов для проверки.Но до одной минуты у вас есть сеанс и все атрибуты сеанса, так что вы можете делать все, что захотите.Я не знаю, насколько это солидная идея, это просто подход, который пришел мне в голову.
Также предположим, что пользователь вошел в систему, а затем внезапно закрыл браузер.Закрытие браузера закрывает сессию.Теперь, когда вы открываете браузер, вы получаете сообщение о том, что ваш сеанс истек.Я хочу спросить, когда вы открываете браузер, могу ли я использовать эту проверку
if (httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid()) {
System.out.println("Session has expired");
if (session.isNew()) {
/**
* getSession() (or, equivalently, getSession(true)) creates a new session if no
* session already exists.
*/
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0"); // public user
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else {
httpServletResponse.sendRedirect("http://www.google.com");
}
}
Я использовал проверку isNew (), потому что я хочу сделать это, если пользователь заходит на ваш сайт впервые, например, открывает свой браузер, затемон не видел сообщения о перенаправлении, хотя его сеанс истек из-за закрытия браузера.
Спасибо