- 互聯網金融信息系統的設計與實現
- 梁循 楊健 陳華
- 4187字
- 2020-05-22 18:47:03
5.3 使用Servlet和JSP技術開發互聯網系統
Java語言是一個面向對象的語言。每一個類可以看作是一個獨立的個體,完成不同的功能,彼此功能不重疊。各個類之間互相協調工作,組成一個條理分明、工作有序的整體,從而使程序體可讀性強、出錯率低、易調試,編程速度和質量都大大提高。從工程的角度上說,開發費用和維護費用都有較大程度地降低。
Java的一個最大優勢就是網絡編程。當前Java Web應用的范圍非常廣泛,Servlet就是最主要的Java Web組件之一,它運行在服務端的Servlet容器當中,使用的是“request/response(請求/響應)”的工作模式。JSP(Java server page)技術作為Servlet的擴展,其目的是簡化建立和管理動態網站的工作,能夠很有效地分離業務邏輯和顯示邏輯。
5.3.1 Servlet概述
Java Servlet是與平臺無關的服務器端組件,它在Web服務器上或應用服務器上運行并擴展了該服務器的能力,Java Servlet API定義了Servlet和服務器之間的一個標準接口,這使得Servlet具有跨服務器平臺的特性。
在傳統的CGI中,每個請求都要啟動一個新的進程,如果CGI程序本身的執行時間較短,啟動進程所需要的開銷很可能反而超過實際執行時間。而使用Servlet時,服務器上僅有一個Java虛擬機在運行,只有當Servlet被調用時,它才被加載,且直到Servlet更改時,它才會被再次加載。在傳統CGI中,如果有N個并發的對同一CGI程序的請求,則該CGI程序的代碼在內存中重復裝載了N次;而對于Servlet,處理請求的是N個線程,只需要一份Servlet類代碼。在性能優化方面,Servlet也比CGI有著更多的選擇,比如緩存以前的計算結果,保持數據庫連接的活動等。
通過使用Servlet API,開發人員不必擔心服務器的內部運作方式。表格資料、服務器頭、cookies等皆可通過Servlet處理。另外,因為Servlet是用Java寫的,能將其從一個服務器移到另一個服務器以供發布,同時不必擔心操作系統或服務器的類型。這一優點充分體現了Java“一次編寫,隨處運行”的優越特性。
Servlet可完成如下功能:
(1)創建并返回基于客戶請求的動態HTML頁面。
(2)創建可嵌入到現有HTML頁面中的部分HTML頁面(HTML片段)。
(3)與其他服務器資源(如文件、數據庫或Java應用程序等)進行通信。
(4)接受多個客戶機的輸入,并將結果廣播到多個客戶機上。例如,Servlet可實現多人參與的游戲服務器。
(5)根據客戶請求采用特定的MIME(multipurpose Internet mail extensions)類型對數據過濾,例如進行圖像格式轉換等。
Servlet的框架由兩個Java包組成:javax.servlet和javax.servlet.http。在javax.servlet包中定義了必須實現或擴展的通用接口(interface)和類(class); javax.servlet.http包中定義的則是采用HTTP協議通信的HttpServlet類。Servlet框架的核心是javax.servlet.Servlet接口,所有的Servlet都必須實現這個接口。
5.3.2 JSP概述
JSP技術是由Servlet擴展出來的,結合傳統網頁的HTML標簽和JSP標簽就構成了JSP網頁,可以被用來操作數據庫、重定向網頁以及發送E-mail等。
使用JSP可以有效地分離HTML編碼和業務邏輯,通常JSP被用來實現動態的HTML頁面,業務邏輯由其他可重用的組件(Servlet、JavaBean)和Java程序來實現,JSP可通過程序片斷來訪問這些業務組件。
一般情況下,JSP文件在Web服務器端會被解析成Servlet來執行,其過程是:當一個JSP請求發送過來之后,Web服務器就會對JSP文件進行解析生成Servlet源文件,然后會被編譯器編譯生成Java class,這個過程僅在JSP被初次調用時發生,如果JSP文件發生改變,服務器再去解析一遍重新編譯產生class文件,過程如圖5-14所示。

