一.思路分析
统计其IP的数量,将IP的数量作为当前的在线人数,那么如何统计IP的数量呢?
这样将会导出以下问题:
1 如何获取用户的IP?
2 .IP将如何存储?
3 .如何判断IP之前已经存在?
现在来解决这些问题:
只能从请求中获取
通过2、3问题,我们想到了集合(List),因为集合不仅可以存储任何字符串,还可以通过遍历来判断之前是否有重复的IP出现。
到了这里又冒出来一个问题集合(List)放到哪个域里呢?
二. 代码实现:
( 1 ) ServletContext 域[ ServletContextListener ]
import javax. servlet. ServletContext ;
import javax. servlet. ServletContextEvent ;
import javax. servlet. ServletContextListener ;
import javax. servlet. annotation. WebListener ;
import javax. servlet. http. * ;
import java. util. ArrayList ;
import java. util. HashMap ;
import java. util. List ;
import java. util. Map ;
@WebListener ( )
public class MyServletContextListener implements ServletContextListener {
private ServletContext sc;
@Override
public void contextInitialized ( ServletContextEvent sce) {
Map < String , List < HttpSession > > map = new HashMap < > ( ) ;
sc = sce. getServletContext ( ) ;
sc. setAttribute ( "map" , map) ;
}
}
( 2 ) 由于IP只能在Request 域中获取,所以遍历判断在Request 域中进行:
import javax. servlet. * ;
import javax. servlet. annotation. WebListener ;
import javax. servlet. http. * ;
import java. util. ArrayList ;
import java. util. List ;
import java. util. Map ;
@WebListener ( )
public class MyRequestListener implements ServletRequestListener {
private HttpServletRequest sr;
private String clientIp;
private ServletContext sc;
private List < String > ips;
private HttpSession currentSession;
private Map < String , List < HttpSession > > map;
private List < HttpSession > sessions;
@Override
public void requestInitialized ( ServletRequestEvent sre) {
sr = ( HttpServletRequest ) sre. getServletRequest ( ) ;
clientIp = sr. getRemoteAddr ( ) ;
currentSession = sr. getSession ( ) ;
sc = sre. getServletContext ( ) ;
map = ( Map < String , List < HttpSession > > ) sc. getAttribute ( "map" ) ;
sessions = map. get ( clientIp) ;
if ( sessions == null ) {
sessions = new ArrayList < > ( ) ;
}
for ( HttpSession session : sessions) {
if ( session == currentSession)
return ;
}
sessions. add ( currentSession) ;
map. put ( clientIp, sessions) ;
sc. setAttribute ( "map" , map) ;
currentSession. setAttribute ( "clientIp" , clientIp) ;
}
}
( 3 ) 因为要统计在线人数,所以要设置退出按钮,点击退出按钮之后,
因为要从List 域中移除,所以使用Session 域监听器来判断session回话的关闭
import javax. servlet. ServletContext ;
import javax. servlet. ServletContextEvent ;
import javax. servlet. ServletContextListener ;
import javax. servlet. annotation. WebListener ;
import javax. servlet. http. * ;
import java. util. List ;
import java. util. Map ;
@WebListener ( )
public class MySessionListener implements HttpSessionListener {
private ServletContext sc;
private List < String > ips;
private HttpSession currentSession;
private String clientIp;
private Map < String , List < HttpSession > > map;
private List < HttpSession > sessions;
@Override
public void sessionDestroyed ( HttpSessionEvent se) {
sc = se. getSession ( ) . getServletContext ( ) ;
currentSession = se. getSession ( ) ;
clientIp = ( String ) currentSession. getAttribute ( "clientIp" ) ;
map = ( Map < String , List < HttpSession > > ) sc. getAttribute ( "map" ) ;
sessions = map. get ( clientIp) ;
sessions. remove ( currentSession) ;
if ( sessions. size ( ) == 0 ) {
map. remove ( clientIp) ;
} else {
map. put ( clientIp, sessions) ;
}
sc. setAttribute ( "map" , map) ;
}
}
( 4 ) 此处代码是页面点击关闭后,激活的退出方法
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import javax. servlet. http. HttpSession ;
import java. io. IOException ;
@WebServlet ( name = "LogoutServlet" , urlPatterns = "/logoutServlet" )
public class LogoutServlet extends HttpServlet {
private HttpSession session;
protected void doPost ( HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException {
session = request. getSession ( false ) ;
if ( session != null ) {
session. invalidate ( ) ;
}
}
protected void doGet ( HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException {
doPost ( request, response) ;
}
}
@GetMapping ( "/logoutServlet" )
public String logoutServlet ( HttpSession session, HttpServletRequest request) {
session = request. getSession ( false ) ;
if ( session != null ) {
session. invalidate ( ) ;
}
}
前端显示:
< center>
< h1 > You are the ${applicationScope.map.size()} customer to visit. < /h1 >< br>
< h3 >< a href = "${pageContext.request.contextPath} /logoutServlet" > 安全退出< /a> < br> < /h3 >
< h2 >< c:forEach items = "${map} " var = "entry" > ${entry.key } = ${entry.value.size()} < br> < /c:forEach> < /h2 >
< /center>
You are the 3 customer to visit.
172.0 .0.1= 1
127.0 .0.1= 1
0.0 .0.0= 1