• 基于Servlet、JSP的学生管理系统(附完整源码)


    起因

    最近重温servlet,想到了大学时期用同一个“学生管理系统”水了几门课的课程设计,不免感慨万千。

    周末简单的写了个界面,建了几张表,做了一个小系统(试图找一找当年划水的感觉,可惜没找到)。

    写的比较简单,不过做个普通的课程设计应该够了,需要的可以自取。

    源码地址

    https://gitee.com/DayCloud/student-manage

    界面截图

    主界面

     管理员界面

     学生管理(管理员视角)

     添加系统用户(管理员视角)

     学生主页

     学生个人信息

     目录结构

    运行环境

    tomcat9

    jdk1.8

    其他依赖jar包见WEB-INF下面的lib文件夹。

    涉及技术:Servlet、JSP、BootStrap、Jquery(较少)

    主要功能

    系统有两个角色,管理员和学生。做的比较简单,没有建额外的角色表、权限表,仅仅用了一个字段区分。

    管理员可以管理学生信息、教师信息、可以添加系统用户,录入成绩,具有增删改查的一切权限。

    学生只能查看自己的分数,个人档案等。

    代码分析

    首页数据统计

    系统运行时常、当前在线人数,这两个功能用到了servlet的组件,监听器。

    通过继承ServletContextListener, HttpSessionListener, HttpSessionAttributeListener等接口,可以完成对servlet上下文、session的创建销毁等关键节点的监听。

    在线人数,必然是登录成功的人数。而session是有人访问页面就会创建,所以我们不能根据session的创建和销毁来统计在线人数。

    在登陆成功后,会在session里添加一个变量,我们可以监听这一行为。

    当设置session变量的时候,在线人数+1

    移除session变量的时候,在线人数-1。

    当然这种做法还是有问题的,比如直接关闭浏览器,不点注销,数据统计就会失效,这里不做深入探究。

    再来说说系统运行时长,我的思路是servlet上下文创建的时候,记录下那个时刻的时间戳。

    后面用到的时候,直接用当前的时间戳减去保存的时间戳,就可以计算出相隔的毫秒数,也就可以得到天数。

    @WebListener
    public class CustomServerListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
    
        private volatile ServletContext application = null;
        //上下文初始化,记录当前时间的时间戳,初始化人数统计变量
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("初始化开始---------");
            int onlineNum = 0;
            application = sce.getServletContext();
            application.setAttribute("onlineNum", onlineNum);
            application.setAttribute("startTime", new Date().getTime());
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            ServletContextListener.super.contextDestroyed(sce);
        }
    
        //session创建的时候调用该方法。但是我们计算在线人数指的是登录成功的人
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            
        }
    
        //连接断开
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            
        }
    
        //
        @Override
        public void attributeAdded(HttpSessionBindingEvent se) {
            System.out.println("有人登录了---------");
            int onlineNum = (int) application.getAttribute("onlineNum");
            application.setAttribute("onlineNum", ++onlineNum);
        }
        
        
    
        @Override
        public void attributeRemoved(HttpSessionBindingEvent se) {
            System.out.println("有人退出了---------");
            int onlineNum = (int) application.getAttribute("onlineNum");
            application.setAttribute("onlineNum", --onlineNum);
        }
    
        @Override
        public void attributeReplaced(HttpSessionBindingEvent se) {
            
        }
    }

    计算统计数据的servlet

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            StudentService studentService = new StudentService();
            CourseService courseService = new CourseService();
            ScoreService scoreService = new ScoreService();
            int studentNum = studentService.count();
            int courseNum = courseService.count();
            int onlineNum = (int) request.getServletContext().getAttribute("onlineNum");
            long startTime = (long) request.getServletContext().getAttribute("startTime");
            List<ScoreDto> scoreList = scoreService.getTopScoreList(10);
            
            int days = (int)((new Date().getTime() - startTime) / (1000*3600*24)) + 1;
            request.setAttribute("studentNum", studentNum);
            request.setAttribute("courseNum", courseNum);
            request.setAttribute("onlineNums", onlineNum);
            request.setAttribute("days", days);
            request.setAttribute("scores", scoreList);
            
            
            
            
            request.getRequestDispatcher("/WEB-INF/pages/main.jsp").forward(request, response);
        }

    身份校验

    身份校验自然就用到了过滤器。

    这边没有做复杂的角色权限校验,仅仅在用户表加上一个字段表示区分。

    两个过滤器。

    一个检查用户是否登录(有些页面需要登录,有些不需要的可以放行)

    另一个检查权限够不够。

    @WebFilter(value = "/*")
    public class LoginFilter implements Filter {
    
        private static List<String> passUrlList = Arrays.asList("login.jsp", "css"
                , "js", "jpg", "loginUrl");
    
        /**
         * Default constructor.
         */
        public LoginFilter() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see Filter#destroy()
         */
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        /**
         * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
         */
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse resp = (HttpServletResponse) response;
    
            String uri = req.getRequestURI();
            // 登录页以及静态资源放行
            boolean needLogin = true;
            //页面名称
            String pageName = "";
            //后缀名
            String endName = "";
            if(uri.lastIndexOf("/") != -1 && uri.lastIndexOf("/") + 1 < uri.length()) {
                pageName = uri.substring(uri.lastIndexOf("/") + 1);
            }
            
            if(uri.lastIndexOf(".") != -1 && uri.lastIndexOf(".") + 1 < uri.length()) {
                endName = uri.substring(uri.lastIndexOf(".") + 1);
            }
            
            for (String passUrl : passUrlList) {
                if(passUrl.equals(pageName) || passUrl.equals(endName)) {
                    //不需要登录
                    needLogin = false;
                }
            }
            
            User user = (User) req.getSession().getAttribute("loginUser");
            
            if(needLogin && user == null) {
                //该资源需要登录,并且当前用户没有登录
                resp.sendRedirect("/StudentManage/login.jsp");
            }else {
                //不需要登录
                chain.doFilter(req, resp);
            }
    
            
        }
    
        /**
         * @see Filter#init(FilterConfig)
         */
        public void init(FilterConfig fConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
    }

    权限校验过滤器

    @WebFilter(value = "/admin/*", filterName = "B")
    public class AuthenticationFilter implements Filter{
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            // TODO Auto-generated method stub
            HttpServletRequest req = (HttpServletRequest) request;
            
            User user = (User) req.getSession().getAttribute("loginUser");
            Byte type = user.getUserType();
            if(type != 1) {
                //不是管理员,跳转到错误页面
                req.setAttribute("msg", "抱歉,您没有权限访问!");
                req.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(req, response);;
            }else {
                chain.doFilter(req, response);
            }
        }
    
    }

    其他

    整体上写的随心所欲,不是很规范。

    查找以及分页界面做了,后台没做。因为感觉没啥必要,原生的servlet知道基本原理和用法即可,写业务直接SpringBoot吧。

  • 相关阅读:
    POJ 1860 Currency Exchange (Bellman ford)
    POJ 1502 MPI Maelstrom (最短路)
    2015 Multi-University Training Contest 2 1006(DFS)
    HDU 1495 非常可乐(枚举+DFS)
    HDU 5289 Assignment(单调队列)
    ACDream 1734 Can you make a water problem?(贪心)
    ACDream 1735 输油管道
    ACDream 1726 A Math game (折半查找)
    CSU 1602 Needle Throwing Game (投针问题)
    CSU 1604 SunnyPig (BFS)
  • 原文地址:https://www.cnblogs.com/phdeblog/p/14075413.html
Copyright © 2020-2023  润新知