圖5-14 Web服務器初次解析JSP流程
對于一個正常的JSP文件,通常包括以下一些主要內容:
1.JSP指令
用來設置和整個JSP頁面相關的屬性,如網頁的編碼方式和腳本語言等,這部分內容放在<%@和%>之間,指令的語法形式為<%@ 指令名 屬性=“值”%>。常用的指令為page, include和taglib,例如:
<%@ page contentType=″text/html; charset=GBK″%><! --注釋 指定響應結果類型--> <%@ page import=″cn.edu.pku.icst.dm.*″%><! --指定導入的軟件包名-->
2.JSP聲明
用于聲明JSP所代表的Servlet類的成員變量和成員方法,代碼放置在<%!和%>之間,例如:
<%! String stock_id=new String(″600000″); %> <! --注釋 聲明一個String類型變量-->
聲明只在當前的JSP文件中有效,如果當前頁面所包含的頁面文件中存在聲明,則同樣在當前的JSP頁面有效。
3.Java程序段(scriptlet)
由于JSP技術是基于Java的動態網頁技術,所以會用到Java的相應程序代碼,這些代碼在JSP文件中被放在<%和%>之間,可以實現Java程序能夠在前端實現的功能,例如:
<% if(session.isNew()! = true){ //判斷會話是否已經過期 session.invalidate(); //使會話失效 } response.sendRedirect(″login.jsp″); //使頁面轉向login.jsp %>
4.變量表達式
Java變量表達式標記為<%=和%>,該表達式的值會被顯示到前端頁面上,以下是包含變量表達式的例子:
<%=stock_id%> //輸出到網頁上顯示
5.隱含對象
Servlet/JSP容器提供了一系列的隱含對象,可以直接使用它們,不用進行聲明,JSP有9個隱含對象,如表5-1所示。
表5-1 JSP隱含對象列表

5.3.3 JavaBean組件
JavaBean是Java類,它是一個Java Web應用的標準部件,被定義為一種可重復使用、跨平臺的軟件構件。JavaBean分為兩種:一種是有界面(UI)的JavaBean,還有一種是沒有界面的,主要負責處理事務的JavaBean。使用JSP可以訪問JavaBean,通常JSP訪問的是無界面的JavaBean,以實現某種邏輯功能。
JavaBean的實現需要一個公共(public)的Java類(class)的聲明,該類需要有一個不帶參數的構造方法,JavaBean中的屬性通過setXXX()方法來進行設置,通過getXXX()方法進行屬性獲取,這樣的方法通常都被聲明成公共(public)的。JavaBean中除了可以定義set和get方法,也能定義一些其他的具有特定功能的方法來協助處理事務。
以下是一個JavaBean類的代碼示例,該JavaBean名為StockBean,在這個JavaBean中定義了一個屬性num,還定義了訪問這個屬性的方法setNum()和getNum():
package cn.edu.pku.icst.dm public class StockBean{ private int num=100; public StockBean(){} public int getNum(){ return num; } public void setNum(int num){ this.num= num; } }
JavaBean屬于具有規范編碼方式的組件,并且擴展了適應性和范圍,允許用戶訪問內部的屬性和方法。
在開發互聯網信息挖掘系統中使用JavaBean,主要是通過和JSP搭配來處理相應的請求,同時還有Servlet進行相應事務和請求的處理,這樣能夠使得系統的開發更加規范和高效。
JavaBean結合JSP使用的優勢主要體現在以下幾個方面:
(1)JavaBean的使用可以更好地將HTML與Java代碼進行分離,便于系統的維護工作。單一地依靠JSP來完成同樣的功能會使得代碼變得繁雜。
(2)分離地實現可以降低JSP網頁編程人員對Java編碼能力的要求,提高網頁的實現效率。
(3)使用JSP重點實現動態網頁,事務處理可交由JavaBean完成,能夠充分利用JavaBean組件的可重用性特點。
在動態網頁JSP中使用JavaBean的操作也很簡單,首先是導入JavaBean類,使用<%@page import %>指令進行,舉例如下:
<%@page import=″cn.edu.pku.icst.dm.StockBean″%>
接下來在下面的JSP文件中對JavaBean進行聲明,使用<jsp:useBean>標簽進行,如下:
<jsp:useBean id=″stockbean″class=″cn.edu.pku.icst.dm.StockBean″scope=″session″/>
然后就可以訪問該JavaBean的屬性了,通過標簽<jsp:getProperty>和<jsp:setProperty>來操作使用:
<jsp:getProperty name=″stockbean″property=″num″/> <! --注釋:得到屬性值--> <jsp:setProperty name=″stockbean″property=″num″value=″50″/> <! --設置屬性值-->
5.3.4 Java Web組件應用
運行在互聯網上的系統一般采用當前很流行的Java Web組件技術,能夠很方便地構造基于Web的應用程序。
考慮到MVC模式能夠通過分離數據及其表示來分離控制邏輯和表現界面,使用該模式可降低系統中各個模塊之間的耦合,從而增強代碼的可重用性和可維護性。這里采用如圖5-15所示的一個結構。

圖5-15 系統設計模式圖
圖5-15中所示Servlet用來處理用戶從瀏覽器提交的請求,通過相應的JavaBean實現到數據層的交互,最后經過JSP將響應發回到相應的用戶端,數據庫的連接由一個連接的緩沖池來建立,可以提高存取數據的效率。
這里簡要介紹一個金融文件上傳系統的基本功能設計實現過程,主要是Java Web組件的應用。金融信息的提交包含許多與上市公司相關的信息,如公司名稱、地址、電話、傳真以及人員信息等。為了更加有效地對這些信息資源進行管理,我們在系統中需要設計合理的數據庫結構來配合系統的運行。
系統面向的對象有兩個,即管理員、普通用戶,他們各自的分工有所不同,管理員負責對所有用戶和他們上傳內容的管理,普通用戶有權對上傳的金融文件信息和個人資料進行調整。
按照上述的設計模式,成功地實現了一個金融文件信息的上傳系統。
用Java實現的類主要有如下幾個:
(1)Registerservlet,用戶注冊和修改個人資料功能;
(2)LoginServlet,用戶登錄驗證功能;
(3)FileUploadServlet,信息及文件上傳功能;
(4)PropertyConfig,為JavaBean,具有屬性配置讀取功能;

圖5-16 類關系圖
(5)DeleteServlet,信息刪除功能;
(6)SendMail,發送郵件功能。
主要的類之間的邏輯關系如圖5-16所示。
用戶登錄界面由JSP動態實現,包含一些供用戶輸入名稱和密碼的界面,并包含驗證JavaBean來進行輸入有效性檢查,主要部分如下:
<%@page contentType=″text/html; charset=GB2312″%> <! --頁面信息--> <%@page import=″cn.edu.pku.icst.dm.ValidateBean″%> <! --引入有效性驗證包--> <html> <head> <title>金融文件上傳系統 - 登錄</title> ... <jsp:useBean id=″validate″class=″cn.edu.pku.icst.dm.ValidateBean″scope=″application″/> <! --對有效性驗證JavaBean進行聲明--> <% String username= request.getParameter(″user″); boolean isNamealidate= validate.isValicate(username); //調用JavaBean進行有效性驗證 %> ... </html>
用戶注冊是用Servlet來實現的,用戶輸入基本信息,然后提交到系統,可以產生一個新的用戶賬號。這個類可以被用來更新用戶個人資料,也就是通過改變傳遞的參數來區分是新注冊用戶還是老用戶的資料修改。代碼按照Servlet的寫法,處理方法在doGet()中實現,如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ response.setContentType(CONTENT_TYPE); request.setCharacterEncoding(″GB2312″); //設置頁面編碼 String username= (String)request.getParameter(″username″); //獲取用戶資料參數 String email= (String)request.getParameter(″email1″); String addr= (String)request.getParameter(″addr″); String phonee= (String)request.getParameter(″phone″); register(username, pwd, email, addr, phone); //調用注冊方法 }
用戶登錄也是用Servlet實現,用戶在登錄界面輸入他的用戶名和密碼,如果正確則會被賦予一定的權限來進入到系統中,可以執行權限范圍內的操作。
在模塊的處理過程中首先會按照用戶輸入的名稱進行查詢,獲取密碼之后會和用戶輸入的密碼進行比較,然后會從數據庫中返回應有的權限,如果失敗則回到登錄頁重新進入,利用doGet或doPost方法均可實現,只是接受參數的方式不一樣,doGet方法實現如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ response.setContentType(CONTENT_TYPE); request.setCharacterEncoding(″GB2312″); //設置頁面編碼 String username= (String)request.getParameter(″username″); //獲取用戶輸入參數 String password= (String)request.getParameter(″password″); checkUser(username, pwd); //調用檢查用戶方法 }
doPost方法中嵌入doGet的處理方式可以處理前端頁面post方式提交過來的請求,代碼如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ doGet(request, response); }
系統中同時需要使用發送電子郵件(E-mail)通知用戶的功能,對于這一功能我們通過編寫一個JavaBean調用javamail包來實現,類名為SendMail,實現的相應功能方法如下:
private void sendMessage(String recipient, String subject, String message){ Properties props= new Properties(); props.put(″mail.smtp.auth″, ″false″); props.put(″mail.host″, SMTP_HOST); props.put(″mail.smtp.user″, ″″); props.put(″mail.smtp.password″, ″″); Session session= Session.getDefaultInstance(props, null); try{ Message msg= new MimeMessage(session);
msg.setFrom(new InternetAddress(SENDER_EMAIL_ADDRESS, SENDER_NAME)); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient)); msg.setSubject(subject); msg.setSentDate(new Date()); msg.setText(message); //設置發送的信息內容 Transport transport= session.getTransport(″smtp″); transport.connect((String)props.get(″mail.smtp.host″), props.getProperty(″mail.smtp.user″), props.getProperty(″mail.smtp.password″)); transport.sendMessage(msg, msg.getAllRecipients()); }catch(Exception e){ System.out.println(e); } }
關于Java Web組件的使用,限于篇幅的原因就不做過多的介紹了,相應系統的詳細實現過程可以在后續的章節中看到。