JavaWeb-网站在线用户信息、网站访问量以及管理踢出用户实例

简介: 转载请注明出处: http://blog.csdn.net/qq_26525215本文源自【大学之旅_谙忆的博客】这个稍微比上个版本做得完善了一点,用了JavaBean来封装用户信息,添加了一个管理踢用户的功能。

转载请注明出处: http://blog.csdn.net/qq_26525215
本文源自大学之旅_谙忆的博客

这个稍微比上个版本做得完善了一点,用了JavaBean来封装用户信息,添加了一个管理踢用户的功能。
上一个的用户访问量是通过监听request来统计的,在这个实例中,我们也可以通过过滤器来实现统计网站访问量。

直接看源码吧,感觉没多少要讲的,我习惯把解释写在代码中。

部分源码

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>在线人信息管理与统计</h2>

    <c:if test="${empty sessionScope.user}" var="boo">
        <h3>会员登录:</h3>
        <form action='<c:url value='/LoginServlet'></c:url>' method="post">
            姓名:<input type='text' name="name"><br /> <input type="submit"
                value="注册">
        </form>
    </c:if>

    <c:if test="${!boo}">
        亲爱的${user.name}
        <c:if test="${user.admin}" var="bo">
            -管理员
        </c:if>
        <c:if test="${!bo}">
            -会员
        </c:if>
        ,欢迎来到...<br />
    </c:if>

    <br />
    <a href="<c:url value='/servlet/ShowServlet'/>">显示所有在线用户</a>
    <br />
    <a href="<c:url value='/servlet/LogOutServlet'/>">安全退出</a>

    <br/>网站访问量:${count}

</body>
</html>

MyServletContextListener

这个就是实现把访问量持久化的监听器实现类:

package cn.hncu.listeners;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

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

public class MyServletContextListener implements ServletContextListener{

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //从服务器硬盘把之前存储的点击量数据读取出来
        ServletContext sct = sce.getServletContext();
        String path = sct.getRealPath("/count.txt");
        try {
            BufferedReader br = new BufferedReader(new FileReader(path));
            String line = br.readLine();
            Integer count = Integer.valueOf(line);
            sct.setAttribute("count", count);
        } catch (Exception e) {
            //如果出异常了,我们认为文件还不存在,服务器第一次启动
            e.printStackTrace();
            sct.setAttribute("count",new Integer(0));
        }

    }

    //关闭服务器时
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //把当前servletContext容器中存储的点击量数据 永久化到  服务器硬盘
        ServletContext sct = sce.getServletContext();
        String path = sct.getRealPath("/count.txt");

        try {
            PrintWriter pw = new PrintWriter(path);
            pw.write(""+sct.getAttribute("count"));
            pw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


    }

}

CharsetFilter

实现统计访问量和全站编码的过滤器

package cn.hncu.filter;

import java.io.IOException;

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

public class CharsetFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        //获取该用户的ip,存储到它的session对象中
        HttpServletRequest req = (HttpServletRequest) request;
        if(req.getSession().getAttribute("ip")==null){
            req.getSession().setAttribute("ip", req.getRemoteAddr());
            //这里的req和request是同一个对象!!!
            //所以传过去的参数还可以是request
        }

        //new一个线程统计访问量
        new MyThread(request.getServletContext()).start();

        //放行
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
    }
}

class MyThread extends Thread{
    private ServletContext servletContext =null;
    private static Object boj = new Object();

    public MyThread(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public void run() {
        synchronized (boj) {
            servletContext.setAttribute("count",(Integer)servletContext.getAttribute("count")+1);
        }
    }

}

LoginFilter

用户访问其他页面时进行的权限过滤:

如果你没有登陆,就不给你权限去访问除主页外的其他页面。

package cn.hncu.filter;

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;
        if(req.getSession().getAttribute("user")==null){
            HttpServletResponse resp = (HttpServletResponse) response;
            resp.sendRedirect(req.getContextPath()+"/index.jsp");
        }else{//放行
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
    }


}

MySessionListener

有用户来访问时,我们就通过监听器去监听session的创建与销毁,在这里,我们认为一个session就是一个用户!

package cn.hncu.listeners;

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

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

public class MySessionListener implements HttpSessionListener{

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        Map<String, HttpSession> onLines = (Map<String, HttpSession>) se.getSession().getServletContext().getAttribute("onLines");
        if(onLines==null){//第一个来访问的
            onLines = Collections.synchronizedMap(new HashMap<String, HttpSession>() );//使用同步技术的Map
            se.getSession().getServletContext().setAttribute("onLines", onLines);
        }
        onLines.put(se.getSession().getId(), se.getSession());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        Map<String, HttpSession> onLines = (Map<String, HttpSession>) se.getSession().getServletContext().getAttribute("onLines");
        //这里也要防范好!多线程,多个管理同时踢一个人的时候,如果不防范就会出问题
        if(onLines.containsKey( se.getSession().getId() )){
            onLines.remove( se.getSession().getId() );
        }

    }


}

