떠오르는 스타로서 JSP는 서버 프로그래밍 환경에서 특정 위치를 차지할 수 있으며 이는 일련의 업계 표준에 대한 우수한 지원과 밀접한 관련이 있습니다. 세션은 세션이 제공하는 인프라 중 하나입니다. 프로그래머는 클라이언트에서 어떻게 구현되는지 걱정하지 않고 간단한 세션 기반 사용자 관리를 쉽게 구현할 수 있습니다. 요즘에는 온라인 사용자를 대하는 방법이 몇 가지 있습니다.
하나는 페이지 새로 고침을 사용자가 제어하고, 시간이 지나도 아무런 조치가 없으면 서버가 30분 등의 시간 초과를 제어한다는 것입니다. 이 방법의 장점은 사용자가 로그아웃하는 것을 잊어버린 경우에도 다른 사람의 악의적인 작업을 방지할 수 있다는 것입니다. 단점은 시간이 많이 걸리고 이 제한 시간을 초과하는 작업을 수행하는 경우 제출 시 다시 로그인해야 할 수도 있다는 것입니다. 원래 잎 표면이 다시 손상될 경우, 수행한 작업이 손실될 수 있습니다. 구현 관점에서 볼 때 이것이 가장 간단하며 서버 측에서는 기본적으로 이 모드를 구현합니다.
또 다른 방법은 사이트가 프레임 구조를 채택하고 지속적으로 새로 고쳐지는 프레임 또는 숨겨진 iframe이 있으므로 절대로 쫓겨나지 않는 것입니다. 그러나 온라인 상태인지 확인하려면 서버에서 설정해야 합니다. 이 멍하니 시간을 초과할 경우, 자동으로 새로 고쳐지는 페이지 외에 다른 페이지를 새로 고치지 않으면 더 이상 온라인 상태가 아닌 것으로 간주됩니다. 이 접근 방식의 일반적인 예는 xici.net입니다. 장점은 지속적인 새로 고침을 사용하여 네티즌 간 메시지 전송과 같은 서버 푸시와 유사한 일부 기능을 구현할 수 있다는 것입니다.
어떤 모드를 사용하든 현재 모든 온라인 사용자를 검색하려면 몇 가지 추가 작업을 수행해야 합니다. Servlet API에는 세션 목록을 가져오는 API가 없습니다.
여기서 사용할 수 있는 것은 Listener 입니다. Servlet 2.2와 2.3의 사양은 약간 다릅니다. 2.2의 HttpSessionBindingListener는 HTTPSession의 속성이 변경될 때 이를 알려주는 클래스를 구현할 수 있습니다.
HttpSessionAttributeListener는 2.3에도 도입되었습니다. 제가 사용하고 있는 환경은 Java 4및
JRun 서버 3.1용이므로 Servlet 2.3 프로그래밍을 직접 지원하지 않습니다. 여기서는 HttpSessionBindingListener를 사용합니다.
HttpSessionBindingListener 인터페이스를 구현합니다. 이 인터페이스에는 두 가지 메소드가 있습니다.
public void valueBound(HttpSessionBindingEvent event)
public void valueUnbound(HttpSessionBindingEvent event)
Session.addAttribute(String,Object)를 실행할 때 HttpSessionBindingListener 인터페이스를 구현하는 클래스를 속성으로 추가한 경우 Session이 이를 알립니다. 클래스를 만들고 valueBound 메서드를 호출하세요. 반대로 Session.removeAttribute 메소드는 valueUndound 메소드에 해당합니다.
public class HttpSessionBinding은 javax.servlet.http.HttpSessionBindingListener를 구현합니다.
{
ServletContext application = null;
public HttpSessionBinding(ServletContext application)
{
super();
if (application ==null)
throw new IllegalArgumentException("Null 응용 프로그램은 허용되지 않습니다.")
; .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 = (벡터) 애플리케이션 .getAttribute("activeSessions");
if (activeSessions != null)
{
activeSessions.remove(e.getSession().getId());
application.setAttribute("
activeSessions",activeSessions)
}
}
}
}
클래스는 임의의 사용자 클래스입니다. 사용자 로그인을 수행할 때 User 클래스와 HttpSessionBinding 클래스를 모두 Session에 추가합니다.
이러한 방식으로 사용자가 로그인할 때마다 애플리케이션의 "activeSessions" 속성 벡터에 레코드가 추가됩니다. 세션 시간이 초과될 때마다 valueUnbound가 트리거되고 시간 초과될 세션이 이 벡터에서 삭제됩니다.
public void login()
throws ACLException,SQLException,IOException
{
/* get JDBC User Class */
if (user != null )
{
logout ();
}
{
// 세션 시간이 초과되거나 사용자가 로그인하지 않은 경우
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("password") );
user.touchLoginTime()
this.session.setAttribute
("user",user);
,new HttpSessionBinding (application));
}
}
로그인할 때 User 및 BindingNotofy 목적 클래스를 세션에 추가합니다. 로그아웃할 때 activeSessions 벡터에서 세션을 적극적으로 삭제해야 합니다.
public void logout()
throws SQLException,ACLException
{
if (this.user == null && this.session.getAttribute("user")==null)
{
return ;
}
Vector activeSessions = (벡터) this.application.getAttribute("activeSessions");
if
(activeSessions
!= null)
{
activeSessions.remove(this.session);
application.setAttribute("activeSessions",activeSessions);
util.Enumeration e = this.session.getAttributeNames();
while (e.hasMoreElements())
{
String s = (String)e.nextElement();
this.session.removeAttribute
(s)
; );
this.user = null;
}
이 두 함수는 HttpSessionManager 클래스에 있습니다. 이 클래스는 jsp의 애플리케이션 전역 개체를 참조합니다. 이 클래스의 다른 코드는 이 글과 관련이 없고 내용이 꽤 길어서 포스팅하지 않겠습니다.
JSP에서 어떻게 사용하는지 살펴보겠습니다.
로그인 양식이 doLogin.jsp에 제출되고 양식에 UserName 및 비밀번호 필드가 포함되어 있다고 가정하십시오. 발췌:
<%
HttpSessionManager hsm = new HttpSessionManager(application,request,response);
try
{
hsm.login();
}
catch (UserNotFoundException e)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=User%20does%20not %20exist .");
return;
}
catch(InvalidPasswordException e2)
{
response.sendRedirect("InsufficientPrivilege.jsp?detail=Invalid%20Password");
return;
}
catch(예외 e3)
{
%> 오류:<%=e3.toString( ) %><br>
<a href="login.jsp">여기
</a>를 눌러 다시 로그인하세요.
<% return;
}
response.sendRedirect
("index.jsp");
지금 현재 온라인 사용자 목록을 얻는 방법.
<body bgcolor="#FFFFFF">
<tablecellspacing="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 = (벡터) 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>
위의 코드는 애플리케이션에서 activeSessions를 검색하고 특정 시간을 표시합니다. BeaconDate 클래스는 형식화된 시간 클래스로 간주됩니다.
이런 방식으로 우리는 온라인 사용자 목록을 보기 위한 프레임워크를 얻습니다. 온라인 사용자 목록 페이징 및 기타 기능은 이 기사와 관련이 없으므로 논의하지 않습니다.
이는 세션 시간 초과 메커니즘에 의존하는 새로 고침되지 않는 모델의 예입니다. 내 동료 sonymusic은 각 제조업체의 아이디어가 다르기 때문에 이것이 신뢰할 수 없는 경우가 많다고 지적했습니다. 이러한 요구사항을 고려하면, 각 잎 표면을 새로 고칠 때 현재 사용자가 마지막으로 사용한 이후의 시간이 미리 정해진 시간 값을 초과하는지 여부를 판단할 필요가 있다. 이는 본질적으로 세션 시간 초과를 직접 구현하는 것입니다. 새로 고침 모델을 구현해야 하는 경우 각 잎 표면에 대한 새로 고침을 판단하는 이 방법을 사용해야 합니다.