




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
目錄系統(tǒng)實(shí)現(xiàn)登錄注冊模塊當(dāng)用戶第一次使用系統(tǒng)時(shí),需要進(jìn)行登錄注冊操作,以下是本系統(tǒng)對登錄注冊流程步驟以及實(shí)現(xiàn)的原理的闡述。圖STYLEREF1\s4-SEQ圖\*ARABIC\s11登錄注冊功能流程圖本系統(tǒng)登錄模塊流程如圖4-1所示,會(huì)對用戶輸入賬號(hào)、密碼、驗(yàn)證碼進(jìn)行簡單校驗(yàn)判空,輸入有誤自動(dòng)刷新驗(yàn)證碼。賬號(hào)密碼正確則提交給后臺(tái)獲得用戶權(quán)限,前端會(huì)根據(jù)用戶權(quán)限展示相應(yīng)功能菜單;若密碼錯(cuò)誤,則給出錯(cuò)誤提示。如果用戶沒有賬號(hào)可以進(jìn)行賬號(hào)注冊,填寫正確信息后可進(jìn)入登錄流程。登錄成功后進(jìn)入系統(tǒng)的首頁,根據(jù)登錄角色的不同即管理員和企業(yè),系統(tǒng)展示不同的功能菜單提供服務(wù)。系統(tǒng)通過"request"對象獲取當(dāng)前請求的路徑信息,以及協(xié)議、域名和端口等基本信息,并將這些信息拼接成完整的URL地址,使用了POST方法提交表單數(shù)據(jù)到攔截器MyInterceptor中進(jìn)行判斷,表單中包含了四個(gè)字段:account(用戶名)、password(密碼)、role(角色)、verifyCode(驗(yàn)證碼)。系統(tǒng)Myinterceptor中封裝了登錄攔截器對頁面請求進(jìn)行篩選攔截操作,非法請求無法進(jìn)行登錄驗(yàn)證操作。攔截器重要功能代碼:HttpSessionsession=request.getSession();Objectobject=(Object)session.getAttribute("user");Stringuri=request.getRequestURI();if(uri.endsWith("logon.html")||uri.endsWith("logon.jsp")||uri.endsWith("logon")||uri.endsWith("userLogon.html")||uri.endsWith("css")||uri.endsWith("js")||uri.endsWith(".jpg")||uri.endsWith(".html")||uri.endsWith("addStudent.html")|| uri.endsWith("checkName.action")){//訪問登錄頁面時(shí),直接訪問returntrue;}elseif(object!=null){//用戶已經(jīng)登錄了,session中有用戶的信息,可以訪問admin/下的內(nèi)容returntrue;}else{//其他情況,不允許訪問下的內(nèi)容跳轉(zhuǎn)到登錄頁面//System.out.println("--攔截--");PrintWriterout=response.getWriter();out.print("<script>alert('您還未登錄!請先完成登錄后再操作!!');</script>");response.sendRedirect(request.getContextPath()+"/logon.html");// request.getRequestDispatcher("/admin/login.jsp").forward(request,response);}通過攔截器后進(jìn)入登錄AdminController,先進(jìn)行驗(yàn)證碼verifyCode的判斷,通過后再進(jìn)行用戶角色role的判斷,role值為用戶登錄時(shí)選取的身份,1、2、3分別對應(yīng)管理員、老師、學(xué)生,不同的role值會(huì)重定向到不同的頁面。系統(tǒng)AdminController中定義身份驗(yàn)證的的接口,通過注解@RequestMapping映射路徑,對用戶登錄信息進(jìn)行驗(yàn)證后進(jìn)入到不同的功能界面。AdminController身份權(quán)限驗(yàn)證功能代碼://后臺(tái)生成的驗(yàn)證碼 StringvCode=(String)session.getAttribute("vCode"); ModelAndViewmav=newModelAndView(); if(verifyCode.equalsIgnoreCase(vCode)){ //驗(yàn)證碼正確時(shí)分角色登錄role if(role==0){ //管理員登錄 Adminadmin=adminService.adminLogon(map); if(admin==null){ mav.addObject("info","[管理員登錄]用戶名或密碼錯(cuò)誤!??!"); mav.setViewName("logon"); returnmav; }else{ session.setAttribute("user",admin); session.setAttribute("role",0); returnnewModelAndView("redirect:/index.html"); } }elseif(role==1){ //教師登錄 Teacherteacher=teacherService.teacherLogon(map); if(teacher==null){ mav.addObject("info","[教師登錄]用戶名或密碼錯(cuò)誤?。?!"); mav.setViewName("logon"); returnmav; }else{ session.setAttribute("user",teacher); session.setAttribute("role",1); returnnewModelAndView("redirect:/teacherIndex.html"); } }else{ //學(xué)生登錄 Studentstudent=studentService.studentLogon(map); if(student==null){ mav.addObject("info","[學(xué)生登錄]用戶名或密碼錯(cuò)誤!?。?); mav.setViewName("logon"); returnmav; }else{ session.setAttribute("user",student); session.setAttribute("role",2); returnnewModelAndView("redirect:/studentIndex.html"); } } }else{ //驗(yàn)證碼錯(cuò)誤 mav.addObject("info","?。?!驗(yàn)證碼錯(cuò)誤?。?!"); mav.setViewName("logon"); returnmav; } }圖4-2為系統(tǒng)登錄界面效果圖:圖STYLEREF1\s4-SEQ圖\*ARABIC\s12登錄界面效果圖個(gè)人信息模塊當(dāng)用戶擁有本系統(tǒng)登錄權(quán)限的賬號(hào)后,系統(tǒng)會(huì)對用戶注冊時(shí)所填寫的信息進(jìn)行保存,用戶在個(gè)人信息模塊可以進(jìn)行個(gè)人信息的修改操作,下面對信息修改操作以及實(shí)現(xiàn)原理進(jìn)行詳細(xì)敘述。圖STYLEREF1\s4-SEQ圖\*ARABIC\s13信息修改流程圖如圖4-3,修改個(gè)人信息只需在頁面填寫想要修改的項(xiàng),經(jīng)過填寫規(guī)則校驗(yàn)之后,填寫完整修改信息后,還需要輸入一次密碼確認(rèn)修改,提交修改后會(huì)跳轉(zhuǎn)到登錄界面。信息修改功能實(shí)現(xiàn)與登錄注冊時(shí)的原理類似,通過"request"對象獲取當(dāng)前Web應(yīng)用的上下文路徑信息,將其保存在變量basePath中,在表單提交時(shí),將用戶輸入的教師信息封裝到POST請求中,提交給指定的URL,表單中包含了學(xué)生姓名、學(xué)號(hào)、學(xué)院、聯(lián)系電話、身份證號(hào)、學(xué)生性別、登錄賬戶、登錄密碼等,通過EL表達(dá)式(${})來訪問服務(wù)器端變量,并動(dòng)態(tài)生成,通過JSTL標(biāo)簽庫(<%@taglibprefix="c"uri="/jsp/jstl/core"%>)來處理循環(huán)、判斷等邏輯并增加了一些正則表達(dá)式驗(yàn)證規(guī)則。頁面中使用了一些自定義的CSS樣式,如wk-breadcrumb、wk-panel、wk-normal-input等,用于美化頁面并保持風(fēng)格統(tǒng)一。圖4-4為系統(tǒng)信息修改界面效果圖:圖STYLEREF1\s4-SEQ圖\*ARABIC\s14信息修改效果圖考試功能考試功能為學(xué)生用戶特有功能,用戶在老師發(fā)布考試后可以看到自己的所有考試信息,可以選擇對應(yīng)的考試場次進(jìn)行考試,考試結(jié)束后系統(tǒng)會(huì)自動(dòng)進(jìn)行判分并記錄學(xué)生考試答題狀況以及分?jǐn)?shù)。下面就對考試流程的實(shí)現(xiàn)原理進(jìn)行詳細(xì)的敘述。圖STYLEREF1\s4-SEQ圖\*ARABIC\s15考試模塊流程圖如圖4-5所示,考試模塊功能,用戶進(jìn)入考試模塊界面可以看到所有的考試信息,考試信息包括考試科目、考試時(shí)間,點(diǎn)擊某一場考試可以進(jìn)入該場考試的頁面入口,該入口有開始考試的功能按鈕,該按鈕僅在考試時(shí)間期間可以點(diǎn)擊進(jìn)入本場考試。用戶在對應(yīng)的時(shí)間進(jìn)入考試后在考試規(guī)定的時(shí)間內(nèi)可以答題,完成試卷可以手動(dòng)提交試卷或者考試結(jié)束時(shí)間到系統(tǒng)自動(dòng)保存試卷提交。倒計(jì)時(shí)功能實(shí)現(xiàn):變量endtime,它表示考試結(jié)束時(shí)間,通過獲取當(dāng)前時(shí)間(newDate().getTime())并加上考試時(shí)長計(jì)算得到,變量flag,表示考試是否已經(jīng)結(jié)束。初始值為true。函數(shù)showtime()根據(jù)當(dāng)前時(shí)間和考試結(jié)束時(shí)間的差計(jì)算出剩余時(shí)間,并將剩余時(shí)間格式化成字符串返回,變量examtime,它表示考試的時(shí)長(以分鐘為單位)。然后,通過將當(dāng)前時(shí)間和結(jié)束時(shí)間的差計(jì)算出剩余的時(shí)間,再將剩余時(shí)間按照小時(shí)、分鐘和秒數(shù)進(jìn)行拆分和格式化,最終在頁面上顯示倒計(jì)時(shí)。在頁面加載完成后,反復(fù)調(diào)用showtime()函數(shù),并將其返回值顯示在頁面上。如果剩余時(shí)間小于0,并且考試還沒有結(jié)束,則將flag設(shè)為false,彈出提示框告訴用戶考試時(shí)間結(jié)束,并跳轉(zhuǎn)到提交考試成績的頁面。當(dāng)用戶點(diǎn)擊“提交”按鈕時(shí),彈出提示框詢問用戶是否確定要提交考試,如果確定則跳轉(zhuǎn)到提交考試成績的頁面。當(dāng)用戶選擇了某個(gè)題目的答案時(shí),通過AJAX將該答案提交到服務(wù)器保存??荚嚨褂?jì)時(shí)功能主要代碼:setInterval(function(){ div.innerHTML=showtime(); },1000);//反復(fù)執(zhí)行函數(shù)本身 varshowtime=function(){ varnowtime=newDate()//獲取當(dāng)前時(shí)間 varlefttime=endtime-nowtime.getTime(),//距離結(jié)束時(shí)間的毫秒數(shù) leftd=Math.floor(lefttime/(1000*60*60*24)),//計(jì)算天數(shù) lefth=Math.floor(lefttime/(1000*60*60)%24),//計(jì)算小時(shí)數(shù) leftm=Math.floor(lefttime/(1000*60)%60),//計(jì)算分鐘數(shù) lefts=Math.floor(lefttime/1000%60);//計(jì)算秒數(shù) if(lefttime<0&&flag==true){ flag=false $("#outTime").modal(); $("#outOk").on("click",function(){ location.href="<%=basePath%>saveExamScore/${exam.id}.html"; }); } returnlefth+"小時(shí)"+leftm+"分"+lefts+"秒";//返回倒計(jì)時(shí)的字符串 }用一個(gè)表單元素taskForm,并且使用POST請求方法將表單的數(shù)據(jù)提交到服務(wù)器上的一個(gè)URL地址。同時(shí),這個(gè)表單中包含了一個(gè)題目列表。通過c:forEach標(biāo)簽的迭代,每個(gè)問題都被轉(zhuǎn)化成了一個(gè)showTask類型的div元素。在每個(gè)showTask元素中,都包含有一個(gè)表示問題標(biāo)題的label以及四個(gè)表示問題答案選項(xiàng)的radio元素。在這些radio元素中,name屬性值是相同的,這樣就能夠保證同一個(gè)問題只能有一個(gè)答案被選定。此外,在每個(gè)radio元素后面都有一個(gè)標(biāo)簽,用于展示相應(yīng)答案選項(xiàng)的內(nèi)容??荚嚬δ芎诵拇a:<formid="taskForm"action="<%=basePath%>saveStudentTask/${taskId}.html"method="POST"> <divclass="panel-body"> <divclass="row"> <c:forEachitems="${questions}"var="var"varStatus="idxStatus"> <!--試題--> <divclass="showTask"> <divclass="form-inline"> <divclass="form-group"> <labelclass="control-labelwk-filed-label"style="font-weight:600;"> 題目${idxStatus.index+1}:${var.title} </label> </div> </div> <divclass="form-inline"> <labelclass="control-labelwk-filed-label">答案:</label> <divstyle="font-size:16px;margin-left:82px;margin-top:-28px;"class="userAnswer"name="${var.id}"> <inputtype="radio"required="required"value="A"name="${var.id}"/> A: ${var.itemA}</br> <inputtype="radio"required="required"value="B"name="${var.id}"/> B: ${var.itemB}</br> <inputtype="radio"required="required"value="C"name="${var.id}"/> C: ${var.itemC}</br> <inputtype="radio"required="required"value="D"name="${var.id}"/> D: ${var.itemD}</br> </div> </hr> </div> </div> </c:forEach> </div> </div> <divclass="panel-footerwk-panel-footer"> <buttonid="submitBtn"type="button"class="btnbtn-defaultwk-btn">完成考試</button> </div> </form>圖STYLEREF1\s4-SEQ圖\*ARABIC\s16考試效果圖老師部分的考試模塊功能,老師進(jìn)入考試模塊界面可以查看自己組織的考試,點(diǎn)擊考試可以進(jìn)入該場考試信息頁面,點(diǎn)擊修改可以更改考試試卷,成功提交后會(huì)有成功提示,此時(shí)會(huì)回到該場考試對應(yīng)的信息界面。也可以創(chuàng)建考試,對考試試卷進(jìn)行設(shè)置后提交,成功后會(huì)回到該場考試信息界面。此上就是老師部分的考試模塊的主要功能。成績分析功能實(shí)現(xiàn)效果(學(xué)生端)如圖4-7圖STYLEREF1\s4-SEQ圖\*ARABIC\s17成績查看效果圖在頁面文件頭部引入ECharts的JavaScript文件:<scripttype="text/javascript"src="js/echarts5/echarts.min.js"></script>,用一個(gè)div元素,作為圖表的容器,配置圖表選項(xiàng)和數(shù)據(jù),代碼如下:letoption2={ xAxis:{ type:'category', data:data.exams }, yAxis:{ type:'value' }, series:[{ data:data.scores, type:'line', smooth:true }] };調(diào)用ECharts實(shí)例的setOption方法,將圖表配置應(yīng)用到實(shí)例中,代碼如下:echartsRecords.setOption(option2);實(shí)現(xiàn)效果(老師端)如圖4-8:圖STYLEREF1\s4-SEQ圖\*ARABIC\s18成績查看效果圖圖STYLEREF1\s4-SEQ圖\*ARABIC\s19對應(yīng)學(xué)生成績效果圖首先通過解析頁面URL獲取到教師的ID,然后將其存儲(chǔ)在變量teacherId中。接著使用jQuery的ajax方法異步請求服務(wù)器端的數(shù)據(jù)。ajax方法的參數(shù)包括:url:請求的URL地址,包含了教師ID參數(shù)、type:請求類型,這里使用GET方法、dataType:返回?cái)?shù)據(jù)的類型,這里使用JSON格式、success:請求成功時(shí)的回調(diào)函數(shù),其中data參數(shù)包含了所有學(xué)生的考試成績、error:請求失敗時(shí)的回調(diào)函數(shù)。在success回調(diào)函數(shù)中,首先定義了用于存儲(chǔ)圖表數(shù)據(jù)的各個(gè)數(shù)組(如labels、passScores、failScores等)。然后對返回的data數(shù)據(jù)進(jìn)行遍歷,將每個(gè)學(xué)生的考試成績加入到相應(yīng)的數(shù)組中。這里使用parseFloat方法將字符串類型的成績轉(zhuǎn)換為數(shù)字類型。initChart函數(shù)用于渲染一個(gè)柱狀圖,在該函數(shù)中,使用Chart.js庫創(chuàng)建一個(gè)柱狀圖對象,并設(shè)置其屬性:type:圖表類型為柱狀圖、data:數(shù)據(jù)包括labels和datasets兩部分,其中datasets包括及格分?jǐn)?shù)和不及格分?jǐn)?shù)兩個(gè)數(shù)據(jù)集。options:圖表的選項(xiàng),包括標(biāo)題、坐標(biāo)軸、圖例等設(shè)置。最后再調(diào)用echartsRecords.setOption(option)方法將option對象傳遞給echarts實(shí)例對象進(jìn)行圖表渲染。InitChart功能函數(shù)代碼如下:functioninitChart(select,data){ letechartsRecords=echarts.init(document.getElementById('echarts-records'),'dark'); letoption={ legend:{}, tooltip:{}, dataset:{ source:data }, xAxis:{type:'category'}, yAxis:{}, //Declareseveralbarseries,eachwillbemapped //toacolumnofdataset.sourcebydefault. series:[ {type:'bar'},{type:'bar'}, ] }; echartsRecords.setOption(option); }initChart2函數(shù)用于渲染一條折線圖,同樣接收兩個(gè)參數(shù)select和data。其內(nèi)部邏輯與initChart類似,不過這里的option對象包括了橫軸、縱軸、以及一條折線圖系列,其中折線圖的數(shù)據(jù)通過data參數(shù)中的exams和scores兩個(gè)數(shù)組獲取到。initChart2功能函數(shù)代碼如下:functioninitChart2(select,data){ letechartsRecords=echarts.init(document.getElementById('echarts-records2'),'dark'); letoption2={ xAxis:{ type:'category', data:data.exams }, yAxis:{ type:'value' }, series:[{ data:data.scores, type:'line', smooth:true }] }; echartsRecords.setOption(option2); }為頁面中的三個(gè)按鈕添加了監(jiān)聽器。當(dāng)點(diǎn)擊這些按鈕時(shí),會(huì)觸發(fā)相應(yīng)的回調(diào)函數(shù),更新圖表的數(shù)據(jù)并重新渲染。JSTL標(biāo)簽庫主要用于呈現(xiàn)動(dòng)態(tài)內(nèi)容。主要使用了以下幾個(gè)標(biāo)簽:c:forEach:用于遍歷獲取到的學(xué)生考試成績,并將它們渲染到HTML代碼、fmt:formatNumber:用于格式化輸出數(shù)字類型的數(shù)據(jù),例如保留小數(shù)點(diǎn)后兩位、添加千位分隔符等操作。使用c:forEach標(biāo)簽遍歷所有學(xué)生的考試成績數(shù)據(jù)。在每次循環(huán)中,使用fmt:formatNumber標(biāo)簽格式化輸出分?jǐn)?shù),并將其存儲(chǔ)在一個(gè)變量中。最后,用JSP腳本語言將這些數(shù)據(jù)拼接成HTML代碼,并輸出到頁面上。系統(tǒng)視頻模塊視頻上傳系統(tǒng)老師用戶擁有視頻上傳功能,老師可以選擇對應(yīng)的課程進(jìn)行教學(xué)視頻上傳,老師點(diǎn)擊上傳視頻后彈出下拉選擇框,選擇對應(yīng)的課程點(diǎn)擊選擇上傳文件,在本地選擇文件上傳。savaVideoTest()方法,用于將瀏覽器傳來的視頻流數(shù)據(jù)保存到服務(wù)器上。具體來說,該方法需要傳入兩個(gè)參數(shù):一個(gè)名為file的文件流對象和一個(gè)名為SavePath的字符串,前者表示要上傳的視頻流數(shù)據(jù),后者表示要保存到服務(wù)器的路徑地址。在方法體內(nèi),首先通過file.getOriginalFilename()方法獲取上傳的視頻的原始文件名,并從中截取出文件后綴,得到一個(gè)名為fileExt的字符串變量。然后通過UUID.randomUUID().toString().replaceAll("-","")方法生成一個(gè)唯一標(biāo)識(shí)符pikId,并將其加上文件后綴組成新的文件名newVideoName。接著,將原始文件名、視頻URL路徑和新文件名調(diào)用數(shù)據(jù)庫接口的save()方法存入數(shù)據(jù)庫中。Map<String,String>resultMap=newHashMap<>();try{//獲取文件后綴,因此此后端代碼可接收一切文件,上傳格式前端限定StringfileExt=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1).toLowerCase();System.out.println("前端傳遞的保存路徑:"+SavePath);StringpikId=UUID.randomUUID().toString().replaceAll("-","");StringnewVideoName=pikId+"."+fileExt;System.out.println("重構(gòu)文件名防止上傳同名文件:"+newVideoName);StringvideoNameText=file.getOriginalFilename();System.out.println("視頻原名:"+videoNameText);StringvideoUrl=SavePath+"/"+newVideoName;//調(diào)用數(shù)據(jù)庫接口插入數(shù)據(jù)庫方法save,把視頻原名,視頻路徑,視頻的唯一標(biāo)識(shí)碼傳進(jìn)去存到數(shù)據(jù)庫內(nèi)videoUploadMapper.save(videoNameText,videoUrl,newVideoName);然后,該方法會(huì)判斷視頻需要保存的文件夾是否存在,如果不存在則會(huì)創(chuàng)建。之后,使用File類在服務(wù)器上創(chuàng)建一個(gè)新的視頻文件,并將上傳的視頻流數(shù)據(jù)寫入其中。最后,將一些有關(guān)視頻信息的鍵值對以Map的形式返回給前端,比如重構(gòu)后的視頻名稱、返回碼、視頻保存路徑等。如果上傳和保存過程中發(fā)生錯(cuò)誤,則會(huì)通過try-catch語句捕獲異常并記錄相關(guān)信息,并將錯(cuò)誤碼和異常信息添加到Map中返回給瀏覽器。Filefilepath=newFile(SavePath,file.getOriginalFilename());if(!filepath.getParentFile().exists()){//如果不存在,就創(chuàng)建一個(gè)這個(gè)路徑的文件夾。filepath.getParentFile().mkdirs();}FilefileSave=newFile(SavePath,newVideoName);file.transferTo(fileSave);//構(gòu)造Map將視頻信息返回給前端//視頻名稱重構(gòu)后的名稱:這里put代表添加進(jìn)map集合內(nèi),和前端的push一樣。括號(hào)內(nèi)是前面字符串是鍵,后面是值resultMap.put("newVideoName",newVideoName);resultMap.put("resCode","200");//返回視頻保存路徑resultMap.put("VideoUrl",SavePath+"/"+newVideoName);returnresultMap;}catch(Exceptione){//在命令行打印異常信息在程序中出錯(cuò)的位置及原因e.printStackTrace();e.getMessage();resultMap.put("resCode","400");returnresultMap;}視頻查看與刪除videoTable()方法:用來查詢所有視頻信息并返回給前端展示成表格形式。在這個(gè)方法中,我們直接調(diào)用videoMapper.SelectVideoAll()方法來查詢數(shù)據(jù)庫中保存的所有視頻信息,并將其以列表的形式返回給前端。deleteVideo()方法:用來刪除指定視頻。在這個(gè)方法中,我們首先通過調(diào)用videoMapper.SelectVideoId(videoId)方法查詢數(shù)據(jù)庫獲取對應(yīng)videoId的視頻信息,然后根據(jù)該視頻路徑刪除對應(yīng)的視頻文件,如果刪除成功則再根據(jù)videoId刪除數(shù)據(jù)庫中對應(yīng)的視頻信息記錄。視頻刪除功能部分代碼如下:Map<String,String>resultMap=newHashMap<>();VideovideoPathList=videoMapper.SelectVideoId(videoId);if(videoPathList!=null){if(FileSystemUtils.deleteRecursively(newFile(videoPathList.getVideoUrl()))){resultMap.put("videoName",videoPathList.getVideoName());//dataSource:文件是否被刪除resultMap.put("dataRource","true");resultMap.put("VideoUrl",videoPathList.getVideoUrl());if(videoMapper.rmVideo(videoId)){//mysql:數(shù)據(jù)庫信息記錄是否被刪除resultMap.put("mysql","true");}else{resultMap.put("mysql","false");}}else{resultMap.put("dataResource","false");}視頻播放視頻播放功能是所有用戶都擁有的功能模塊,在老師針對對應(yīng)課程上傳課程視頻就,用戶就可以在課程學(xué)習(xí)模塊使用該功能,點(diǎn)擊對應(yīng)的課程,選擇特定的課程視頻點(diǎn)擊播放即可。視頻播放主要是依靠videoPreview()方法。該用來獲取指定視頻的流數(shù)據(jù)并輸出到瀏覽器。在這個(gè)方法中,我們首先通過調(diào)用videoMapper.SelectVideoId(videoId)方法查詢數(shù)據(jù)庫獲取對應(yīng)videoId的視頻信息,然后從視頻信息對象中取出視頻路徑,將其轉(zhuǎn)為磁盤上的路徑,最后通過創(chuàng)建自定義的NonStaticResourceHttpRequestHandler組件并調(diào)用其中的handleRequest()方法將該視頻的流數(shù)據(jù)輸出到瀏覽器。//調(diào)用查詢方法,把前端傳來的id傳過去,查詢對應(yīng)的視頻信息。VideovideoPathList=videoMapper.SelectVideoId(videoId);//從視頻信息中單獨(dú)把視頻路徑信息拿出來保存StringvideoPathUrl=videoPathList.getVideoUrl();//保存視頻磁盤路徑PathfilePath=Paths.get(videoPathUrl);//Files.exists:用來測試路徑文件是否存在if(Files.exists(filePath)){//獲取視頻的類型,如MP4StringmimeType=FbeContentType(filePath);if(StringUtils.hasText(mimeType)){//判斷類型,根據(jù)不同的類型文件來處理對應(yīng)的數(shù)據(jù)response.setContentType(mimeType);}//轉(zhuǎn)換視頻流部分request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE,filePath);nonStaticResourceHttpRequestHandler.handleRequest(request,response);瀏覽器視頻列表展示部分:使用Bootstrap的表格組件展示所有視頻信息,并為每一行視頻信息添加預(yù)覽和刪除按鈕。刪除確認(rèn)框部分:使用Bootstrap的模態(tài)框組件實(shí)現(xiàn)刪除視頻時(shí)的確認(rèn)提示,用戶點(diǎn)擊“刪除”按鈕時(shí)將會(huì)發(fā)送一個(gè)GET請求到后端控制器中的deleteVideo()方法,并攜帶要?jiǎng)h除的視頻ID。監(jiān)聽預(yù)覽和刪除按鈕的點(diǎn)擊事件,當(dāng)點(diǎn)擊預(yù)覽按鈕時(shí)向后端控制器中的videoPreview()方法發(fā)送GET請求并攜帶對應(yīng)的視頻ID,獲取視頻流數(shù)據(jù)并在頁面上展示播放器;當(dāng)點(diǎn)擊刪除按鈕時(shí)彈出刪除確認(rèn)框并將要?jiǎng)h除的視頻ID保存到模態(tài)框表單中,當(dāng)用戶點(diǎn)擊確認(rèn)刪除后再次向后端控制器中的deleteVideo()方法發(fā)送GET請求進(jìn)行刪除操作。如果刪除成功,則刷新頁面以更新視頻列表展示。瀏覽器監(jiān)聽預(yù)覽和刪除按鈕實(shí)現(xiàn)代碼如下:<script>$(function(){//監(jiān)聽刪除按鈕的點(diǎn)擊事件,將該行視頻ID保存到模態(tài)框表單中$('#deleteModal').on('show.bs.modal',function(event){varbutton=$(event.relatedTarget);varvideoId=button.data('video-id');varmodal=$(this);modal.find('#videoIdInput').val(videoId);});//監(jiān)聽刪除表單的提交事件,成功后刷新頁面$('#deleteForm').submit(function(event){event.preventDefault();varform=$(this);$.get(form.attr('action')+form.find('#videoIdInput').val(),function(result){if(result.mysql==='true'&&result.dataRource==='true'){location.reload();}else{alert('刪除失敗');}});});});</script>第五章系統(tǒng)測試與分析系統(tǒng)測試與分析在上一章中對在線學(xué)習(xí)系統(tǒng)進(jìn)行了設(shè)計(jì)與實(shí)現(xiàn)。在本章中主要對重要功能在web端進(jìn)行測試與驗(yàn)證系統(tǒng)測試環(huán)境表5-SEQ表\*ARABIC\s11系統(tǒng)測試環(huán)境表系統(tǒng)windows11內(nèi)存16GB處理器Intel(R)Core(TM)i7-9750HCPU@2.60GHz2.59GHz瀏覽器谷歌如表5-1,為系統(tǒng)將在Windows11的環(huán)境下采用谷歌瀏覽器自帶的系統(tǒng)測試工具ChromeDevTools進(jìn)行系統(tǒng)測試功能測試本節(jié)將測試在線學(xué)習(xí)系統(tǒng)重要的功能模塊:登錄注冊模塊、考試模塊、信息修改、人員新增、視頻上傳、視頻播放、成績分析、討論模塊。表STYLEREF1\s5-SEQ表\*ARABIC\s12功能測試表編號(hào)功能點(diǎn)前置條件測試步驟預(yù)期結(jié)果實(shí)際結(jié)果是否通過Z-101注冊無用戶填寫基本身份信息,格式無誤后注冊成功,獲得登錄權(quán)限。成功注冊,跳轉(zhuǎn)到登錄界面成功注冊,跳轉(zhuǎn)到登錄界面是Z-102登錄無用戶填寫注冊時(shí)填的賬戶信息與密碼,核驗(yàn)無誤后登陸成功進(jìn)入系統(tǒng)主界面成功登錄,進(jìn)入主界面成功登錄,進(jìn)入主界面是Z-103考試學(xué)生賬戶登錄點(diǎn)擊考試選擇對應(yīng)的考試開始考試成功,進(jìn)入考試界面開始考試成功,進(jìn)入考試界面是Z-104信息修改用戶賬戶登錄點(diǎn)擊個(gè)人信息點(diǎn)擊修改個(gè)人信息填寫個(gè)人信息后提交修改成功,信息顯示為自己修改后的信息修改成功,信息顯示為自己修改后的信息是Z-105試題新增老師用戶登錄點(diǎn)擊考試進(jìn)入考試界面點(diǎn)擊錄入試題填寫試題信息后點(diǎn)擊提交新增成功,在試題列表中可以看見自己新增的試題新增成功,在試題列表中可以看見自己新增的試題是Z-106人員新增管理員用戶登錄點(diǎn)擊新增老師填寫老師信息提交新增成功,新增的人員可以正常登錄習(xí)題新增成功,新增的人員可以正常登錄習(xí)題是Z-107視頻上傳老師用戶登錄點(diǎn)擊視頻上傳選擇對應(yīng)的課程選擇上傳文件點(diǎn)擊上傳上傳成功,視頻列表中有新增視頻上傳成功,視頻列表中有新增視頻是Z-108成績分析用戶登錄點(diǎn)擊成績查看查看成功查看成功是Z-109新增討論老師用戶登錄點(diǎn)擊發(fā)布話題選擇對應(yīng)的課程輸入話題信息點(diǎn)擊發(fā)布發(fā)布成功,學(xué)生端可以參與話題討論發(fā)布成功,學(xué)生端可以參與話題討論是Z-110參與討論學(xué)生用戶登錄點(diǎn)擊話題選擇對應(yīng)的話題進(jìn)行發(fā)言點(diǎn)擊發(fā)布參與成功,討論記錄有新增參與成功,討論記錄有新增是Z-111查看考試記錄學(xué)生用戶登錄點(diǎn)擊考試記錄查看成功,展示自己所有考試記錄查看成功,展示自己所有考試記錄是Z-112發(fā)布考試?yán)蠋熡脩舻卿淈c(diǎn)擊考試選擇新增考試選擇試題錄入填寫試題信息點(diǎn)擊發(fā)布發(fā)布成功,學(xué)生可以進(jìn)入考試界面答題發(fā)布成功,學(xué)生可以進(jìn)入考試界面答題是Z-113刪除人員管理員賬戶登錄點(diǎn)擊刪除人員選擇對應(yīng)的人員點(diǎn)擊刪除刪除成功,數(shù)據(jù)庫用戶信息刪除,該用戶失去系統(tǒng)登錄權(quán)限刪除成功,數(shù)據(jù)庫用戶信息刪除,該用戶失去系統(tǒng)登錄權(quán)限是性能測試本系統(tǒng)對瀏覽器的兼容性較好,對于主流瀏覽器的頁面展示效果均符合需求。性能測試運(yùn)用谷歌瀏覽器原生工具ChromeDevTools,圖5-1為性能分析圖,測試結(jié)果顯示,在采集樣本中響應(yīng)時(shí)間區(qū)間的為100-3000ms,符合需求要求加載和響應(yīng)時(shí)間小于4000ms,對于數(shù)據(jù)存儲(chǔ)和并發(fā)使用的場景下系統(tǒng)依舊保持穩(wěn)定安全運(yùn)行。由此可見,這個(gè)系統(tǒng)具備快速響應(yīng)和順暢性能非常好的在線學(xué)習(xí)工具,同時(shí)還配有簡單易用的操作界面,使得用戶可以享受到優(yōu)質(zhì)的使用體驗(yàn)。圖STYLEREF1\s5-SEQ圖\*ARABIC\s11性能測試圖安全性測試本系統(tǒng)的安全性測試主要從用戶登錄和在線時(shí)未操作超時(shí)進(jìn)行測試。測試結(jié)果如表5-3所示。表STYLEREF1\s5-SEQ表\*ARABIC\s13安全性測試表功能點(diǎn)測試步驟預(yù)期結(jié)果實(shí)際結(jié)果是否通過登錄測試輸入賬號(hào)、密碼和驗(yàn)證碼中一個(gè)或多個(gè)錯(cuò)誤時(shí),測試系統(tǒng)能否正常登錄輸入賬號(hào)、密碼和驗(yàn)證碼中一個(gè)或多個(gè)錯(cuò)誤時(shí),系統(tǒng)均不能登錄輸入賬號(hào)、密碼和驗(yàn)證碼中一個(gè)或多個(gè)錯(cuò)誤時(shí),系統(tǒng)均不能登錄是在線時(shí)長測試當(dāng)系統(tǒng)未操作時(shí)間過長時(shí),系統(tǒng)是否會(huì)拒絕請求,且提示重新登錄當(dāng)系統(tǒng)未操作時(shí)間過長時(shí),系統(tǒng)拒絕請求,且提示重新登錄當(dāng)系統(tǒng)未操作時(shí)間過長時(shí),系統(tǒng)拒絕請求,且提示重新登錄是本章小結(jié)本章主要針對系統(tǒng)功能模塊和非功能模塊進(jìn)行了測試。對發(fā)現(xiàn)的小問題進(jìn)行了修
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 IEC 61300-2-5:2022+AMD1:2025 CSV EN Fibre optic interconnecting devices and passive components - Basic test and measurement procedures - Part 2-5: Tests - Torsion
- 【正版授權(quán)】 IEC 60614-2-1:1982 EN-D Specification for conduits for electrical installations. Part 2: Particular specifications for conduits. Section One: Metal conduits
- 校園食品安全知識(shí)培訓(xùn)
- 藥學(xué)執(zhí)業(yè)考試試題及答案
- 法院文職面試題及答案
- 骨科填空考試題及答案
- 海關(guān)模擬面試題及答案
- 2025年湖北省中考語文真題(含答案)
- 腦出血考試題及答案
- 保密行業(yè)考試題及答案
- 2025歷年退役軍人考試題庫及答案
- 第一二單元月考綜合試卷(試題)四年級(jí)上冊數(shù)學(xué)滬教版
- 2025級(jí)新生軍訓(xùn)開訓(xùn)儀式動(dòng)員大會(huì)
- 農(nóng)產(chǎn)品質(zhì)量安全標(biāo)準(zhǔn)體系與實(shí)施路徑-洞察及研究
- 中組部選調(diào)生管理辦法
- 克痙方濕熱敷:缺血性腦卒中后上肢肌肉痙攣康復(fù)新路徑
- 血常規(guī)檢驗(yàn)中的質(zhì)量控制
- 高尿酸血癥健康管理方案
- 秋季肌膚護(hù)理課件
- 骨科總論教學(xué)課件
- 大單元教學(xué)培訓(xùn)
評(píng)論
0/150
提交評(píng)論