您的位置:首页 > 编程语言 > Java开发

JavaWeb实例:记录在线人员信息,管理员可以踢人

2016-12-17 11:07 453 查看

总的需求:

1、使用HttpSessionListener记录在线人数。
2、使用HttpSessionAttributeListener记录登录人数。
3、 将用户踢出系统。

成果展示:

主页登录



登录成功:



显示所有在线用户:若是管理员则



普通用户登录:



好了。。代码奉上:

canOnlineWeb

index.jsp 主页
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录页面</title>
</head>

<body>
<h2>一个综合示例,jsp+jstl+servlet+filter+listener</h2>
<c:if test="${empty sessionScope.user }" var="boo">
<form action="<c:url value='/LoginServlet' />" method="post">
用户名:<input type="text" name="name"><br/>
<input type="submit" value="登录">
</form>
</c:if>
<c:if test="${!boo }">
欢迎您.${sessionScope.user.name}!
<a href="<c:url value='/servlet/ShowServlet' />" >显示所有在线用户</a>
<a href="<c:url value='/servlet/LoginOutServlet' />">安全退出</a>
</c:if>
</body>
</html>


两个过滤器:字符过滤器和登录过滤器

CharacterFilter.java
package cn.hncu.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class CharacterFilter implements Filter{
String charset;
@Override
public void init(FilterConfig config) throws ServletException {
charset=config.getInitParameter("charset");
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/*
* 因为Map里面封装的session对象无法拿到用户的ip,而request可以拿到(包括游客)
* 所以为了实现能在ShowServlet中显示所有在线用户,可以在一个拦截路径为"/*"的过滤器中把ip信息封装到
* session中,然后在ShowServlet中从session对象中读取出来
*/
request.setCharacterEncoding(charset);//这里更灵活,应让用户在xml中配置编码
HttpSession session=((HttpServletRequest)request).getSession();
if(session.getAttribute("ip")==null){
session.setAttribute("ip", request.getRemoteAddr());
}

chain.doFilter(request, response);
}

@Override
public void destroy() {
}

}


LoginFilter.java
package cn.hncu.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginFilter implements Filter{

@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response;

if(req.getSession().getAttribute("user")==null){
resp.sendRedirect(req.getContextPath()+"/index.jsp");
}else{
//对已登录用户放行
chain.doFilter(request, response);
}
}

@Override
public void destroy() {
}

}


LoginServlet.java 登录的servlet
package cn.hncu.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.domain.User;
import cn.hncu.service.IUserService;
import cn.hncu.service.IUserServiceImpl;

public class LoginServlet extends HttpServlet {
IUserService service=new IUserServiceImpl();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//封装数据用对象
String name=request.getParameter("name");
User user=new User();
user.setName(name);

user=service.login(user);
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
}


service层

IUserService.java
package cn.hncu.service;

import cn.hncu.domain.User;

public interface IUserService {
public User login(User user);
}


IUserServiceImpl.java
package cn.hncu.service;

import java.util.Random;

import cn.hncu.domain.User;

public class IUserServiceImpl implements IUserService{
//这里是service层,用户登录的时候应该去后台查找数据库验证,这里省略了
@Override
public User login(User user) {
Random r=new Random();
int n=r.nextInt(10);
if(n%2==0){//若为偶数,则设为管理员
user.setAdmin(true);
}
return user;
}

}


ShowServlet.java 显示所有用户时,封装数据的servlet
package cn.hncu.servlets;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.hncu.domain.User;

public class ShowServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

Map<String, HttpSession> onLines=(Map<String, HttpSession>) request.getSession().getServletContext().getAttribute("onLines");
List<Map<String,Object>> users=new ArrayList<Map<String,Object>>();
if(onLines!=null){
Collection<HttpSession> sessions=onLines.values();
for(HttpSession s:sessions){
Map<String, Object> map=new HashMap<String, Object>();
map.put("id", s.getId());
User user=(User) s.getAttribute("user");
map.put("user", user);
map.put("creationTime", new Date(s.getCreationTime()));
map.put("lastAccessedTime", new Date(s.getLastAccessedTime()));
map.put("ip", s.getAttribute("ip"));
users.add(map);
}
}
request.setAttribute("users", users);

//		//从web容器中取出的在线用户集合onLines1---Map<sessionId,session对象>
//				Map<String, HttpSession> onLines1 = (Map<String, HttpSession>) getServletContext().getAttribute("onLines");
//
//				//要给show.jsp显示的在线用户集合onLines---List<每个在线用户>  ,每个在线用户--map.put("name","Jack"),map.put("ip","127.0.0.1")
//				//下面这一段是封装onLines
//				List<Map<String,Object>> onLines = new ArrayList<Map<String,Object>>();
//				Iterator<Entry<String, HttpSession>> it = onLines1.entrySet().iterator();
//				while(it.hasNext()){
//					Entry<String, HttpSession> en = it.next();
//					HttpSession session = en.getValue();
//					Map<String,Object> userMap = new HashMap<String, Object>();
//					userMap.put("id", en.getKey());
//					User user = (User) session.getAttribute("user");
//					userMap.put("user", user);
//
//					/*
//					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//					String creationTime = sdf.format(new Date(session.getCreationTime()));
//					userMap.put("creationTime",creationTime );
//					*/
//					userMap.put("creationTime", new Date(session.getCreationTime()));
//					userMap.put("lastAccessedTime", new Date(session.getLastAccessedTime()));
//					userMap.put("ip", session.getAttribute("ip"));
//
//					onLines.add(userMap);
//				}
//
//		request.setAttribute("users", onLines);
//		System.out.println(onLines);
request.getRequestDispatcher("/jsps/show.jsp").forward(request, response);
}

}


