起因
最近重溫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 = "https://www.cnblogs.com/*") 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 = "https://www.cnblogs.com/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吧,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/228421.html
標籤:其他
下一篇:思維導圖學 Kotlin
