有没有办法确定从给定的客户端IP地址创建的活动会话的数量?
解决方法
标准的Servlet API不提供这样的设施.最好的办法是自己维护一个
Map<HttpSession,String>
(其中String是IP地址),并在每个
ServletRequest
上检查
HttpSession#isNew()
,并将其与
ServletRequest#getRemoteAddr()
一起添加到地图中.然后可以使用一个活动会话在
Map#values()
使用
Collections#frequency()
.您只需确保在
HttpSessionListener#sessionDestroyed()
期间从地图中删除HttpSession.
这一切都可以在实现ServletContextListener
,HttpSessionListener
和ServletRequestListener
的单个监听器中完成.
这是一个开球示例:
public class SessionCounter implements ServletContextListener,HttpSessionListener,ServletRequestListener { private static final String ATTRIBUTE_NAME = "com.example.SessionCounter"; private Map<HttpSession,String> sessions = new ConcurrentHashMap<HttpSession,String>(); @Override public void contextInitialized(ServletContextEvent event) { event.getServletContext().setAttribute(ATTRIBUTE_NAME,this); } @Override public void requestInitialized(ServletRequestEvent event) { HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); HttpSession session = request.getSession(); if (session.isNew()) { sessions.put(session,request.getRemoteAddr()); } } @Override public void sessionDestroyed(HttpSessionEvent event) { sessions.remove(event.getSession()); } @Override public void sessionCreated(HttpSessionEvent event) { // NOOP. Useless since we can't obtain IP here. } @Override public void requestDestroyed(ServletRequestEvent event) { // NOOP. No logic needed. } @Override public void contextDestroyed(ServletContextEvent event) { // NOOP. No logic needed. Maybe some future cleanup? } public static SessionCounter getInstance(ServletContext context) { return (SessionCounter) context.getAttribute(ATTRIBUTE_NAME); } public int getCount(String remoteAddr) { return Collections.frequency(sessions.values(),remoteAddr); } }
在web.xml中定义如下:
<listener> <listener-class>com.example.SessionCounter</listener-class> </listener>
您可以在任何servlet中使用它,如下所示:
SessionCounter counter = SessionCounter.getInstance(getServletContext()); int count = counter.getCount("127.0.0.1");