Будучи восходящей звездой, JSP может занять определенную позицию в среде серверного программирования, что тесно связано с хорошей поддержкой ряда отраслевых стандартов. Сессия — это одна из инфраструктур, которые он предоставляет. Как программист, вы можете легко реализовать простое управление пользователями на основе сеансов, не беспокоясь о том, как оно реализовано на клиенте. В наши дни существует несколько различных способов взаимодействия с онлайн-пользователями.
Во-первых, обновление страницы контролируется пользователем, а сервер управляет тайм-аутом, например 30 минут. По истечении времени пользователь будет исключен, если не предпримет никаких действий. Преимущество этого метода в том, что если пользователь забудет выйти из системы, это может предотвратить злонамеренные операции других лиц. Недостаток заключается в том, что если вы делаете что-то, что занимает много времени и превышает этот срок, вам, возможно, придется снова войти в систему при отправке. Если исходная поверхность листа снова выйдет из строя, вы можете потерять проделанную работу. С точки зрения реализации это самый простой вариант, и серверная часть реализует этот режим по умолчанию.
Другой способ заключается в том, что сайт использует фреймовую структуру и имеет фрейм или скрытый iframe, который постоянно обновляется, поэтому вас никогда не выгонят. Однако, чтобы определить, находитесь ли вы в сети, серверу необходимо установить фрейм. Если вы превысите это время, если вы не обновите другие страницы, кроме этой автоматически обновляемой страницы, будет считаться, что вы больше не в сети. Типичным примером такого подхода является xici.net. Его преимущество заключается в том, что он может использовать непрерывное обновление для реализации некоторых функций, подобных серверным, таких как отправка сообщений между пользователями сети.
Независимо от того, какой режим используется, необходимо выполнить некоторую дополнительную работу, чтобы просмотреть всех пользователей, находящихся в сети в данный момент. В API сервлетов нет API для получения списка сеансов.
Что можно использовать, так это Listener. Спецификации сервлетов 2.2 и 2.3 здесь немного отличаются. HttpSessionBindingListener в версии 2.2 может реализовать класс, который уведомляет вас об изменении атрибута в HTTPSession. HttpSessionAttributeListener также был представлен в версии 2.3. Поскольку я использую среду Visual Age для Java 4 и сервера JRun 3.1, они напрямую не поддерживают программирование Servlet 2.3. Здесь я использую HttpSessionBindingListener,
включая создание нового класса. реализовать интерфейс HttpSessionBindingListener. Этот интерфейс имеет два метода:
public void valueBound(событие HttpSessionBindingEvent)
public void valueUnbound(событие HttpSessionBindingEvent).
При выполнении Session.addAttribute(String,Object), если вы добавили класс, реализующий интерфейс HttpSessionBindingListener в качестве атрибута, Session уведомит об этом. свой класс и вызовите метод valueBound. Напротив, метод Session.removeAttribute соответствует методу valueUndound.
общедоступный класс HttpSessionBinding реализует javax.servlet.http.HttpSessionBindingListener
{
ServletContext application = null;
public HttpSessionBinding(
ServletContext application)
{
super();
if (application == null)
throw new IllegalArgumentException («Нулевое приложение не принимается».);
.application = application;
}
public void valueBound(javax.servlet.http.HttpSessionBindingEvent e)
{
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
activeSessions = new Vector();
}
JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
if (sessionUser != null)
{
activeSessions.add(e.getSession())
;
application.setAttribute("activeSessions",activeSessions) }
public void valueUnbound(javax.servlet.http.HttpSessionBindingEvent e)
{
JDBCUser sessionUser = (JDBCUser)e.getSession().getAttribute("user");
if
(sessionUser == null)
{
Vector activeSessions = (Vector) application; .getAttribute("activeSessions");
if (activeSessions != null)
{
activeSessions.remove(e.getSession().getId());
application.setAttribute
(
"activeSessions",activeSessions);
Предположим
, что JDBCUser
;
Класс — произвольный класс пользователя. При выполнении входа пользователя добавьте в сеанс класс User и класс HttpSessionBinding.
Таким образом, каждый раз, когда пользователь входит в систему, запись будет добавляться к вектору атрибута «activeSessions» в приложении. Всякий раз, когда истекает время сеанса, срабатывает valueUnbound, и сеанс, для которого истекло время ожидания, удаляется из этого вектора.
public void login()
генерирует ACLException,SQLException,IOException
{
/* get JDBC User Class */
if (user != null )
{
logout ();
}
{
// если время сеанса истекло или пользователь не вошел в систему, временно сохраните целевой URL-адрес
JDBCUserFactory uf = new JDBCUserFactory();
if ( (this.request.getParameter("userID")= =null) || (this.request.getParameter("password")==null) )
{
throw new ACLException("Введите допустимое имя пользователя и пароль.");
JDBCUser
user = (JDBCUser) uf.UserLogin(
this .request.getParameter("userID"),
this.request.getParameter("пароль") );
user.touchLoginTime();
this.session.setAttribute("user",user);
this.session.setAttribute("BindingNotify" ,new HttpSessionBinding (application));
}
}
При входе в систему добавьте в сеанс пользователя и целевой класс BindingNotofy. При выходе из системы вы должны активно удалить сеанс в векторе activeSessions.
public void logout()
выдает SQLException,ACLException
{
if (this.user == null && this.session.getAttribute("user")==null)
{
return ;
}
Vector activeSessions = (Vector) this.application.getAttribute("activeSessions");
if (activeSessions!= null)
{
activeSessions.remove(this.session);
application.setAttribute("activeSessions",activeSessions }
java
. util.Enumeration e = this.session.getAttributeNames();
while (e.hasMoreElements())
{
String s = (String)e.nextElement();
this.session.removeAttribute(s);
}
this.user.touchLogoutTime( );
this.user = null;
}
Эти две функции находятся в классе HttpSessionManager. Этот класс относится к глобальному объекту приложения в jsp. Другой код этого класса не имеет отношения к этой статье и довольно длинный, поэтому выкладывать его не буду.
Давайте посмотрим, как использовать его в JSP.
Предположим, что форма входа отправлена в doLogin.jsp и содержит поля имени пользователя и пароля. Отрывок:
<%
HttpSessionManagerhsm
= new HttpSessionManager(application,request,response);
try
{
hsm.login
(
)
;
.");
return;
}
catch (InvalidPasswordException e2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch (Exception e3)
{
%> Ошибка:<%=e3. toString( ) %><br>
Нажмите <a href="login.jsp">Here</a>, чтобы перезайти.
<% return
}
response.sendRedirect("index.jsp");
Давайте
посмотрим, что мы делаем. have now Как получить список пользователей, которые в данный момент находятся в сети.
<body bgcolor="#FFFFFF">
<table cellpacing="0" cellpadding="0" width="100%">
<tr >
<td style="width:24px">SessionId
</td>
<td style= "width:80px" >Пользователь
</td>
<td style="width:80px" >Время входа
</td>
<td style="width:80px" >Время последнего доступа
</td>
</tr>
<%
Vector activeSessions = (Vector) application.getAttribute("activeSessions");
if (activeSessions == null)
{
activeSessions = new Vector();
application.setAttribute("activeSessions",activeSessions
}
Iterator it = activeSessions.iterator()); ;
while (it.hasNext())
{
HttpSession sess = (HttpSession)it.next();
JDBCUser sessionUser = (JDBCUser)sess.getAttribute("user");
String userId = (sessionUser!=null)?sessionUser.getUserID ():"Нет";
%>
<tr>
<td nowrap=''><%= sess.getId() %></td>
<td nowrap=''><%= userId %></td>
<td nowrap=''>
<%= BeaconDate.getInstance( new Java.util.Date(sess.getCreationTime())).getDateTimeString()%></td>
<td class="<%= stl %>3 " nowrap=''>
<%= BeaconDate.getInstance( new java.util.Date(sess.getLastAccessedTime())).getDateTimeString()%></td>
</tr>
<%
}
%>
</table>
</body>
Приведенный выше код извлекает активные сеансы из приложения и отображает конкретное время. Предполагается, что класс BeaconDate является форматированным классом времени.
Таким образом, мы получаем основу для просмотра списка онлайн-пользователей. Что касается пейджинга онлайн-списков пользователей и других функций, они не имеют отношения к этой статье и обсуждаться не будут.
Это пример модели без обновления, основанной на механизме тайм-аута сеанса. Мой коллега из Sonymusic отметил, что во многих случаях это может быть ненадежно из-за разных идей каждого производителя. Учитывая это требование, необходимо определить, превышает ли время с момента последнего использования текущим пользователем заданное значение времени, когда обновляется каждая листовая поверхность. По сути, это реализация тайм-аута сеанса самостоятельно. Если вам нужно реализовать модель обновления, вы должны использовать этот метод оценки обновления для каждой конечной поверхности.