描述:用户登陆后才算在线,管理员存在一个踢人的功能。
//登陆servlet
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if(username==null || username.trim().equals("")) {
request.setAttribute("message", "用户名或密码错");
request.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setUsername(username);
user.setPassword(password);
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath());
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//退出servlet
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getSession().removeAttribute("user");
response.sendRedirect(request.getContextPath());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//踢人servlet
public class KickServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 踢人: 既要讲其从在线列表中删除还要将当前用户注销,也就是移除登陆标记
// 获得点击踢人超链接后带过来的参数id
String id = request.getParameter("id");
// 调用 列表的方法 踢人
OnlineUserList.INSTANCE.kick(id);
response.sendRedirect(request.getContextPath() + "/servlet/ShowOnlineuserServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//查看在线用户servlet
public class ShowOnlineuserServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获得列表后添加到request域中交给jsp进行显示
Collection<User> onlineUsers = OnlineUserList.INSTANCE.getOnlineUsers();
request.setAttribute("onlineUsers", onlineUsers);
request.getRequestDispatcher("/show.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//javabean实现了HttpSessionBindingListener接口后,就可以感知到当javabean加入session后触发
//这个user对象既是事件又是事件源,也就是自己监视自己,这样就不用在web.xml中进行描述了
public class User implements HttpSessionBindingListener {
private String id;
private String username;
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// 当前user对象被绑定到 session后触发
public void valueBound(HttpSessionBindingEvent event) {
// 将 user 存入一个用户列表
OnlineUserList.INSTANCE.addUser(this, event.getSession());
}
// 当前user对象被从session中移除后触发
public void valueUnbound(HttpSessionBindingEvent event) {
// 将 user 从用户列表中移除
OnlineUserList.INSTANCE.removeUser(this);
}
}
// 记录在线用户列表
public class OnlineUserList {
//单利设计模式,为了维护一个map
private OnlineUserList() {}
public final static OnlineUserList INSTANCE = new OnlineUserList();
//用map不用list的主要原因是当踢人的时候还要讲其在域中的登陆标记移除,在map中可以很快定位到哪个user对应哪个session
private Map<User, HttpSession> onlineUsers = new HashMap<User, HttpSession>();
//提供向map中加入session的方法,以user为key
public void addUser(User user, HttpSession session) {
onlineUsers.put(user, session);
}
//提供向map中移除session的方法,以user为key
public void removeUser(User user) {
onlineUsers.remove(user);
}
//此方法用于迭代出来在线用户列表返回值为Collection为多态
//在写单列集合的时候应劲量避免写list和set,要用Collection
public Collection<User> getOnlineUsers() {
Set<User> users = onlineUsers.keySet();
return users;
}
// 踢人: 将当前用户注销
public void kick(String id) {
// 在集合的迭代元素的期间不能随意增删元素,由于增强for循环用到了Iterator,所以不能增删
//可以用到listIterator,也可在增删后加上break语句。
for(User user : onlineUsers.keySet()) {
if(id.equals(user.getId())) {
// 将 user 从 session 中移除
HttpSession session = onlineUsers.get(user);
//这里就不用再将user从列表中移除了,因为从session中移除的时候会触发监听器的处理器,处理器中就将其从列表中删除了
session.removeAttribute("user");
break;
}
}
}
}