Show.jsp 显示所有在线用户
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>在线用户页面</title>
<style type="text/css">
table{
border:1px solid blue;
border-collapse: collapse;
width:70%;
}
th,td{
border:1px solid blue;
}
.head{
background-color: green;
}
</style>
</head>

<body>
<table>
<tr class="head">
<th>姓名</th><th>上线时间</th><th>最近一次上线时间</th><th>IP</th><th>操作</th>
</tr>
<c:forEach items="${users}" var="map">
<tr>
<td>
<c:if test="${!empty map.user.name}" var="boo">${map.user.name}</c:if>
<c:if test="${!boo}">游客</c:if>
</td>
<td>
<fmt:formatDate value="${map.creationTime}" pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
<td>
<fmt:formatDate value="${map.lastAccessedTime}" pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
<td>${map.ip}</td><td>
<c:if test="${sessionScope.user.admin}">
<c:if test="${sessionScope.user.name!=map.user.name}" var="am">
<a href="<c:url value='/servlet/KickOutServlet?id=${map.id }'/>" >踢出</a>
</c:if>
<c:if test="${!am}">
管理员
</c:if>
</</c:if>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>


LoginOutServlet.java 安全退出
package cn.hncu.servlets;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginOutServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getSession().invalidate();
response.sendRedirect(request.getContextPath()+"/index.jsp");
}

}


KickOutServlet.java 管理员踢人
package cn.hncu.servlets;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class KickOutServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id=request.getParameter("id");
Map<String, HttpSession> onLines=(Map<String, HttpSession>) request.getServletContext().getAttribute("onLines");
onLines.get(id).invalidate();
response.sendRedirect(request.getContextPath()+"/index.jsp");
}

}


User.java 值对象
package cn.hncu.domain;

import java.io.Serializable;

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;

public class User implements HttpSessionActivationListener,Serializable{
private String id;
private String name;
private Integer age;
private String pwd;
private boolean admin;//是否是管理员,此处有一个小细节,变量名不要取成isAdmin,不然在show.jsp中判断是否是管理员是会出现错误:HTTP Status 500 - javax.el.PropertyNotFoundException: Property 'isAdmin' not found on type cn.hncu.domain.User
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + ", pwd="
+ pwd + ", admin=" + admin + "]";
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("保存到硬盘了...........");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("从硬盘中读取...........");

}

}


MySessionListener.java 监听器,用户池(管理在线用户)
package cn.hncu.listeners;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MySessionListener implements HttpSessionListener,HttpSessionActivationListener,Serializable{
private static final long serialVersionUID = 1L;
private Map<String, HttpSession> onLines;
@Override
public void sessionCreated(HttpSessionEvent se) {
//所有用户在线的池onLines
onLines=(Map<String, HttpSession>) se.getSession().getServletContext().getAttribute("onLines");//如果把null强转给对象,是不会抛异常的,本身对象是可以为null的。但是如果是基本类型,比如 int i = (Integer)obj的强转,其实内部会调用intvalue方法去赋值给基本类型,所以这时候是会报错的。
if(onLines==null){
//使用了同步技术中的一个集合(本例中是Map,可以是List,Set,Collection等)
onLines=Collections.synchronizedMap(new HashMap<String, HttpSession>() );
se.getSession().getServletContext().setAttribute("onLines", onLines);
}
onLines.put(se.getSession().getId(), se.getSession());
//这里对onLines集合进行更改以后不需要从新setAttribute,因为getAttribute("onLines");实际上传递的是一个对象名,也就是在C语言中所说的指针。这里更改了onLines,自然也就更改了Attribute属性值
System.out.println("一个用户上线了....");
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
Map<String, HttpSession> onLines=(Map<String, HttpSession>) se.getSession().getServletContext().getAttribute("onLines");
if(onLines!=null&&onLines.containsKey(se.getSession().getId())){
HttpSession ss=onLines.remove(se.getSession().getId());
System.out.println("一个用户下线了....移除了:"+ss);
}
}

@Override
public void sessionWillPassivate(HttpSessionEvent se) {

}

@Override
public void sessionDidActivate(HttpSessionEvent se) {

}
}


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name>
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>cn.hncu.filters.CharacterFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.hncu.filters.LoginFilter</filter-class>
</filter>

<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.hncu.servlets.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ShowServlet</servlet-name>
<servlet-class>cn.hncu.servlets.ShowServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>LoginOutServlet</servlet-name>
<servlet-class>cn.hncu.servlets.LoginOutServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>KickOutServlet</servlet-name>
<servlet-class>cn.hncu.servlets.KickOutServlet</servlet-class>
</servlet>

<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
<url-pattern>/jsps/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>cn.hncu.listeners.MySessionListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/servlet/ShowServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LoginOutServlet</servlet-name>
<url-pattern>/servlet/LoginOutServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>KickOutServlet</servlet-name>
<url-pattern>/servlet/KickOutServlet</url-pattern>
</servlet-mapping>
<session-config>
<!-- 配置session的有效期:单位(分钟) -->
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>




1. 在监听器中,使用Map<String,HttpSession>,使用JSESSIONID和session进行封装,在显示所有用户的时候,再从session中拿出信息,封装成List<Map<String,Object>>,去Jsp中显示。

2. 在new Map的时候,用到线程锁,用Collections.synchoronizedMap(new HashMap<String,HttpSession>)

3 .jsp中,<fmt:formatDate ........>标签,可将Date型数据,转换成日期
4. 更多的知识点,在代码中已写出

不足:
虽然实现User的session的钝化和活化,但是用户池没实现,等技术高了,再来补。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息