基于web的教学答疑系统
歡迎添加微信互相交流學習哦!
項目源碼:https://gitee.com/oklongmm/biye2
第一章 緒 論
1.1基于Struts和Hibernate的教學答疑系統的優勢
目前隨著Internet的廣泛使用,網絡教學系統被越來越多的應用在教學過程中。許多學校都建立了網上教學系統,通過這樣的系統,學生可以在異地訪問教學資源,不受時間的限制進行學習。網上教學系統中豐富的教學資源又可以作為課堂教學重要的補充。自動答疑系統是網上教育系統的一個重要組成部分,學生可以通過這個系統向老師尋求幫助,獲得問題的解答。基于web的自動答疑系統具有以下優勢:
1)改善教學的效果
通過學生在課程學習過程中所反映和提出的共同問題,教師以及課件編寫者等遠程教學過程中涉及的各管理和參與者,能夠藉此反饋直接調整教學的內容、進度,改善教學方式等,從而提高效果。
2)提高學生學習效率
通過在答疑系統中對一些簡單的公共的問題和概念提供詳細的解答和解釋,可以避免教學中的大量時間花費在基本概念的解釋上,從而可以投入進行深入的討論和交流等。
3)豐富教學經驗
學生在學習過程中產生的問題以及教師等的解答,經過一定時間的積累成為可以重復利用的寶貴資源。其它的學生可以從以往學生的問題中取得收獲,教師也能夠利用這些資源來有針對性的制定教學內容和進度等。
4)改善教學的環境
遠程教學系統中,整個系統的設計、教學方式的制定也直接影響了教學效果。從學生的反饋可以調整它的結構,改善現有系統的不足。作為遠程教學的一個重要的輔助系統,自動答疑系統可以直接與課程學習、考試等系統結合在一起,成為其中不可分割的一部分,也可以在實時的教學模式中使用,作為課后學生答疑、師生交流或教師獲得學生反饋、衡量教學效果的一個配套系統。
1.2 我的研究工作
為了順利完成基于Struts和Hibernate的教學答疑系統的設計與實現,我在畢業設計期間所做的研究工作如下:
1)研究了相關文獻中關于基于Struts和Hibernate的教學自動答疑系統的內容;
2)研究了相關文獻中關于關鍵字匹配算法方面的的內容;
3)學習Core Java 等各種技術;
4)制定了基于web的網絡課程答疑系統的總體設計方案;
5)設計了本系統的各模塊的功能和實現細則;
6)設計了底層數據庫的實現;
7)學習,設計了ajax,javascript校驗
第二章 系統設計中各種技術的介紹
2.1 核心Java介紹
在經歷了以大型機為代表的集中計算模式和以PC機為代表的分散計算模式之后,互聯網的出現使得計算模式進入了網絡計算時代。網絡計算模式的一個特點是計算機是異構的,即計算機的類型和操作系統是不一樣的,例如SUN工作站的硬件是SPARC體系,軟件是UNIX中的Solaris操作系統,而PC機的硬件是INTEL體系,操作系統是windows或者是Linux,因此相應的編程語言基本上只是適用于單機系統,例如COBOL、FORTRAN、C、C++等等;網絡計算模式的另一個特點是代碼可以通過網絡在各種計算機上進行遷移,這就迫切需要一種跨平臺的編程語言,使得用它編寫的程序能夠在網絡中的各種計算機上能夠正常運行,java就是在這種需求下應運而生的。正是因為java語言符合了互聯網時代的發展要求,才使它獲得了巨大的成功。
俗話說:有心栽花花不成,無心插柳柳成蔭。Sun公司絕沒想到本想用于消費電子產品開發的編程語言卻率先在網絡中得到了廣泛應用,但是也可以說是東方不亮西方亮,正是因為java語言在設計目標上的正確性使得java語言是金字總會發光的。C語言是面向過程的語言,也是使用率非常高的語言;而面向對象的思想引入到編程語言之后,C語言就被改造成為面向對象的C++語言,得到了廣泛的應用。但是C++語言必須兼容C語言,因此C++語言是面向過程和面向對象混合的語言。java語言產生于C++語言之后,是完全的面向對象的編程語言,充分吸取了C++語言的優點,采用了程序員所熟悉的C和C++語言的許多語法,同時又去掉了C語言中指針、內存申請和釋放等影響程序健壯性的部分,可以說java語言是站在C++語言這個巨人的肩膀上前進的。
java語言的一個目標是跨平臺,因此采用了解釋執行而不是編譯執行的運行環境,在執行過程中根據所在的不同的硬件平臺把程序解釋為當前的機器碼,實現跨平臺運行。而動態下載程序代碼的機制完全是為了適應網絡計算的特點,程序可以根據需要把代碼實時的從服務器中下載過來執行,在此之前還沒有任何一種語言能夠支持這一點。
綜合上述,Java的生命力體現在如下方面:
1.Java產生與流行是InterNet發展的客觀要求。
2.是一門各方面性能都很好的編程語言,它的基本特點是簡單,面向對象,分布式,解釋的,健壯的,完全的,結構中立的,可移植的,性能很優異的,多線程的,動態的,適合的Internet環境上開發應用系統。
3.Java可以制作大部分網絡應用程序系統,而且與如今流行的WWW瀏覽器結合很好。
4.Java不僅僅是一種各方,更重要的是一種區別于傳統系統,遵守網絡就是計算機信條的平臺技術。Java平臺將面向對象系統擴展成包括程序和數據的網絡計算機(NC),而這個平臺的核心就是Java虛擬機,許多使Java成為萬能開發平臺的屬性都源于Java虛擬機的概念和實現。
JAVA面向對象的思想
JAVA是純面向對象編程,面向對象的三大原則封裝,繼承,多態。下面對這三大原則的介紹:
封裝
封裝是一種把代碼和代碼所操作的數據捆綁在一起,使這兩者不受外界干擾和誤用的機制。封裝可被理解為一種用做保護的包裝器,以防止代碼和數據被包裝器外部所定義的其他代碼任意訪問。對包裝器內部代碼與數據的訪問通過一個明確定義的接口來控制。封裝代碼的好處是每個人都知道怎樣訪問代碼,進而無需考慮實現細節就能直接使用它,同時不用擔心不可預料的副作用。
在JAVA中,最基本的封裝單元是類,一個類定義著將由一組對象所共享的行為(數據和代碼)。一個類的每個對象均包含它所定義的結構與行為,這些對象就好象是一個模子鑄造出來的。所以對象也叫做類的實例。
在定義一個類時,需要指定構成該類的代碼與數據。特別是,類所定義的對象叫做成員變量或實例變量。操作數據的代碼叫做成員方法。方法定義怎樣使用成員變量,這意味著類的行為和接口要由操作實例數據的方法來定義。
由于類的用途是封裝復雜性,所以類的內部有隱藏實現復雜性的機制。所以JAVA中提供了私有和公有的訪問模式,類的公有接口代表外部的用戶應該知道或可以知道的每件東西。私有的方法數據只能通過該類的成員代碼來訪問。這就可以確保不會發生不希望的事情。
繼承
繼承是指一個對象從另一個對象中獲得屬性的過程。是面向對象程序設計的三大原則之二,它支持按層次分類的概念。例如,波斯貓是貓的一種,貓又是哺乳動物的一種,哺乳動物又是動物的一種。如果不使用層次的概念,每個對象需要明確定義各自的全部特征。通過層次分類方式,一個對象只需要在它的類中定義是它成為唯一的 各個屬性,然后從父類中繼承它的通用屬性。因此,正是由于繼承機制,才使得一個對象可以成為一個通用類的一個特定實例。一個深度繼承的子類將繼承它在類層次中的每個祖先的所有屬性。
繼承與封裝可以互相作用。如果一個給定的類封裝了某些屬性,它的任何子類將會含有同樣得屬性,另加各個子類所有得屬性。這是面向對象程序在復雜性上呈線性而非幾何增長的一個重要概念。新的子類繼承其所有祖先的所有屬性。子類和系統中的其他代碼不會產生無法預料的交互作用。
多態
多態是指一個方法只能有一個名稱,但可以有許多形態,也就是程序中可以定義多個同名的方法,用一個接口,多個方法來描述。可以通過方法的參數和類型引用。
2.2 持久層的HIBERNATE的介紹
Hibernate 是一個開放源代碼的對象關系映射框架,它對 JDBC 進行了輕量級的對象封裝,使 Java 程序員可以隨心所欲的使用對象編程思維來操縱數據庫。它不僅提供了從 Java 類到數據表之間的映射,也提供了數據查詢和恢復機制。相對于使用 JDBC 和 SQL 來手工操作數據庫,Hibernate 可以大大減少操作數據庫的工作量。另外 Hibernate 可以利用代理模式來簡化載入類的過程,這將大大減少利用 Hibernate QL 從數據庫提取數據的代碼的編寫量,從而節約開發時間和開發成本 Hibernate 可以和多種Web 服務器或者應用服務器良好集成,如今已經支持幾乎所有的流行的數據庫服務器。
Hibernate 具有很大的靈活性,但同時它的體系結構比較復雜,提供了好幾種不同的運行方式。在輕型體系中,應用程序提供 JDBC 連接,并且自行管理事務,這種方式使用了 Hibernate 的一個最小子集;在全面解決體系中,對于應用程序來說,所有底層的 JDBC/JTA API 都被抽象了,Hibernate 會替你照管所有的細節。
在本次系統設計中所有的DAO都應用了Hibernate技術,大部分利用HQL語言對數據庫進行增刪查改,其中只有小部分使用了SQL進行查詢,相比SQL語言而言,HQL使人很直觀的了解所進行的操作,更為對數據庫底層不熟悉的人提供了極大的方便。
2.3業務層的JAVABEAN的介紹
JavaBean 是一種JAVA語言寫成的可重用組件。為寫成JavaBean,類必須是具體的和公共的,并且具有無參數的構造器。JavaBeans 通過提供符合一致性設計模式的公共方法將內部域暴露稱為屬性。眾所周知,屬性名稱符合這種模式,其他Java 類可以通過自省機制發現和操作這些JavaBean 屬性。
?用戶可以使用JavaBean將功能、處理、值、數據庫訪問和其他任何可以用java代碼創造的對象進行打包,并且其他的開發者可以通過內部的JSP頁面、Servlet、其他JavaBean、applet程序或者應用來使用這些對象。用戶可以認為JavaBean提供了一種隨時隨地的復制和粘貼的功能,而不用關心任何改變。
雖然JavaBean和Java之間已經有了明確的界限,但在某些方面JavaBean和Java之間仍然存在著非常明顯的混淆。Java確實是能夠為用戶創建可重用的對象,但它卻沒有管理這些對象相互作用的規則或標準。JavaBean通過指定定義對象之間交互作用的機制,以及大部分對象需要支持的常用行為,如持久性和實際處理等,建立了自己需要的組件模型。
雖然當前的Java組件模型也可以運行得很好,但在傳送真正的可重用性和交互操作性上仍然非常有限,Java用戶需要做的最多的一件事就是創建applet并使得它們在Web 頁面上相互通訊,這并非易事。JavaBean提供了一個框架包,使用這個包進行通訊就容易得多了。
JavaBean組件能夠通過定義好的標準屬性改進性能。總體而言,JavaBean充分發展了Java applet的功能,并結合了Java AWT組件的緊湊性和可重用性。
2.4表現層Servlet和JSP的介紹
2.4.1Servlet和JSP的介紹
Servlet是運行在WEB服務器或應用服務器上的Java程序,它是一個中間層,負責連接來自Web瀏覽器或其他HTTP客戶程序的請求和HTTP服務器上的數據庫或應用程序。可以將Servlet看作是一個含有HTML的JAVA程序Servlet的工作是執行下面的任務:讀取客戶發送的顯式數據;讀取由瀏覽器發送的隱式請求數據;生成結果;向客戶發送顯式數據(即文檔);發送隱式的HTTP響應數據。
我們可以把JSP看作在靜態頁面上寫Java代碼,但其實JSP在服務器第一次運行的時候被服務器翻譯為Servlet,正真運行的是翻譯后的Servlet。
JSp和Servlet的區別就如下幾點:
1) JSP以文本為主,主要用于畫界面
2) JSP可以人工擴充,而servlet是固定的
3) JSP內核是servlet,所以也是基于HTTP協議的請求響應循環
4) 由HTML(Css、xml)、java code、JSP標簽組成
5) JSP有自定義標簽(ASP沒有)
6) CGI和Servlet以代碼為主,代碼中嵌文本 ;JSP中文本中嵌代碼
7) JSP擅長于表現,而短于邏輯;而Servlet一般用作Contorler和diapatch(控制和流轉);所以在JSP中寫界面元素,而邏輯方面由Servlet完成。
8) JSP不需要寫java文件、不需要編譯和配置,它被封裝到了容器內部;
9) JSP代碼不可重用。
2.4.2 EL和JSTL的介紹
EL全名為Expression Language,它原本是JSTL1.0為方便存取數據所自定義的語言。當時EL只能在JSTL標簽中使用。
到了JSP2。0之后,EL已經正式納入成為標準規范之一。因此,只要是支持servlet2.4/JSP 2.0的Container,就都可以在JSP網頁中直接使用EL了。
JSTL全名為JavaServer Pages Standard Tag Library, 目前最新的版本為1。2版。JSTL是由JCP(Java Community Process)所制定的標準規范,它主要提供給Java Web開發人員一個標準通用的標簽函數庫。
Web程序員能夠利用JSTL和EL來開發Web程序,取代傳統直接在頁面上嵌入Java程序(Scripting)的做法,以提高程序的閱讀性,維護性和方便性。
JSTL是一個標準的已制定好的標簽庫,可以應用于各種領域,如:基本輸入輸出,流程控制,循環,XML文件剖析,數據庫查詢及國際化和文字格式標準化的應用等。從(表2-1)可以知道,JSTL所提供的標簽函數庫主要分為五大類:另外,JSTL也支持EL語法,這也是本系統設計上處理集合迭代的主要方法。
表2-1標簽函數庫
2.5 WEB架構MVC模式和STRUTS的介紹
2.5.1MVC模式的優先和缺點
說道MVC的優點,首先,最重要的是應該有多個視圖對應一個模型的能力。在目前用戶需求的快速變化下,可能有多種方式訪問應用的要求。例如,在本系統中用戶的注冊有學生注冊也可能是教師注冊,但對于注冊的處理都是一樣,也就是說注冊的處理是一致的。按MVC設計模式,一個用戶模型以及多個視圖即可解決問題。這樣減少了代碼的復制,即減少了代碼的維護量,一旦模型發生改變,也易于維護。 其次,由于模型返回的數據不帶任何顯示格式,因而這些模型也可直接應用于接口的使用。
再次,由于一個應用被分離為三層,因此有時改變其中的一層就能滿足應用的改變。一個應用的業務流程或者業務規則的改變只需改動MVC的模型層。
控制層的概念也很有效,由于它把不同的模型和不同的視圖組合在一起完成不同的請求,因此,控制層可以說是包含了用戶請求權限的概念。
最后,它還有利于軟件工程化管理。由于不同的層各司其職,每一層不同的應用具有某些相同的特征,有利于通過工程化、工具化產生管理程序代碼。
關于MVC的缺點,首當其沖的是其增加了系統結構和實現的復雜性。對于簡單的界面,嚴格遵循MVC,使模型、視圖與控制器分離,會增加結構的復雜性,并可能產生過多的更新操作,降低運行效率。
另外,視圖與控制器間的過于緊密的連接。視圖與控制器是相互分離,但確實聯系緊密的部件,視圖沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。
最后,視圖對模型數據的低效率訪問。依據模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數據。對未變化數據的不必要的頻繁訪問,也將損害操作性能。
2.5.2MVC模型簡介
模型一(圖2-2):JSP+JavaBean,JSP既充當控制,又充當視圖,以頁面為核心,JSP使用jsp:useBean,他不能夠實現不同的頁面,顯示不同的數據,需要借助于中間類來調用JavaBean的方法才能實現。
圖 2-2 JSP+JavaBean控制圖
模型二(圖2-3):JSP+Servlet+JavaBean,以控制為核心,JSP只負責顯示和收集數據,sevlet,連接視圖和模型,將視圖層數據,發送給模型層,JavaBean,分為業務類和數據實體,業務類處理業務數據,數據實體,承載數據,基本上大多數的項目都是使用這種MVC的實現模式。
圖2-3 MVC1控制圖
StrutsMVC框架
Struts是使用MVC的實現模式二來實現的,也就是以控制器為核心。(圖2-4)
Struts提供了一些組件使用MVC開發應用程序:
1)模型(Model)
在Struts的體系結構中,模型分為兩個部分:系統的內部狀態和可以改變狀態的操作(事務邏輯)。內部狀態通常由一組Actinform Bean表示。根據設計或應用程序復雜度的不同,這些Bean可以是自包含的并具有持續的狀態,或只在需要時才獲得數據(從某個數據庫 (?http:?/??/?db.rdxx.com?/? _blank?))。大型應用程序通常在方法內部封裝事務邏輯(操作),這些方法可以被擁有狀態信息的bean調用。比如購物車bean,它擁有用戶購買商品的信息,可能還有checkOut()方法用來檢查用戶的信用卡,并向倉庫發定貨信息。小型程序中,操作可能會被內嵌在Action類,它是struts框架中控制器角色的一部分。當邏輯簡單時這個方法很適合。 建議用戶將事務邏輯(要做什么)與Action類所扮演的角色(決定做什么)分開。
2)視圖(View)
視圖主要由JSP建立,struts包含擴展自定義標簽庫(TagLib),可以簡化創建完全國際化用戶界面的過程。目前的標簽庫包括:Bean Tags、HTML (?http:?/??/?web.rdxx.com?/?HTML?/? _blank?) tags、Logic Tags、Nested Tags 以及Template Tags等。
3)控制器(Controller)
在struts中,基本的控制器組件是ActionServlet類中的實例servelt,實際使用的servlet在配置文件中由一組映射(由ActionMapping類進行描述)進行定義。對于業務邏輯的操作則主要由Action、ActionMapping、ActionForward這幾個組件協調完成的,其中Action扮演了真正的業務邏輯的實現者,ActionMapping與ActionForward則指定了不同業務邏輯或流程的運行方向。struts-config。xml 文件配置控制器。
Struts框架的處理流程清楚的體現了MVC系統的特點,簡單的Struts組件結構如圖2所示。Struts Controller ActionServlet處理客戶請求,利用配置的ActionMapping對象把請求映射到Action處理器對象進行處理。Action處理對象訪問ActionForm中的數據,處理和響應客戶請求,它還調用后臺的Bean組件,這些組件封裝了具體的業務邏輯。Action處理器對象根據處理結果通知Controller,Controller進行下一步的處理。
圖2-4 MVC2控制圖
2.6 Spring簡介
Spring是一個開源框架,它由Rod Johnson創建。它是為了解決企業應用開發的復雜性而創建的。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限于服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。
◆目的:解決企業應用開發的復雜性
◆功能:使用基本的JavaBean代替EJB,并提供了更多的企業應用功能
◆范圍:任何Java應用
簡單來說,Spring是一個輕量級的控制反轉(IoC (?http:?/??/?baike.baidu.com?/?view?/?146665.htm _blank?))和面向切面(AOP (?http:?/??/?baike.baidu.com?/?view?/?73626.htm _blank?))的容器框架。
◆輕量——從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個大小只有1MB多的JAR文件里發布。并且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴于Spring的特定類。
◆控制反轉——Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。你可以認為IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。
◆面向切面——Spring提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。
◆容器——Spring包含并管理應用對象的配置和生命周期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創建——基于一個可配置原型 (?http:?/??/?baike.baidu.com?/?view?/?228368.htm _blank?)(prototype),你的bean可以創建一個單獨的實例或者每次需要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不應該被混同于傳統的重量級的EJB容器,它們經常是龐大與笨重的,難以使用。
◆框架——Spring可以將簡單的組件配置、組合成為復雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件里。Spring也提供了很多基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。
所有Spring的這些特征使你能夠編寫更干凈、更可管理、并且更易于測試的代碼。它們也為Spring中的各種模塊提供了基礎支持。
◆Spring能有效地組織你的中間層對象,無論你是否選擇使用了EJB。如果你僅僅使用了Struts或其他的包含了J2EE特有APIs的framework,你會發現Spring關注了遺留下的問題。
◆Spring能消除在許多工程上對Singleton的過多使用。根據我的經驗,這是一個主要的問題,它減少了系統的可測試性和面向對象特性。
◆Spring能消除使用各種各樣格式的屬性定制文件的需要,在整個應用和工程中,可通過一種一致的方法來進行配置。曾經感到迷惑,一個特定類要查找迷幻般的屬性關鍵字或系統屬性,為此不得不讀Javadoc乃至源編碼嗎?有了Spring,你可很簡單地看到類的JavaBean屬性。倒置控制的使用(在下面討論)幫助完成這種簡化。
◆Spring能通過接口而不是類促進好的編程習慣,減少編程代價到幾乎為零。
◆Spring被設計為讓使用它創建的應用盡可能少的依賴于他的APIs。在Spring應用中的大多數業務對象沒有依賴于Spring。
◆使用Spring構建的應用程序易于單元測試。
◆Spring能使EJB的使用成為一個實現選擇,而不是應用架構的必然選擇。你能選擇用POJOs或local EJBs來實現業務接口,卻不會影響調用代碼。
◆Spring幫助你解決許多問題而無需使用EJB。Spring能提供一種EJB的替換物,它們適于許多web應用。例如,Spring能使用AOP提供聲明性事務而不通過使用EJB容器,如果你僅僅需要與單個的數據庫打交道,甚至不需要JTA實現。
◆Spring為數據存取提供了一致的框架,不論是使用JDBC或O/R mapping產品(如Hibernate)。Spring確實使你能通過最簡單可行的解決辦法解決你的問題。這些特性是有很大價值的。
總結起來,Spring有如下優點:
1)低侵入式設計,代碼污染極低
2)獨立于各種應用服務器,可以真正實現Write Once,Run Anywhere的承諾
3)Spring的DI機制降低了業務對象替換的復雜性
4)Spring并不完全依賴于Spring,開發者可自由選用Spring框架的部分或全部
第三章 系統所使用工具的介紹
3.1 TOMCAT的介紹
Tomcat在嚴格意義上并不是一個真正的應用服務器,它只是一個可以支持運行Serlvet/JSP的Web容器,不過Tomcat也擴展了一些應用服務器的功能,如JNDI,數據庫連接池,用戶事務處理等等。Tomcat是Apache組織下Jakarta項目下的一個子項目,目前Tomcat被非常廣泛的應用在中小規模的Java Web應用中。
Tomcat 是一種具有JSP環境的Servlet容器。Servlet容器是代替用戶管理和調用 Servlet的運行時外殼。作為一個開放源代碼的軟件, Jakarta -Tomcat有著自己獨特的優勢:
? 首先,它容易得到。事實上,任何人都可以從互聯網上自由地下載這個軟件。無論從http://jakarta。Apache。org還是從其他網站(Jakarta Tomcat是Apache軟件基金會開發的一個開放源碼的應用服務器)。
? 其次,對于開發人員,特別是Java開發人員,Tomcat提供了全部的源代碼,包括Servlet引擎、JSP引擎、HTTP服務器。無論是對哪一方面感興趣的程序員,都可以從這些由世界頂尖的程序員書寫的代碼中獲得收益。
? 最后,由于源代碼的開放及世界上許多程序員的卓有成效的工作, Tomcat已經可以和大部分的主流服務器一起工作,而且是以相當高的效率一起工作。如:以模塊的形式被載入Apache,以ISAPI形式被載入IIS或PWS,以NSAPI的形式被載入Netscape Enterprise Server。
? 由于Java的跨平臺特性,基于Java的Tomcat也具有跨平臺性。
Tomcat的目錄結構
首先,下載jakarta-tomcat.zip包,解壓縮到一個目錄下,如:c: omcat”。這時,會得到如下的Tomcat的目錄結構:
- - - jakarta - tomcat
| - - - bin Tomcat執行腳本目錄
| - - - Common 放置一些通用類(如JDBC的驅動程序等)
| - - - conf Tomcat配置文件
| - - - doc Tomcat文檔
| - - - lib Tomcat運行需要的庫文件(JARS)
| - - - logs Tomcat執行時的LOG文件
| - - - src Tomcat的源代碼
| - - - webapps Tomcat的主要Web發布目錄(存放我們自己的JSP,SERVLET,類)
| - - - work Tomcat的工作目錄,Tomcat將翻譯JSP文件到的Java文件和class文件放在這里。(表3-1)
表3-1 tomcat目錄結構
目 錄 名 該目錄內的文件的一般功能描述
bin 包含有Startup。bat(啟動服務器)與shutdown。bat(關閉服務器)文件
conf 包含設置部署在Tomcat上的Web應用的變量的初始值的設置文件,包括 server。xml (Tomcat 的全局配置文件) 和 web。xml (為不同的Tomcat配置的web應用設置缺省值的文件)
doc 包含關于Tomcat的各種各樣的文檔。
common 在其lib目錄下,主要存放如JDBC的驅動程序等
lib 包含被Tomcat使用的各種各樣的jar文件。在UNIX上,任何這個目錄中的文件將被附加到Tomcat的classpath中。
logs Tomcat的log文件。
src servlet API的源文件。
webapps 包含Web應用的程序 (JSP、Servlet和JavaBean等)
work 由Tomcat自動生成,這是Tomcat放置它運行期間的中間(intermediate)文件(諸如編譯的JSP文件)地方。 如果當Tomcat運行時,你刪除了這個目錄那么將不能夠執行包含JSP的頁面。
本系統由Myeclipse部署至TOMCAT6.0服務器中。
3.2 MYSQL的介紹
MySQL是最受歡迎的開源SQL數據庫管理系統,它由MySQL AB開發、發布和支持。MySQL AB是一家基于MySQL開發人員的商業公司,它是一家使用了一種成功的商業模式來結合開源價值和方法論的第二代開源公司。
MySQL是一個數據庫管理系統:一個數據庫是一個結構化的數據集合。如果要添加、訪問和處理存儲在一個計算機數據庫中的數據,你就需要一個像MySQL這樣的數據庫管理系統。從計算機可以很好的處理大量的數據以來,數據庫管理系統就在計算機處理中和獨立應用程序或其他部分應用程序一樣扮演著一個重要的角色。
MySQL是一個關系數據庫管理系統:關系數據庫把數據存放在分立的表格中,這比把所有數據存放在一個大倉庫中要好得多,這樣做將增加你的速度和靈活性。MySQL”中的SQL代表Structured Query Language”(結構化查詢語言)。SQL是用于訪問數據庫的最通用的標準語言,它是由ANSI/ISO定義的SQL標準。SQL標準發展自1986年以來,已經存在多個版本:SQL-86,SQL-92,SQL:1999,SQL:2003,其中SQL:2003是該標準的當前版本。
MySQ是開源的:開源意味著任何人都可以使用和修改該軟件,任何人都可以從Internet上下載和使用MySQL而不需要支付任何費用。如果你愿意,你可以研究其源代碼,并根據你的需要修改它。
本系統采用MySQL 5.0.8版本。
3.3 Myeclipse的介紹
說到Myeclips先得說下Eclipse,Eclipse 是一個開放源代碼的、基于 Java 的可擴展開發平臺。就其本身而言,它只是一個框架和一組服務,用于通過插件組件構建開發環境。幸運的是,Eclipse 附帶了一個標準的插件集,包括 Java 開發工具(Java Development Tools,JDT)。
MyEclipse 是什么??簡單而言,MyEclipse是Eclipse的插件,也是一款功能強大的J2EE集成開發環境,支持代碼編寫、配置、測試以及除錯。所以作為本次畢業設計IDE工具的不二人選。
第四章 教學答疑系統的總體設計
4.1系統的需求分析
項目目標:
本軟件功能大致分為三大模塊:學生模塊,教師模塊和管理員模塊。
學生模塊:學生用戶進行操作的模塊。
教師模塊:教師用戶進行操作的模塊。
管理員模塊:管理員用戶進行操作的模塊。
具體各用戶需求分析:
1.學生用戶的需求分析
學生登錄后可以選擇查看個人資料或者進入答疑系統,進入答疑系統后可以提出問題,問題提交給服務器端,等待教師的解答。若教師解答了此題目,當學生下次查看自己問題時即可看到老師回答的答案。
2.教師用戶的需求分析
教師登錄后可以選擇查看個人資料或者進入答疑系統,進入答疑系統后可以查看未解題目,對未解問題的解答,教師還可以進行題庫的管理操作,給題庫添加刪除修改章節,章節關鍵字,章節標準答案,標準答案的關鍵字。讓題庫能適應學生的要求。
3.管理員用戶的需求分析
管理員登錄后可以為對用戶的管理操作,對題目的管理操作和個人信息的修改,以及添加新的用戶。
4.2系統的總體設計
4.2.1系統總結構設計
系統結構采用B/S結構:
B/S(Browser/Server)結構即瀏覽器和服務器結構。它是隨著Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,用戶工作界面是通過WWW瀏覽器來實現,極少部分事務邏輯在前端(Browser)實現,但是主要事務邏輯在服務器端(Server)實現,形成所謂三層(3-tier)結構。一個三層架構的應用程序由三部分組成,這三部分各自分布在網絡中的不同地方。這三個部分分別是:工作站或表示層接口、事務邏輯、數據庫以及與其相關的程序設計。在一個典型的三層架構應用程序中,應用程序的用戶工作站包括提供圖形用戶界面(GUI)的程序設計和具體的應用程序入口表格或交互式窗口。事務邏輯處在局域網(LAN)服務器或其他共享主機上,它作為響應工作站所發出客戶請求的服務器,而相對于處于大型機的第三層它是作為客戶端,并且決定需要什么數據以及數據存儲在哪里。第三層包括數據庫以及處理讀寫以及訪問數據庫的程序。然而應用程序的設計可能比這個架構要復雜,對于大型程序來說,這個三層模式是一種比較簡便的考慮方法。這種應用程序的設計使用客戶/服務器模式,各層可以同時開發,并且可以由不同的成員組用不同的語言來開發。因為各個層次的開發不會影響其他層次,所以這種模型對于進一步開發軟件是很方便的。這樣就大大簡化了客戶端電腦載荷,減輕了系統維護與升級的成本和工作量,降低了用戶的總體成本(TCO)。以目前的技術看,局域網建立B/S結構的網絡應用,并通過Internet/Intranet模式下數據庫應用,相對易于把握、成本也是較低的。它是一次性到位的開發,能實現不同的人員,從不同的地點,以不同的接入方式(比如LAN, WAN, Internet/Intranet等)訪問和操作共同的數據庫;它能有效地保護數據平臺和管理訪問權限,服務器數據庫也很安全 。特別是在JAVA這樣的跨平臺語言出現之后,B/S架構管理軟件更是方便、快捷、高效。
4.2.1系統流程圖
系統流程圖如(圖4-1)所示
圖(4-1) 系統流程圖
系統用例圖設計
系統用例圖如(圖4-2)所示
圖4-2 系統用例圖
4.2.2系統的分層和技術選用
本系統的分層結構以及技術選用: (圖4-3)
圖4-3 分層結構技術圖
在整體設計模式上采用StrutsMVC模式的B/S架構
各層的技術選用:
在表現層:選用Struts,JSP為主要表現技術。
需在Web.xml中添加:
action
org.apache.struts.action.ActionServlet
config
/WEB-INF/struts-config.xml
debug
3
detail
3
0
action
*.do
在業務層:選用JavaBean為主要技術,負責業務的操作。
在持久層:選用Hibernate為主要技術,負責對持久對象的操作。
由于使用Hibernate為持久層,由于我使用了Spring做中間代理,所有與數據庫連接的工作只需要在applicationContext.xml中配置,部分代碼如下:
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/aq_system
root
root
org.hibernate.dialect.MySQLDialect
true
在數據庫層上:選用開源的MySql為數據庫。
4.2.3各層之間的連接:工廠模式。
工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性和低耦合的目的。跟為系統以后的擴展提供了良好接口。
以AdminMgmtService為例,
//產生DAO的工廠,綁定在線程上面,單例,線程安全。
public interface AdminMgmtService {
Userinfo login(String loginname, String loginpassword);
Module getModules(Integer id);
Collection queryAll();
Question findByquestionid(Integer id);
void deleteQuestion(Integer id);
Collection queryAlluser();
void deleteUser(Integer id);
void register(Userinfo userinfo);
}
AdminMgmtServiceImpl類代碼如下,在需要使用DAO時就直接調用方法,寫好get和set方法:
public class AdminMgmtServiceImpl implements AdminMgmtService {
private AdminMgmtDAO dao;
public AdminMgmtDAO getDao() {
return dao;
}
public void setDao(AdminMgmtDAO dao) {
this.dao = dao;
}
public Module getModules(Integer id) {
Module ms =dao.modByid(id);
return ms;
}
public Userinfo login(String loginname, String loginpassword) {
return dao.login(loginname ,loginpassword)
}
public void deleteQuestion(Integer id) {
dao.deleteQuestion(id);
}
public void deleteUser(Integer id) {
dao.deleteUser(id);
}
public Question findByquestionid(Integer id) {
return dao.qryByid(id);
}
public Collection queryAll() {
return dao.queryAll();
}
public Collection queryAlluser() {
return dao.queryAlluser();
}
public void register(Userinfo userinfo) {
dao.registerUser(userinfo);
}
}
在業務層如果要調用某個DAO對象,只需寫在applicationContext.xml如下代碼:
在Action中如果要調用某個業務對象,只需寫如下代碼:
private AdminMgmtService service;
public AdminMgmtService getService() {
return service;
}
public void setService(AdminMgmtService service) {
this.service = service;
}直接使用service調用方法
第五章 系統詳細設計
系統共分學生用戶模塊,教師用戶模塊,題庫管理模塊和管理員模塊。
5.1 系統數據庫設計
5.1.1 數據庫表的設計
本系統共設用戶表userinfo,問題表questions,模塊表modules,章節關鍵字表operations,模塊功能表rights。(圖5-1)
圖5-1 數據庫聯系圖
5.1.2 數據庫表的建立
以userinfo表為例,由于實體類設計管理員,學生,教師都有用戶表而來,所以建表是需要考慮到權限功能的不同,因此在用戶表有字段status區分到底是哪個權限的用戶(表5-2)。
表5-2 userinfo表
Id為與任務業務無關的獨立字段,其優點是能確保永遠不會修改。為此表主鍵約束。
status為用戶的類型:1為學生,2為教師,3為管理員;類型Varchar
loginname為用戶名。唯一約束。 類型Varchar
loginPassword為用戶密碼。 類型Varchar
Email 為用戶email;唯一約束。 類型Varchar
name 為真實姓名;類型Varchar
sex 為性別;類型Varchar
phone 為電話;類型Varchar
具體建表SQL建表語言為:
CREATE TABLE `userinfo` (
`id` int(10) NOT NULL auto_increment,
`loginname` varchar(20) NOT NULL,
`loginpassword` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`sex` varchar(10) default NULL,
`phone` int(20) default NULL,
`email` varchar(20) default NULL,
`status` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
其他表的建立如下:
Questions(表5-3):
表5-3 questions表
ID為問題ID,與業務無關,為此表主鍵約束。 類型為int。
questionname為問題主題;類型varchar。
Details為問題內容;類型Varchar。
Answer 為問題回答;可以為空,類型Varchar。
SQL建表語句:
CREATE TABLE `questions` (
`id` int(10) NOT NULL auto_increment,
`questionname` varchar(500) NOT NULL,
`details` varchar(500) NOT NULL,
`answer` varchar(500) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
modules(表5-4):
表5-4 modules表
id為模塊的id,與業務無關,為此表主鍵約束。 類型為INT。
mname為模塊名; 類型Varchar。
url為模塊的超鏈接; 類型Varchar。
SQL建表語句:
CREATE TABLE `modules` (
`id` int(10) NOT NULL auto_increment,
`mname` varchar(20) NOT NULL,
`url` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
operations (表5-5):
表5-5 operations 表
Id為章節關鍵字表ID,與業務無關,為此表主鍵。 類型為INT。
Nume為模塊目錄。 類型Varchar。
Mid為對應模塊id,類型int。
SQL建表語句:
CREATE TABLE `operations` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(30) NOT NULL,
`mid` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
rights(表5-6):
表5-6 rights 表
id為功能ID,與業務無關,為此表主鍵;類型為INT。
name為功能名;類型Varchar。
url為功能名對應的連接;類型Varchar。
Operationid為章節對應的id;類型int。
SQL建表語句:
CREATE TABLE `rights` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(30) NOT NULL,
`url` varchar(40) NOT NULL,
`operationid` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 COMMENT=InnoDB free: 10240 kB;
5.1.3 對象與數據庫的映射
因為JDBC代碼重復量大,所以在本系統采用了Hibernate技術,使用Hibernate技術,對象與數據庫的映射只需要在配置文件中實現。以userinfo為例,在實體包下添加Userinfo.xml,在里面添加配置:
SYSTEM http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
5.2學生用戶模塊的設計
學生功活動圖如下(圖5-7):
學生通過帳號密碼登錄, 學生登錄后可以選擇查看個人資料或者進入答疑系統,進入答疑系統后可以提出問題,問題提交給服務器端,等待教師的解答。若教師解答了此題目,當學生下次查看自己問題時即可看到老師回答的答案。
圖5-7 學生模塊活動圖
5.2.1學生模板大致設計
學生的一般操作如登錄,注銷,對應系統Action,然后根據類型的不同返回不同的頁面。學生的其他操作對應StudentAction,利用隱藏標簽或者超鏈接直接帶參數調用不同的方法,在各個方法中,調用學生業務實現類QuestionMgmtServiceImpl, QuestionMgmtServiceImpl再調用不同的QuestionMgmtDAO類實現對象的基本操作以完成業務操作,然后根據struts-config.xml中對應的路徑返回頁面。
5.2.2 學生提問功能的設計
學生進入學生模塊后,調用StudentAction中的listQuestion方法看到所有的問題,可以進入看看是否回答了,并顯實在學生的瀏覽器上,若學生對想提出問題可以調用StudentAcion中的bringQuestion方法把題目添加到題庫,等待老師來解決。
學生提問界面(圖5-8):
圖5-8 學生提問界面
學生查詢完后的界面(圖5-9):
圖5-9 學生查詢問題界面
5.3.3學生信息修改的設計
學生通過此功能可以修改,調用StudentAction中的getUserinf方法就將個人信息查詢出并顯示在JSP表單中,點擊修改調用JS校驗判斷信息是否合法,如果沒問題就調用modifystu方法進行修改。
學生信息修改界面(圖5-10):
圖5-10 學生信息修改界面
5.3.4學生模塊代碼舉例說明
以學生查詢自己以解答案為例:學生點擊查看問題連接通過togetq.do頁面跳轉進入getQuestions.jsp。可以看到自己的所有問題,若問題已回答,可以看見問題狀態成為已解答,并有超鏈接查看答案
/getq.do?qid=${q.id}”>
進入查看解答
我們可以看到這是個帶參數的超連接,getQuestion方法會調用傳的參數然后找到具體是那個問題,方法代碼如下:
public ActionForward getQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println(in getQuestion);
Integer id = Integer.valueOf(request.getParameter(qid));
Question q = service.findQuestionById(id);
request.getSession().setAttribute(LOOKQ,q);
return mapping.findForward(success);
}
該方法通過qid調用業務層QuestionMgmtServiceImpl中的findQuestionById方法獲得該題目的問題和答案,DAO中其代碼為:
public Question qryByid(Integer id) {
return (Question)this.getHibernateTemplate().get(Question.class.id);
}
這樣,在獲得了問題,答案和教師以后,分別把他們存放進session中,并跳轉至lookquestion.jsp中,通過EL語言:
${LOOKQ.answer}老師給出的答案.
5.4教師模塊的設計
教師的活動圖如下(圖5-11):
教師登錄后可以選擇查看個人資料或者進入答疑系統,進入答疑系統后可以查看未解題目,對未解問題的解答,教師還可以進行題庫的管理操作,給題庫添加刪除修改章節,章節關鍵字,章節標準答案,標準答案的關鍵字。讓題庫能適應學生的要求。
圖5-11 教師模塊活動圖
5.4.1教師模塊大致設計
教師的一般操作如登錄,注銷,對應系統Action,然后根據類型的不同返回不同的頁面。教師的其他操作對應TeacherAction,利用隱藏標簽或者超鏈接直接帶參數調用不同的方法,在各個方法中,調用教師業務實現類TeacherMgmtServiceImpl, TeacheMgmtServiceImpl再調用不同的TeacheMgmtDAO類實現對象的基本操作以完成業務操作,然后根據struts-config.xml中對應的路徑返回頁面。
5.4.2教師回答問題模塊的設計
教師進入查看問題模塊中,可以通過TeacherAction中的listQuestion方法查看到所有學生遺留的問題,并且可以通過每個問題查看提出問題,教師在TeacherAction中的toanswerQuestion可以進入對單個問題進行解答。answerQuestion方法進行回答問題。
教師回答問題界面(圖5-12)
圖5-12 教師回答問題界面
5.4.3教師信息修改的設計
教師通過此功能可以修改,調用TeacherAction中的getUserinf方法就將個人信息查詢出并顯示在JSP表單中,點擊修改調用JS校驗判斷信息是否合法,如果沒問題就調用modifytea方法進行修改。
5.4.4教師模塊代碼舉例說明
以教師修改答案為例:教師點擊進入解答超連接進入answerquestion.com 。這是我們可以看到所有此教師的答案都在頁面上,點擊修改答案超鏈接/toanswerq.do?qid=${q.id}”>
進入解答
我們可以看到這是個帶參數的超連接,toanswerQuestion方法會調用傳的參數然后找到具體是那個問題,方法代碼如下:
public ActionForward toanswerQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println(in toanswerQuestion);
Integer id = Integer.valueOf(request.getParameter(qid));
Question q = service.findByQuestionid(id);
request.getSession().setAttribute(ANSWERQ,q);
return mapping.findForward(success);
}
該方法先從session中取得answer,然后對answerQuestion進行修改,并調用TeacheMgmtDAO中的updateAnswer方法進行答案的修改。UpdateAnswer中調用AnswerDAO的updateAnswer方法,
public void updateQuestion(Question question) {
this.getHibernateTemplate().saveOrUpdate(question);
}
進行對answer的更新。
5.5管理員模塊的設計
管理員活動圖如下(圖5-13):
管理員登錄后可以為對用戶的管理操作,對題目的管理操作和個人信息的修改,以及添加新的用戶。
圖5-13 管理員模塊活動圖
5.5.1管理員模板大致設計
管理員的一般操作如登錄,注冊,注銷,對應系統Action,然后根據類型的不同返回不同的頁面。學生的其他操作對應AdminAction,利用隱藏標簽或者超鏈接直接帶參數調用不同的方法,在各個方法中,調用學生業務實現類AdminMgmtServiceImpl, AdminMgmtServiceImpl再調用不同的AdminMgmtDAOImpl類實現對象的基本操作以完成業務操作,然后根據struts-config.xml中對應的路徑返回頁面。
5.5.2管理員人員/問題管理功能的設計
管理員進入人員/問題管理后,可以通過不同的帶參數超連接進行學生,教師和管理員或者問題的查看,還可以通過用戶名進行單個用戶的查看。還可以通過帶參數的超鏈接調用AdminAction中不同的方法進行對用戶刪除。(圖5-14)
圖5-14 管理問題界面
5.5.3管理員注冊用戶的設計
這個系統是面對校內的同學老師開放的,所以我的思想是只能有管理員才能進行開放注冊的功能,學生是學號,老師是用戶名,進入register.jsp頁面,在表單最后點擊注冊。傳入/register.do調用AdminAction中的register方法,進行注冊。
5.5.4管理員模塊代碼舉例
管理員進入問題管理后,可以
/lookquestion.do?qid=${q.id }>查看解答
/delequestion.do?qid=${q.id }>刪除
2個單元格,分別傳有參數,調用顯示問題的詳細信息,還有個是否刪除的超鏈接
AdminAction中的delete方法,該方法代碼如下:
public ActionForward deleUser(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println(in deleUser);
Integer id = Integer.valueOf(request.getParameter(uid));
service.deleteUser(id);
return mapping.findForward(success);
}
該方法調用adminMgmtDAO中的deleteQuestion方法進行刪除。
AdminMgmtDAO的deleteQuestion方法,
public void deleteQuestion(Integer id) {
Question q = (Question) this.getHibernateTemplate().get(Question.class, id);
this.getHibernateTemplate().delete(q);
}
第6章 軟件測試
調試本身的目的是盡可能多地暴露程序中的錯誤,但是,發現錯誤的最終目的還是為了改正錯誤。因此,在成功的測試之后,還必須進一步診斷和改正程序中的錯誤,這就是調試的任務。調試是軟件開發過程中最艱巨的腦力勞動。調試開始時,程序員僅僅面對著錯誤的征兆,然而在問題的外部現象和內在原因之間往往并沒有明顯的聯系,在組成程序的數以萬計的元素中,每一個都可能是錯誤的根源。如何在浩如煙海的程序元素中找出有錯誤的幾個元素,這是調試過程中最關鍵的技術問題。
6.1 調試過程
本系統的開發過程遵循如下步驟:先進行需求分析以及總體設計,而后根據總體設計思路進行逐個部分的設計、編碼、調試,整個軟件基本框架搭建好后,再逐步進行完善。當然這個步驟是伴隨著調試進行的,因此調試滲透在整個軟件開發過程之中,而且,對于系統中大部分的局部設計、開發過程是建立在實驗的基礎上的,而進行實驗的目的也是為了便于進行各種測試與調試,來確定與了解某些控件或類的功能、屬性、方法以及可能出現的問題等等,可以說調試在整個開發過程中占了很大一部分時間。
程序的調試原則包括正確性,可靠性,易用性等幾個方面。在調試過程中,可能會遇到多種錯誤,最常見且易發現的是編譯錯誤。遇到編譯的錯誤,可以根據系統的提示作出相應的修改。另一種錯誤是邏輯錯誤,在編譯的時候不易發現,而在運行之后結果與程序員預先設想的結果不一致,但是系統又沒有提示,所以這樣的情況下,需要仔細查找原因。
6.2 調試過程中遇到的問題
1)Hibernate配置問題,因為Hibernate配置文件需要實體類屬性和字段的一一對應,而且對于一對多的多對一的關系有特殊的寫法,所以在一開始設計上總是問題很多。
2)DAO層HQL語言的使用問題,除了上面說到的延遲抓取,HQL畢竟有別與我們經常使用的SQL語言,經常由于兩者相互混淆而導致錯誤。
3)在業務層的事務操作上,有時候不小心會把兩個有關聯的操作放在不同的事務中,導致操作錯誤。
問題還有很多,以上只是挑取比較常見的幾種。
結 論
本次畢業設計,學到了很多東西,無論是在知識的掌握方面,還是在經驗的積累方面,都收獲頗豐。獨立開發一個基于Struts和Hibernate的教學答疑系統,從接受畢業設計的任務,到熟悉軟件開發環境,再到集中精力開發系統,整個過程中遇到了很多問題,我學著自己解決這些問題,在解決問題的過程中,學到了很多有用的東西。過程雖然幾多波折,但卻真的令我受益匪淺。
第一,關于程序設計方面,由于系統較小所以采用瀑布式開發,但由于經驗太少和對業務的考慮不夠深遠,導致寫代碼時發現有些寫到的類用不到,要用到的沒寫,在這方面可以說教訓很大。所以深深感覺到設計在一個系統開發的重要地位。
第二,在積累經驗方面,感覺平時的學習只有通過實踐才能真正掌握,雖然有時候嘴上能把很多東西說的很詳細,很輕松,但是真正寫了才發現問題很多,這對于我來說是本此畢業設計的最大收獲。
第三,關于WEB技術方面, 我理想中的Web開發架構是這樣的:開發速度快,運行速度快,結構清晰優雅。在使用JavaEE對于Web技術的開發后,我深刻的體會到Web技術的分層結構及其優點。 本系統使用到了當今比較流行的框架Java Web開發框架, ,最流行的框架是Apache Struts。當Web開發繼續演變它的工具和編程方法時,Java應用程序框架也將繼續成長下去。Java Web開發框架的未來一片明亮。
在這次畢業設計中我使用到了非常多的新技術,在基于Struts和Hibernate的教學答疑系統這個課題的基礎上,我加上了Spring做了一個代理程序,也算是SSH框架吧,校驗也使用了ajax,對于這些技術的運用我只是了解皮毛而已,但是要是想更深入的了解,使用J2EE我要學習的還很多,要鞏固的還很多。
主要參考文獻
[1]孫衛琴.JAVA面向對象編程[M].北京,電子工業出版社,2006.
[2]孫衛琴.精通Hibernate[M]. 北京,電子工業出版社, 2005.
[3] Hibernate3.2官方文檔[M]. 2006.
[4](美)Marty Hall, larry Browm,趙學良.Servlet與JSP核心編程[M]. 北京,清華大學出版社,2004.
[5]林上杰,林康司.JSP2.0技術手冊[M]. 北京,電子工業出版社,2004.
[6]孫衛琴.精通Struts:基于MVC的Java Web設計與開發[M]. 北京,電子工業出版社,2004.
[7]張天河 .Struts Hibernate Spring 集成開發寶典[M]. 北京,電子工業出版社,2006.
[8]Gai-Tai Huang Hsiu-Hsen Yao .Chinese Question-Answering System.2003
[9]李素建,張健,黃雄,白碩,劉群.Semantic Computation in a Chinese Question-Answering System[J]. 北京,電子工業出版社,2001.
[10]王小冬 .為Struts應用程序構建Web服務[J]. 北京,計算機與現代化出版社 ,2005.
[11]JamesTurner.Struts Kick Start[M]. 北京,北京電子工業出版社,2004.
[12]李剛.整合Struts+Hibernate+Spring應用開發詳解[M]. 北京,清華大學出版社,2007.
[13]蔡劍.J2EE和Tomcat第2版[M]. 北京,清華大學出版社, 2005.
[14]張靚.Java案例開發[M].北京,中國水利水電出版社,2005.
[15]崔洪斌.J2EE Web Service高級編程[M].北京,清華大學出版社,2005.
[16]史燕.基于Struts和Hibernate的Web應用開發框架[M]. 北京,中國數據通信出版社,2005.
[17]高昂.基于Hibernate與Struts框架的數據持久化應用研究[M]. 北京,計算機應用出版社,2005.
[18]陳光.Struts開發及項目實施[C]. Internet信息世界,2002—10.
[19]歐冰玉.利用struts架構進行項目開發的探討[C].柳鋼科技,2006—3.
[20]透明.冬眠的數據庫——Hibernate初接觸[J].科技資訊,2006—3.
[21]胡建華.基于Hibernate開發與數據庫無關的系統[J]. 北京,計算機與現代化,2005—9.
[22]高昂,衛文學.基于Hibernate與Struts框架的數據持久化應用研究[J].計算機應用,2005.
[23]王青松.基于Hibernate實現MVC中的模型框架[J].遼寧大學學報(自然科學版),2007,34(4):309-311.
[24]邱曉榮,王繼斌,朱應國.基于MVC模式的Struts框架在信息管理系統中的應用[J].福建電腦,2007,27(8):84-85.
致 謝
這次畢業設計的順利完成感謝我的母校——江蘇技術師范學院,對我辛勤培育之恩;感謝校院領導和老師們多年來,對我的孜孜教誨,在這里我會永生不忘;感謝同學們這么多年來對我的關心和幫助。
這里我還要感謝我的指導老師:常玉慧老師。他從一開始就幫助我分析系統的設計,技術的選擇,并指導我注冊時的校驗和ajax方法。他還為我收集有關系統的中英文資料,使我能對這個項目有更廣更深的認識。他還督促我認真完成畢業設計,所有這些都體現了他作為教師對工作高度負責的精神和對知識、技術一絲不茍的態度。
最后我要感謝和我一起學習的同學,正是因為我們互幫互助,才能一起克服許許多多困難。
在此再次向校院的各位領導、各位教師表示我最崇高的敬意和最衷心的感謝!
蘇騁
2010年6月
附錄 令牌機制,JS校驗,AJAX
附錄一:令牌機制驗證碼
驗證碼:就是將一串隨機產生的數字或符號,生成一幅圖片, 圖片里加上一些干擾象素(防止OCR),由用戶肉眼識別其中的驗證碼信息,輸入表單提交網站驗證,驗證成功后才能使用某項功能。
驗證碼一般是防止有人利用機器人自動批量注冊、對特定的注冊用戶用特定程序暴力破解方式進行不斷的登陸、灌水。因為驗證碼是一個混合了數字或符號的圖片,人眼看起來都費勁,機器識別起來就更困難。像百度貼吧未登錄發貼要輸入驗證碼大概是防止大規模匿名回帖的發生。
我使用的方法是,jsp頁面生成一個4位數字,用戶輸入后在登錄的Action中會取得并且對比,正確就成功登錄,請看下面代碼:
1) image.jsp
<%@ page import=java.awt.*,java.awt.image.*,java.util.*,javax.imageio.* %>
<%@ page import=java.io.OutputStream %>
<%!
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
try{
response.setHeader(Pragma,No-cache);
response.setHeader(Cache-Control,no-cache);
response.setDateHeader(Expires, 0);
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os=response.getOutputStream();
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
g.setFont(new Font(Times New Roman,Font.PLAIN,18));
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String sRand=;
for (int j=0;j<4;j++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
g.drawString(rand,13*j+6,16);
}
session.setAttribute(ccode,sRand);
g.dispose();
ImageIO.write(image, JPEG,os);
os.flush();
os.close();
os=null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(IllegalStateException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}%>
2) LoginAction.java中登陸代碼:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String loginname = request.getParameter(loginname);
String password = request.getParameter(loginpassword);
String ccode = (String)request.getSession().getAttribute(ccode);
String checkcode = (String)request.getParameter(imgcode);
Userinfo user = service.login(loginname, password);
if (user == null){
return mapping.findForward(failed);
}
else{
if(!ccode.equals(checkcode)){
return mapping.findForward(failed);
}
request.getSession().setAttribute(USER, user);
Integer mid=user.getStatus();
Module ms = service.getModules(mid);
System.out.println(ms);
request.getSession().setAttribute(MODULES, ms);
return mapping.findForward(success);
}
}
附錄二:JS校驗
因為我做的網站需要有注冊和修改個人資料,如果不對信息進行校驗的話,會出現不嚴謹不穩定的問題。所以我在需要注冊,修改的JSP頁面上都調用了一個JS校驗:
1) 登錄名不能為空,只能是英文或者數字
2) 密碼不能為空,長度在6-8之間,2次輸入的密碼必須一致
3) 姓名不能為空,姓名中不能有空格
4) 電話號碼必須是數字
5) Email必須有格式限制
function checkuser() {
var name;
var loginname;
var loginpassword;
var email;
var phone;
name = new String(document.userform.name.value);
loginname = new String(document.userform.loginname.value);
password = new String(document.userform.loginpassword.value);
email = new String(document.userform.email.value);
phone = new String(document.userform.phone.value);
if (loginname == ) {
document.getElementById(loginNameErr).innerHTML = 登錄名不能為空!;
document.userform.loginname.focus();
return false;
}else if (!isloginnameString(loginname)) {
document.getElementById(loginNameErr).innerHTML = 只能用英文字符和數字!;
document.userform.loginname.focus();
return false;
}
document.getElementById(loginNameErr).innerHTML = ;
if (password == ) {
document.getElementById(passwordErr).innerHTML = 密碼不能為空!;
document.userform.password.focus();
return false;
}else if (password.length < 6 || password.length > 8) {
document.getElementById(passwordErr).innerHTML = 密碼長度要大于6小于8之間!;
document.userform.password.focus();
return false;
}
document.getElementById(passwordErr).innerHTML = ;
if (document.userform.passwordsec.value == ) {
document.getElementById(passwordsecErr).innerHTML = 請再次輸入密碼!;
document.userform.passwordsec.focus();
return false;
} else if (document.userform.loginpassword.value != document.userform.passwordsec.value) {
document.getElementById(passwordsecErr).innerHTML = 您兩次的密碼不一致!;
document.userform.passwordsec.value = ;
document.userform.passwordsec.focus();
return false;
}
document.getElementById(passwordsecErr).innerHTML = ;
if (name == ) {
document.getElementById(userNameErr).innerHTML = 請輸入姓名!;
document.userform.name.focus();
return false;
}else if(name.indexOf( )!=-1){
document.getElementById(userNameErr).innerHTML = 姓名不能有空格!;
document.userform.name.focus();
return false;
}
document.getElementById(userNameErr).innerHTML = ;
if (!isNumber(phone)) {
document.getElementById(phoneErr).innerHTML = 電話號碼只能為數字!;
document.userform.phone.focus();
return false;
}
document.getElementById(phoneErr).innerHTML =;
document.userform.submit();
if(email==){
document.getElementById(emailErr).innerHTML = 請輸入email!;
document.userform.email.focus();
return false;
}else if (email !=
& IsEmail(document.userform.email.value)) {
document.getElementById(emailErr).innerHTML = 您輸入的email格式不對!;
document.userform.email.focus();
return false;
}
document.getElementById(emailErr).innerHTML = ;
}
function IsEmail(item) {
var etext
var elen
var i
var aa
var uyear, umonth, uday
etext = item;
elen = etext.length;
if (elen < 5)
return true;
i = etext.indexOf(@, 0)
if (i == 0 || i == -1 || i == elen - 1)
return true;
else {
if (etext.indexOf(@, i + 1) != -1)
return true;
}
if (etext.indexOf(.., i + 1) != -1)
return true;
i = etext.indexOf(., 0)
if (i == 0 || i == -1 || etext.charAt(elen - 1) == .)
return true;
if (etext.charAt(0) == - || etext.charAt(elen - 1) == -)
return true;
if (etext.charAt(0) == _ || etext.charAt(elen - 1) == _)
return true;
for (i = 0; i <= elen - 1; i++) {
aa = etext.charAt(i)
if (!((aa == .) || (aa == @) || (aa == -) || (aa == _)
|| (aa >= 0 && aa <= 9) || (aa >= a && aa <= z) || (aa >= A && aa <= Z)))
return true;
}
return false;
}
function isNumber(str) {
if (str.length == 0) {
return false;
}
for ( var i = 0; i < str.length; i++) {
if (str.charAt(i) < 0 || str.charAt(i) > 9) {
return false;
}
}
return true;
}
function isloginnameString(ssn) {
var re = /^[0-9a-z][w]*[0-9a-z]$/i;
if (re.test(ssn)) {
return true;
} else {
return false;
}
}
附錄三:AJAX
在基于數據的應用中,用戶需求的數據如聯系人列表,可以從獨立于實際網頁的服務端取得并且可以被動態地寫入網頁中,給緩慢的Web應用體驗著色使之像桌面應用一樣。AJAX開發與傳統的CS開發有很大的不同。這些不同引入了新的編程問題,最大的問題在于易用性。由于AJAX依賴瀏覽器的JavaScript和XML,瀏覽器的兼容性和支持的標準也變得和JavaScript的運行時性能一樣重要了。這些問題中的大部分來源于瀏覽器、服務器和技術的組合,因此必須理解如何才能最好的使用這些技術。
我在系統中使用到AJAX技術的地方是,登錄的用戶名進行判斷是否是重復的如果在數據庫中有同樣的用戶名則不能注冊,在界面上直接顯示出來。Ajax分別在3個地方寫入:1.在JSP頁面上提出;2.在Action中有一個判斷的方法;3.在applicationContext.xml中進行方法配置。
1) JSP頁面
1) AdminAction.java中判斷方法
public ActionForward userValidator(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String loginname=request.getParameter(loginname);
PrintWriter out=response.getWriter();
if(loginname.trim().length()==0||loginname==null){
out.println(請輸入賬號名);
out.flush();
return mapping.findForward(userreg);
}
Collection admins=service.queryAlluser();
System.out.println(admins);
Iterator it=admins.iterator();
while(it.hasNext()){
Userinfo admin=(Userinfo)it.next();
if(loginname.equals(admin.getLoginname())){
out.println(對不起該賬號名已經存在!);
out.flush();
return mapping.findForward(error);
}
}
return mapping.findForward(error);
}
3) 在applictionContext.xml中配置
登錄
判斷權限
學生模塊
教師模塊
管理員模塊
查看問題
提交問題
修改資料
修改資料
查看問題
解答問題
管理人員
管理問題
注冊
退出
終止
serviceLocator
表示層
Struts
Struts Action,
ActionForm,
Jsp,
Struts-config.xml,etc.
DAO Classes
JavaBean
Hibernate session Management
持久層
Hibernate
DataSource
Transactions
Business Service Classes
QueryLanguage Support and other Hibernate Services
問題表
用戶表
章節關鍵字表
?
總結
以上是生活随笔為你收集整理的基于web的教学答疑系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解什么是Polygon跨链桥
- 下一篇: java信息管理系统总结_java实现科