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

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

这个稍微比上个版本做得完善了一点,用了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");
    }
}
目录
相关文章
|
28天前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
1月前
|
数据采集 XML 前端开发
Jsoup在Java中:解析京东网站数据
Jsoup在Java中:解析京东网站数据
|
1月前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
33 2
WK
|
22天前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
36 0
|
1月前
|
Java Docker 容器
java版本学习网站又添加了一个libgdx模块
java版本学习网站之前添加了docker,想了想还是再把libgdx添加进去吧。
32 3
|
1月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
54 5
|
1月前
|
Java
Java关键字 —— super 与 this 详细解释!一看就懂 有代码实例运行!
本文介绍了Java中this和super关键字的用法,包括在构造方法中使用this来区分参数和成员变量、使用super调用父类构造方法和方法,以及它们在同一个方法中同时使用的场景。
126 0
Java关键字 —— super 与 this 详细解释!一看就懂 有代码实例运行!
|
1月前
|
安全 Java Python
基于python-django的Java网站全站漏洞检测系统
基于python-django的Java网站全站漏洞检测系统
34 0
|
1月前
|
Java
java的Random类和Arrays.sort类使用实例
java的Random类和Arrays.sort类使用实例
11 0
|
6天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####