LoginServlet

用于判断用户登录与设置管理员的servlet。

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;

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

import cn.hncu.domain.User;

public class LoginServlet 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 name = request.getParameter("name");
        if(name!=null && name.trim().length()>0){
            User user = new User();
            user.setName(name);
            //用user作为参数到后台登录,这里我们简化了,直接假设登录成功
            if(true){
                Random r = new Random();
                int a = r.nextInt(2);
                if(a%2==0){
                    user.setAdmin(true);
                }else{
                    user.setAdmin(false);
                }
            }
            request.getSession().setAttribute("user", user);
        }

        response.sendRedirect(request.getContextPath()+"/index.jsp");
    }

}

LogOutServlet

用于用户的安全退出!

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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

public class LogOutServlet 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 {
        //用户安全退出很简单,我们在服务器端移除用户的session就可以了
        request.getSession().invalidate();

        response.sendRedirect(request.getContextPath()+"/index.jsp");
    }
}

ShowServlet

显示所有用户信息时的servlet,需要把信息全部封装到request这个容器中,再转发到前台jsp显示的页面。

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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 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>) getServletContext().getAttribute("onLines"); 

        List<Map<String, Object>> lists = new ArrayList<Map<String,Object>>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //遍历onlines,针对每个session对象封装一个map(信息包含:name,createTime,lastAccessTime,ip),把该map添加到list当中
        Iterator<Entry<String, HttpSession>> it = onLines.entrySet().iterator();
        while(it.hasNext()){
            Entry<String, HttpSession> en = it.next();

            Map<String, Object> m = new HashMap<String, Object>();

            m.put("id", en.getValue().getId() );
            m.put("user", en.getValue().getAttribute("user"));

            String creationTime = sdf.format(new Date(en.getValue().getCreationTime()));
            m.put("creationTime", creationTime);
            String lastAccessTime = sdf.format( new Date(en.getValue().getLastAccessedTime()) );
            m.put("lastAccessTime", lastAccessTime);

             //注意,该ip数据是在CharsetFilter中封装的
            m.put("ip", en.getValue().getAttribute("ip"));

            lists.add(m);
        }

        request.setAttribute("onLines", lists);
        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" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>在线人信息管理</title>
    <style type="text/css">
       table{
          border: 1px solid red;
          border-collapse: collapse;/*设置单线-线合并*/
          width: 80%;
       }
       td{
          border: 1px solid red;
          padding:3px;
       }
       .header{
         background: gray;
       }
    </style>
  </head>

  <body>
    <h2>以下是所有在线用户信息</h2>   
    <table>
       <tr class="header" >
          <td>姓名</td>  <td>上线时间</td>  <td>最后访问时间</td> <td>IP</td> <td>操作</td>
       </tr>

       <c:forEach items="${requestScope.onLines}" var="map">
        <tr>
            <td>
                <c:if test="${empty map.user}" var="boo">
                    游客                  
                </c:if>
                <c:if test="${!boo}">
                    ${map.user.name}
                </c:if>
            </td>
            <td>${map.creationTime}  </td>
            <td>${map.lastAccessTime}</td>
            <td>${map.ip }           </td>

            <td>
                <c:if test="${!boo&&user.admin}">
                     <a href="<c:url value='/servlet/KickOutServlet?id=${map.id}'/> " >踢出${map.user.name}</a>
                </c:if>
            </td>
        </tr>
       </c:forEach>
    </table>
       <br/>网站访问量:${count}
  </body>
</html>

KickOutServlet

管理踢人时请求的servlet,在这里我们把被踢的人的session从服务器端移除就可以了。但是注意防范一下,那个被踢者是否已经被踢走了、

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;
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 {

        response.setContentType("text/html");

        PrintWriter out = response.getWriter();
        String id = request.getParameter("id");
        Map<String, HttpSession> onLines = (Map<String, HttpSession>) getServletContext().getAttribute("onLines");

        if(onLines.containsKey(id)){
            HttpSession session = onLines.get(id);//得到该session
            session.invalidate();//移除该session
            out.println("该用户已被踢出!");
        }else{
            out.println("该用户已经不存在!");
        }
    }
}

user

JavaBean,在这里,我就是简单的封装了一个JavaBean使用了。我们的知识点并不是这里。

package cn.hncu.servlet;

