美文网首页经典好文
2016.10.12日--利用servlet监听器实现用户在线人

2016.10.12日--利用servlet监听器实现用户在线人

作者: LH_0811 | 来源:发表于2016-10-12 16:04 被阅读2509次

servlet中监听器主要的监听对象有三个:
ServletContext HttpSession ServletRequest.
分别可以监听三个对象的创建 销毁,以及属性的更改。

=========================================
实现监听在线人数:

在开始实现功能之前首先创建一个用户模型,为了区别每个用户,我们用sessionId来作为一个用户的id,代码实现:

package model;

public class User {
    private String ipStr;
    private String address;
    private String sessionId;
    
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public String getIpStr() {
        return ipStr;
    }
    public void setIpStr(String ipStr) {
        this.ipStr = ipStr;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    
    
}

第一步:创建出存放在线用户的容器

当应用服务一旦启动,就创建出一个容器来存放在线的人数。这里使用到ServletContextListener。实现这个接口的监听器将监听到我们的服务器程序的启动和销毁。代码实现:

package listener;

import java.util.ArrayList;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import model.User;

@WebListener
public class MyServletContextListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println("===================servlet 服务销毁===================");
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext context = event.getServletContext();
        ArrayList<User> userList = new ArrayList<>();
        context.setAttribute("userList", userList);
        System.out.println("===================servlet 服务启动===================");
    }

}

把用户列表存放到servletContext这个对象中,这个对象的生命周期是整个服务程序的生命周期。

第二步:获得每个用户,并存放到容器中。

在一般的web程序中,用户一旦登录,我们会把用户的信息存放到session对象中。当用户退出登录时,从session对象中移除我们的用户信息。为了获取到用户的ip地址等详细信息。要用到ServletRequestListener这个接口。代码实现:

package listener;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import model.User;


@WebListener
public class MyHttpRequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent event) {
        System.out.println("===================一个request销毁===================");
    }

    @Override
    public void requestInitialized(ServletRequestEvent event) {
        System.out.println("===================一个request创建===================");
        
        HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
        HttpSession session = request.getSession();
        ServletContext app = session.getServletContext();
        ArrayList<User> userList = (ArrayList<User>) app.getAttribute("userList");
        //遍历用户列表,如果用户已经存放就不做操作
        for (User user : userList) {
        //这里用sessionID来模拟一个登陆的用户,正常应该是从session中getAttribute 到当前登录的用户
            if(user.getSessionId().equals(session.getId())){
                return;
            }
        }
        //如果用户没有存放到我们的容器中,就吧这个用户存放到容器里面。这里只是模拟生成了一个用户。正常应该是直接把用户存放到servletContext 的 userList 这个容器中就可以了。
        User currentUser = new User();
        try {
            currentUser.setIpStr(InetAddress.getLocalHost().getHostAddress());
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        currentUser.setSessionId(session.getId());
        currentUser.setAddress("test");
        URL url = null;
        URLConnection connection = null;
        try {
            url = new URL("http://ip.taobao.com/service/getIpInfo.php?ip="+currentUser.getIpStr());
            connection = url.openConnection();
            connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒  
               connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒  
               connection.setDoOutput(true);// 是否打开输出流 true|false  
               connection.setDoInput(true);// 是否打开输入流true|false  
               connection.setUseCaches(false);// 是否缓存true|false  
               connection.connect();// 打开连接端口  
               DataOutputStream out = new DataOutputStream(connection  
                 .getOutputStream());// 打开输出流往对端服务器写数据  
                 
               out.flush();// 刷新  
               out.close();// 关闭输出流  
               BufferedReader reader = new BufferedReader(new InputStreamReader(  
                 connection.getInputStream(), "gbk"));// 往对端写完数据对端服务器返回数据  
               // ,以BufferedReader流来读取  
               StringBuffer buffer = new StringBuffer();  
               String line = "";  
               while ((line = reader.readLine()) != null) {  
                buffer.append(line);  
               }  
               reader.close();
               
               currentUser.setAddress(buffer.toString());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        userList.add(currentUser);
        app.setAttribute("userList", userList);
        
    }

}

第三步:当用户退出后,从容器中移除用户

这里我们要监听到session的生命周期,用到HttpSessionListener这个接口。如果实现用户一段时间内不操作,销毁session的话要在web.xml中配置session超时:

<session-config> 
    <session-timeout>1</session-timeout>
   </session-config>

HttpSessionListener,代码实现:

package listener;

import java.util.ArrayList;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import model.User;

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("===================一个session创建===================");
        
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        
        HttpSession session = event.getSession();
        @SuppressWarnings("unchecked")
        ArrayList<User> userList =(ArrayList<User>) session.getServletContext().getAttribute("userList");
        ArrayList<User> newUserList = new ArrayList<>();
        for (User user : userList) {
            if (! user.getSessionId().equals(session.getId())) {
                newUserList.add(user);
            }
        }
        session.getServletContext().setAttribute("userList", newUserList);
        System.out.println("===================一个session销毁===================");
    }

}

至此大概思路已经完成。剩下的操作,按照需求完善。

相关文章

网友评论

    本文标题:2016.10.12日--利用servlet监听器实现用户在线人

    本文链接:https://www.haomeiwen.com/subject/lfuiyttx.html