摘要:本課題是Web服務器和瀏覽器的設計與實現。該文基于C/S架構,按照軟件工程基本原理和方法,綜合運用UML建模技術、計算機網絡技術進行系統設計,并用Java語言和Eclipse開發工具實現該系統。系統分為客戶端和服務器端,其中客戶端即瀏覽器,具有獲取并顯示服務器端的網頁、查看源代碼以及存儲網頁等基本功能;服務器端則提供Web服務。瀏覽器和服務器之間通過請求和響應方式交換網頁,網頁由報文組成,報文的規則由HTTP協議定義。文中具體闡述了Web服務器和瀏覽器的技術背景及其詳細設計與實現。
關鍵詞:Web服務器;瀏覽器;C/S架構;Java
中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2009)36-10283-05
隨著網絡技術的不斷發展,信息化進程的加快,準確、快速地獲取Internet上提供的資源已成為人們普遍關注的問題。目前比較常用的Web瀏覽器是微軟公司開發的IE,它能方便地查看源文件、清除歷史記錄、設置安全等級以及設置代理服務器等。
1.1 研究背景
WWW服務,也稱Web服務。它是一種交互式圖形界面的Internet服務,具有強大的信息連接功能,它使得用戶通過簡單的圖形界面就可以訪問各個大學、組織和公司等的最新信息和各種服務。
1.2 可行性分析
1.2.1 技術可行性
使用Eclipse作為開發的平臺,Java作為開發語言。在Java 1.2中,SUN公司推出的新的用戶界面庫java.swing包,相比較AWT來說,功能更強大,使用更方便。而且java.swing中的類完全是由Java語言編寫的[1]。
1.2.2 經濟可行性
本系統的開發需要耗費一定的人力和時間,而且在短時間里開發出來的系統可能離具體產生效益還有一定的差距,因為市場上的瀏覽器已經非常成熟并且功能強大。但是,一些個性化的瀏覽器,或一些有定制功能的瀏覽器,仍很具吸引力。因此從長遠利益來考慮,本課題的設計開發是具有較大的經濟可行性的。
2 技術分析
2.1 Java
Java語言是一個面向對象的語言。Java語言提供類、接口和繼承等原語,為了簡單起見,只支持類之間的單繼承,但支持接口之間的多繼承,并支持類與接口之間的實現機制[1]。本系統使用Java語言開發。
2.2 Eclipse
本系統使用Eclipse作為開發平臺。
Eclipse[2]是一種可擴展的開放源代碼IDE。Eclipse允許在同一IDE中集成來自不同供應商的工具,并實現了工具之間的互操作性,從而顯著改變了項目工作流程,使開發者可以專注在實際的嵌入式目標上。
2.3 C/S結構
所謂C/S結構,是將數據存取與應用程序分離開來,把一個軟件系統或應用系統按功能分成若干個部分,再將這些軟件的組成部分按其不同的角色分成Client軟件和Server軟件,分別放置在客戶機和服務器上。
2.4 HTTP協議
HTTP(Hypertext Transfer Protocol,超文本傳輸協議)是Internet的應用層協議。HTTP通過兩個程序實現:一個是客戶端程序(一般稱為瀏覽器),另一個是服務器程序(通常稱為Web服務器)。兩者通常運行在不同的主機上,并通過交換HTTP報文來產生網頁請求和響應。
2.5 UML
UML(Unified Modeling Language,統一建模語言)[3]是用來對軟件密集系統進行可視化建模的一種語言。UML是一種定義良好、易于表達、功能強大且普遍適用的建模語言。它溶入了軟件工程領域的新思想、新方法和新技術。
3 系統需求分析
本系統分為瀏覽器和Web服務器兩部分,根據UML建模技術將瀏覽器分為三個用例,即建立連接、獲取服務及斷開連接;Web服務器也分為三個用例,即允許建立連接、提供服務及允許斷開連接。
瀏覽器用例圖如圖1所示。Web服務器用例圖如圖2所示。圖1及圖2描述了系統總體需求,下面具體介紹各子用例。
3.1 建立連接
功能說明:通過網絡連接到一個Web服務器。
基本條件:有正常的網絡連接,有可用的Web服務器,HTTP的相關設置正確。
基本過程:a) 輸入Web服務器的信息;b) 用戶發出建立或連接Web服務器的請求;c) 連接到指定的Web服務器。
替代過程:c) 連接失敗,將失敗信息返回給用戶;d) 提示用戶重試。
3.2 獲取服務
功能說明:用戶獲取遠端的Web服務器提供的服務。
基本條件:已經連接到Web服務器。
基本過程:a) 用戶提交獲得服務請求;b) 將請求命令提交給Web服務器;c) 從Web服務器獲取服務的內容;d) 將獲取的內容顯示給用戶。
替代過程(一):b) 若沒有建立連接,提醒用戶先建立連接。
替代過程(二):c) 獲取所需的服務失敗;d) 提示用戶失敗信息。
3.3 斷開連接
功能說明:離開當前已經連接的Web服務器。
基本條件:有正常的網絡連接,已經和一個遠端Web服務器建立連接,HTTP的相關設置正確。
基本過程:a) 用戶發送斷開連接的請求;b) 將用戶請求發送到Web服務器;c) 停止從Web服務器獲取服務;d) 斷開和Web服務器的連接。
替代過程(一):d) 斷開連接失敗,提示用戶失敗信息。
替代過程(二):b) 發送請求失敗,提示用戶重試。
3.4 允許建立連接
功能說明:允許用戶連接到當前的Web服務器。
基本條件:有正常的網絡連接,Web服務器已經開啟服務,HTTP的相關設置正確,遠端用戶提交連接請求。
基本過程:a) 等待遠端用戶發出建立連接的請求;b) 獲取遠端用戶發送的連接請求;c) 允許該用戶連接到當前的Web服務器。
替代過程(一):b) 若用戶信息不符合設置,發送拒絕信息到遠端用戶;c) 拒絕建立連接。
替代過程(二):c) 若建立連接失敗,顯示失敗信息。
3.5 提供服務
功能說明:向遠端用戶提供的所請求的服務。
基本條件:已經和遠端用戶建立連接,遠端用戶有獲取服務的請求。
基本過程:a) 獲得遠端用戶提出的服務請求;b) 解析獲取的服務請求的信息;c) 將服務的內容提供給遠端用戶;d) 等待用戶新的請求。
替代過程(一):b) 若無法解析請求的信息,等待新的請求。
替代過程(二):c) 發送服務內容的操作失敗;d) 未超過最大重發次數,重新嘗試發送,執行c);e) 等待新的請求。
3.6 允許斷開連接
功能說明:服務器斷開和所請求的用戶的連接。
基本條件:有正常的網絡連接,收到已經建立連接的遠端用戶的斷開連接的請求,HTTP的相關設置正確。
基本過程:a) 獲取遠端用戶發送的斷開連接的請求;b) 終止對該用戶提供的服務;c) 斷開和該用戶建立的連接。
替代過程(一):c) 斷開連接失敗,重試。
替代過程(二):b) 終止服務失敗,等待服務結束;c) 斷開和該用戶的連接。
4 系統概要設計
從需求分析中,我們可以獲取各用例的對象。服務器沒有用戶界面,作為后臺服務進程啟動;瀏覽器具有用戶界面,其對象圖如圖3所示。
圖3中表示邊界對象,它的作用是作為與外界聯系的媒介。所有系統外部對象必須通過邊界對象才能聯系系統內部對象。
表示實體對象,它是應用中的核心部件,通常貫穿于整個生存周期。
表示控制對象,它調控實體對象和邊界對象之間的關系。
4.1 對象的靜態關系
4.1.1 建立連接
“建立連接”子用例的協作圖如圖4所示。
圖4表明了建立連接用例中各對象之間的關系:用戶向“連接界面”請求連接,“連接界面”向“響應處理”發送“服務器信息”,“響應處理”向“建立連接”“服務器信息”,“建立連接”向“獲取服務”發送“啟動”命令,并向“連接界面”發送“連接建立”,“連接界面”向用戶反饋“連接建立”。
4.1.2 獲取服務
“獲取服務”子用例的協作圖如圖5所示。
圖5描述的對象關系如下:用戶向“服務界面”請求服務,“服務界面”向“響應處理”發送“請求服務”,“響處理”向“獲取服務”發送“請求服務”,“獲取服務”向“服務界面”發送“服務內容”,“服務界面”向用戶發送“服務內容”。
4.1.3 斷開連接
“斷開連接”子用例的協作圖如圖6所示。
圖6清楚地表示了斷開連接用例中各對象之間的關系:用戶向“斷開界面”請求斷開,“斷開界面”向“響應處理”發送“服務器信息”,“響應處理”向“斷開連接”“服務器信息”,“斷開連接”向“斷開服務”發送“斷開”命令,并向“連接界面”發送“連接建立”,“連接界面”向用戶反饋“連接建立”。
4.2 對象的動態關系
4.2.1 建立連接
“建立連接”子用例的序列圖如圖7所示。
該序列圖通過對象之間的交互,描述了它們的動態關系如下:
在整個應用開始時,程序尚未啟動,此時,只有“用戶”對象。
“用戶”通過“請求下載和鏈接消息”來啟動程序,使得“連接界面”對象開始了它的生存周期。
“連接界面”發送“請求連接”給“響應處理”,使得后者開始其生存周期。
“響應處理”發送“請求連接”給“建立連接”,使得后者開始其生存周期。
“建立連接”創建“獲取服務”并發送“建立連接”,使得后者的生存周期。
“連接界面”告知用戶“連接建立”。
4.2.2 獲取服務
“獲取服務”子用例的序列圖如圖8所示。
該序列圖通過對象之間的交互,描述了它們的動態關系如下:
“用戶”通過“請求服務”來啟動程序,使得“服務界面”對象開始了它的生存周期。
“服務界面”發送“請求服務”給“響應處理”,使得后者開始其生存周期。
“響應處理”發送“請求服務”給“獲取服務”,使得后者開始其生存周期。
“建立連接”發送“服務內容”給“連接界面”。
4.2.3 斷開連接
“斷開連接”子用例的序列圖如圖9所示。
該序列圖通過對象之間的交互,描述了它們的動態關系如下:
在整個應用開始時,程序尚未啟動,此時,只有“用戶”對象。
“用戶”通過“請求斷開消息”來斷開程序,使得“斷開界面”對象開始了它的生存周期。
“斷開界面”發送“請求斷開”給“響應處理”,使得后者開始其生存周期。
“響應處理”發送“請求斷開”給“斷開連接”,使得后者開始其生存周期。
“斷開連接”創建“斷開服務”并發送“斷開連接”,使得后者的生存周期。
“斷開界面”告知用戶“連接斷開”。
5 系統詳細設計
5.1 界面設計
界面設計圖如圖10所示。
5.2 功能設計
Web瀏覽器的主體框架類為WebBrowser類,實現框架上各個組件的事件監聽。主要包括4個模塊:圖形用戶界面的構建、組件監聽接口的實現、文件保存功能的實現以及查看源代碼框架的生成。其類圖如圖11所示。
在圖11中:
1) JToolBar、JTextField、JMenuBar、JMenu、JMenuItem等都是和界面有關的屬性。
2) actionPerformed(ActionEvent e):void是用來實現監聽器接口的actionPerformed函數。
3) saveFile(final String url):void是用來保存文件的。
4) getHtmlSource(String url):void是用來獲得源代碼的。
5) hyperlinkUpdate(HyperlinkEvent e):void是實現超鏈接事件監聽器接口的hyperlinkUpdate方法。
6) main(String [] args):void生成一個IE對象,是程序的入口。
在這個核心類中將分別實現在系統總體結構設計中各個功能模塊。
ViewSourceFrame類的主要功能是實現了源文件查看的主體框架,并實現了源文件的保存功能。主要包括兩個模塊:圖形用戶界面的構建;組件監聽接口的實現。其類圖如圖12所示。
1) JPanel contentPane、JButton、JScrollPane、JTextArea等都是和界面有關的屬性。
2) actionPerformed(ActionEvent e):void是實現動作事件監聽器接口的actionPerformed方法。
服務器端設計成Dos程序界面,在后臺運行,提供服務。
1) ConnnectionThread類完成與一個Web瀏覽器的通信。
2) boolean getrequest(String s)判斷請求類型是否為“GET”。
3) String getfilename(String s)獲取要訪問的文件名。
4) void sendfile(PrintStream outs, File file)將指定文件發送給Web瀏覽器。
5.2.1 瀏覽器建立連接
瀏覽器建立連接的實現過程:用actionPerformed()方法響應ActionEvent事件來建立連接。
1) 在地址欄輸入地址后點擊轉向按鈕,e.getSource() = button,url = jurl.getText()就獲得地址欄的內容。
2) 如果url不為空,并且以“http://”開頭,JEditorPane組件將顯示url的內容鏈接,并將url的內容添加到ArrayList型對象history中,設置historyIndex的值,重新布局,調用jEditorPane1.revalidate()。
3) 如果鏈接顯示失敗,則彈出選擇對話框“無法打開該搜索頁”,調用JOptionPane.showMessageDialog (WebBrowser.this,\"無法打開該搜索頁\",\"網頁瀏覽器\",JOptionPane.ERROR_MESSAGE)。
4) 如果url不為空,并且不以“http://”開頭,url=“http://”+url,即自動在url前面添加“http://”。
如果鏈接顯示失敗,則重復c步驟的操作。
5) 如果沒有輸入url,即url為空,輸出提示:JOptionPane.showMessageDialog (WebBrowser.this,\"請輸入鏈接地址\",\"瀏覽器\",JOptionPane.ERROR_MESSAGE)。
5.2.2瀏覽器獲取服務
瀏覽器獲取服務的實現過程:用hyperlinkUpdate()方法響應HyperlinkEvent事件來獲取所需的服務。
1) 如果e.getEventType() == HyperlinkEvent.EventType.ACTIVATED,則激活該類型,調用jEditorPane1.setPage(e.getURL())獲取服務。
2) 在過程中若出現錯誤,則將錯誤顯示ex.printStackTrace(System.err)。
5.2.3 瀏覽器斷開連接
瀏覽器斷開連接的實現過程:用Process windowEvent()方法響應WindowEvent事件執行斷開連接的操作,并關閉窗體。
首先獲取ID,如果getID()==WindowEvent.WINDOW_CLOSING)則System.exit(0),則關閉窗口。
5.2.4 服務器端允許建立連接
服務器端允許建立連接的實現過程:
1) 定義端口號為PORT=8080,ServerSocket server=1;Socket client=1;初始化客戶端和服務器端的套接字。服務器套接字等待請求通過網絡傳入,它基于該請求執行某些操作,然后可能向請求者返回結果。
2) 定義一個try方法,接受客戶機的連接請求,client=server.accept()。
3) catch方法進行異常捕捉,在將錯誤顯示出來System.out.println(e)。
4) 定義一個ConnnectionThread類完成與一個Web瀏覽器的通信。
5) 連接Web瀏覽器的套接字,Socket client。并定義一個計數器counter。
5.2.5服務器端提供服務
服務器端提供服務的實現過程:
1) 構造線程體run,用try方法獲取客戶機IP地址和端口號。
2) inline=instream.readLine(),讀取Web瀏覽器提交的請求信息。
3) 如果是GET請求,filename=getfilename(inline)。
4) 若文件存在,則將文件送給Web瀏覽器System.out.println(filename+\" requested.\")。
5) 發送文件,sendfile(outstream, file)。
6) 若文件不存在,outstream.println(\"HTTP/1.0 404 no found\")。
7) instream.close(),outstream.close()關閉輸入輸出流。
8) 若IOException e發生異常,則用catch方法捕捉異常。
5.2.6 服務器端斷開連接
服務器端斷開連接的實現過程:調用outs.flush()方法刷新緩沖的輸出流,in.close()斷開服務器連接。
6 運行流程及說明
6.1 瀏覽器初始界面
運行瀏覽器程序后,將會出現初始的界面.
6.1.1 界面說明
地址:輸入IP地址。
轉向:點擊轉向地址欄中輸入的IP地址,也可以用回車鍵代替。
另存為:把當前頁面保存下來。
后退:退回上一個瀏覽的頁面。
前進:前進到之后的一個瀏覽頁面。
查看源代碼:查看當前頁面的源代碼。
退出:退出瀏覽器。
6.1.2 創建瀏覽器界面代碼說明
在WebBrowser類中創建瀏覽器界面和各菜單欄,包括:地址欄、網頁顯示界面、菜單欄、菜單組、菜單項、工具欄、工具欄中的按鈕組件等。部分代碼如下:
JButton picSave = new JButton(\"另存為\");
JButton picBack = new JButton(\"后退\");
JButton picForward = new JButton(\"前進\");
JButton picView = new JButton(\"查看源代碼\");
JButton picExit = new JButton(\"退出\");
JLabel label=new JLabel(\"地址\");
JButton button=new JButton(\"轉向\");
6.2 連接服務器界面
輸入IP地址后按回車鍵就會顯示相應的頁面,這表明連接成功。
在轉向按鈕上增加監聽器,觸發執行相關操作,通過填寫輸入,輸出端口的文本區獲取端口號,定義一個public void actionPerformed(ActionEvent e)方法進行事件偵聽,分析地址欄內的內容,若e.getSource() == jurl,url=jurl.getText ();獲取地址欄的內容。將url的內容添加到ArrayList型對象history中,設置historyIndex的值,重新布局,用catch()方法獲取異常捕捉。具體代碼如下:
public void actionPerformed(ActionEvent e) {
String url = \"\";
if (e.getSource() == button){
url=jurl.getText ();
if(url.length ()>0url.startsWith (\"http://\")){
try { jEditorPane1.setPage (url);
history.add(url);
historyIndex=history.size()-1;
jEditorPane1.setEditable(1); //add by copy editor :)
jEditorPane1.revalidate ();
}
catch(Exception ex) {
JOptionPane.showMessageDialog (WebBrowser.this,\"無法打開該搜索頁\",\"網頁瀏覽器\",JOptionPane.ERROR_MESSAGE);}}
// 轉向按鈕相關操作結束
6.3 查看源代碼界面
在點擊查看源代碼按鈕后,根據url,獲得源代碼,生成顯示源代碼的框架對象,并用public ViewSourceFrame (String htmlSource)方法初始化圖形界面,用setBounds方法設置窗口大小,設置setVisible屬性為true。
if (e.getSource() == sourceItem ||e.getSource() == picView){
url = jurl.getText ().toString ().trim ();
if(url.length ()>0!url.startsWith (\"http://\")) {
url=\"http://\"+url; }
if( !url.equals (\"\")) {
getHtmlSource (url);
ViewSourceFrame vsframe = new ViewSourceFrame (htmlSource);
vsframe.setBounds (0,0,800,500);
vsframe.setVisible(true); }
else { JOptionPane.showMessageDialog (WebBrowser.this,\"請輸入鏈接地址\",\"網頁瀏覽器\",JOptionPane.ERROR_MESSAGE);}}
6.3 保存網頁界面
在點擊另存為按鈕后,根據當前頁面,用saveFile()方法將頁面信息保存下來。相關代碼如下:
if (e.getSource() == picSave||e.getSource() == saveAsItem){
url = jurl.getText ().toString ().trim();
if(url.length ()>0!url.startsWith (\"http://\")) {
url=\"http://\"+url; }
if(!url.equals (\"\")) {
saveFile(url);}
else {
JOptionPane.showMessageDialog (WebBrowser.this,\"請輸入鏈接地址\",\"網頁瀏覽器\",JOptionPane.ERROR_MESSAGE);}}
//另存為的代碼結束
7 結束語
經過一段時間的設計和開發,Web服務器及瀏覽器終于完成,其基本功能已實現,瀏覽器能夠訪問Web服務器,通過輸入正確的URL獲取超文本并顯示,同時可以查看源代碼并保存頁面;服務器能夠提供Web服務。
但是由于多方面因素的影響,設計完成略顯倉促,這也導致該系統還有許多不盡如人意的地方,比如用戶界面不夠美觀,刷新網頁、收藏網頁等功能未實現,出錯處理也考慮不周,這些都有待進一步改善。
要完成好這項工作必須在掌握必備的理論知識前提下,不斷實踐,積累經驗,提高分析問題和解決問題的能力。
參考文獻:
[1] 馮博,應群.面向對象的Java網絡編程[M].北京:清華大學出版社,2004.
[2] 張大治,應群.精通Eclipse[M].北京:清華大學出版社,2006.
[3] 董蘭芳.UML課程設計[M].北京:機械工業出版社,2005.
[4] Tanenbaum A S.計算機網絡[M].潘愛民,譯.4版.北京:清華大學出版社,2004.