import java.io.IOException;
import java.io.PrintWriter;
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 {

        response.setContentType("text/html");

        PrintWriter out = response.getWriter();
        String id = request.getParameter("id");
        Map<String, HttpSession> onLines = (Map<String, HttpSession>) getServletContext().getAttribute("onLines");

        if(onLines.containsKey(id)){
            HttpSession session = onLines.get(id);//得到该session
            session.invalidate();//移除该session
            out.println("该用户已被踢出!");
        }else{
            out.println("该用户已经不存在!");
        }
    }
}

web.xml

注意啊!无论是servlet还是监听器,过滤器!一定要记得配置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> 

  <listener>
    <listener-class>cn.hncu.listeners.MyServletContextListener</listener-class>
  </listener>
  <listener>
    <listener-class>cn.hncu.listeners.MySessionListener</listener-class>
  </listener>

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

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LogOutServlet</servlet-name>
    <url-pattern>/servlet/LogOutServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ShowServlet</servlet-name>
    <url-pattern>/servlet/ShowServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>KickOutServlet</servlet-name>
    <url-pattern>/servlet/KickOutServlet</url-pattern>
  </servlet-mapping>

  <filter>
    <filter-name>charset</filter-name>
    <filter-class>cn.hncu.filter.CharsetFilter</filter-class>
  </filter>
  <filter>
    <filter-name>login</filter-name>
    <filter-class>cn.hncu.filter.LoginFilter</filter-class>
  </filter>


  <filter-mapping>
    <filter-name>login</filter-name>
    <url-pattern>/servlet/*</url-pattern>
    <url-pattern>/jsps/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>charset</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

演示结果:

登录之前显示的主页:

未登录的时候,是无法进入显示所有在线用户的,用过滤器拦截了。

登录之后显示的主页:

管理员登录后显示的在线人信息

如果不是管理员登录后,最后的操作时不会显示的。

完整的项目链接:

https://github.com/chenhaoxiang/Java/tree/master/myOnlinesWeb2

myOnlinesWeb2.zip压缩文件

希望本篇博客对大家有一点用(^-^)

转载请注明出处: http://blog.csdn.net/qq_26525215
本文源自大学之旅_谙忆的博客

目录
相关文章
|
20天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
174 37
|
20天前
|
Java
Java——接口的使用实例
Comparable接口用于自定义类的对象比较。通过实现此接口并重写`compareTo`方法,可以定义自定义类型的比较规则。 接下来介绍了Comparator接口,它提供了一种更灵活的比较方式。通过实现Comparator接口并重写`compare`方法,可以根据不同属性定义不同的比较规则。例如,定义一个`BrandComparator`类来比较汽车的品牌。 最后,介绍了Cloneable接口,用于实现对象的克隆。实现该接口并重写`clone`方法后,可以创建对象的浅拷贝或深拷贝。浅拷贝仅复制对象本身,深拷贝则会递归复制所有成员变量。
15 4
Java——接口的使用实例
|
20天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
4天前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
17 2
|
8天前
|
存储 Java
Java之静态(static)与实例(instance)
Java之静态(static)与实例(instance)
|
21天前
|
存储 Java
Java内置数据类型和实例的详解
Java内置数据类型分为基本和引用两类。基本数据类型包括整型(`byte`、`short`、`int`、`long`)、浮点型(`float`、`double`)、字符型(`char`)和布尔型(`boolean`),用于存储简单的数值;引用数据类型则用于存储对象的引用,包括类(如`String`)、接口和数组。掌握这两类数据类型是Java编程的基础。以下示例展示了各种数据类型的使用方法。
|
22天前
|
Java
Java实例详解
Java实例是通过类创建的对象,其核心在于将抽象的类定义转化为具体的实体。类作为对象的模板定义了属性和行为,而实例则是这些定义的具体实现。通过`new`关键字可以创建实例,并利用点运算符访问其属性和方法。实例拥有自己的生命周期,从创建到使用直至被垃圾回收机制自动清理。此外,实例变量和静态变量的区别在于前者属于单个实例,后者则为所有实例共享。理解Java实例的概念及其管理对编程至关重要。
|
21天前
|
SQL JSON JavaScript
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
Vue 指令、生命周期、this和$、vue脚手架进行模块化开发/ElementUI框架、综合案例,element商品列表展示增删改查
JavaWeb基础9——VUE,Element&整合Javaweb的商品管理系统
|
2月前
|
Java
【Java基础面试七】、请介绍一下实例变量的默认值
这篇文章介绍了Java中实例变量的默认值:引用数据类型的默认值是null,而基本数据类型的默认值根据其类型分别是0、0L、0.0F、0.0、'\u0000'和false。
【Java基础面试七】、请介绍一下实例变量的默认值
|
2月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之AllLoggers接口获取异常日志的Logger实例的问题如何解决
Java应用结构规范问题之AllLoggers接口获取异常日志的Logger实例的问题如何解决
下一篇
无影云桌面