在NetBeans環境下的Servlet編程
按照網絡應用程序三層構架的劃分,我們至少需要一個瀏覽器、一個應用程序服務器、一個數據庫服務器。瀏覽器 已經是每臺計算機的標配;支持Java EE的應用程序服務器,例如開源的Apache Tomcat、Oracle的Glassfish、BEA公司的WebLogic、IBM的Websphere等;還需要某款數據庫產品,以進行數據的持久化儲存,例如SQL Server、MySQL、Oracle、DB2、Access等。
本文主要講解Servlet編程,主要包括以下幾部分:
- 開發環境的搭建
- HTTP通訊協議基本概念
- Servlet編程基礎
- 用戶登錄響應的實現
一、開發環境的搭建
1、軟件下載
在學習Servlet編程之前,首先需要搭建開發環境,一款方便快捷的開發工具不僅帶來一個好的開始,而且增加學習興趣,本人使用NetBeans IDE,原因有二:
(1)配置簡單,安裝之後直接使用,不用再進行配置
(2)免費,性價比高
開發環境的搭建需要安裝JDK和NetBeans,鏈接如下:
JDK:oracle官網
NetBeans:NetBeans IDE下載頁面
2、NetBeans IDE開發
NetBeans IDE開發包括開發控制檯程序和Web應用程序
(1)NetBeans IDE開發控制檯程序
(2)NetBeans IDE開發Web應用程序
二、HTTP通訊協議基本概念
1、HTTP協議介紹
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。
2、HTTP協議特點
HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適用於分佈式超媒體信息系統。
HTTP協議的主要特點可概括如下:
1)支持客戶/服務器模式。
2)簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不同。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
3)靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4)無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
5)無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
3、HTTP的基本運行方式
1)基於HTTP協議的客戶/服務器模式的信息交換過程,分四個過程:建立連接、發送請求信息、發送響應信息、關閉連接,如圖所示,
2)瀏覽器與WEB服務器的連接過程是短暫的,每次連接只處理一個請求和響應。對每一個頁面的訪問,瀏覽器與WEB服務器都要建立一次單獨的連接。
3)瀏覽器到WEB服務器之間的所有通訊都是完全獨立分開的請求和響應。
三、Servlet編程基礎
1、Servlet的作用
Servlet是用Java編寫的Server端程序,它與協議和平臺無關。Servlet 通過創建一個框架來擴展服務器的能力,以提供在 Web 上進行請求和響應服務。當客戶機發送請求至服務器時,服務器可以將請求信息發送給 Servlet ,並讓 Servlet 建立起服務器返回給客戶機的響應。 當啓動 Web 服務器或客戶機第一次請求服務時,可以自動裝入 Servlet 。裝入後, Servlet 繼續運行直到其它客戶機發出請求。
2、Servlet實現過程
Servlet 的主要功能在於交互式地瀏覽和修改數據,生成動態 Web 內容。這個過程爲:
1) 客戶端發送請求至服務器端;
2) 服務器將請求信息發送至 Servlet;
3) Servlet 生成響應內容並將其傳給服務器。響應內容動態生成,通常取決於客戶端的請求;
4) 服務器將響應返回給客戶端。
一個 Servlet 就是 Java 編程語言中的一個類,它被用來擴展服務器的性能,服務器上駐留着可以通過“請求-響應”編程模型來訪問的應用程序。雖然 Servlet 可以對任何類型的請求產生響應,但通常只用來擴展 Web 服務器的應用程序。
3、Servlet的生命週期
servlet的生命週期:
1)servlet有良好的生命週期的定義,包括加載、實例化、初始化、處理請求及服務結束。
2)這個生命週期由javax.servlet.Servlet接口的init()、service()、destroy()方法來表達。
3)首先,servlet容器加載servlet,完成servlet的實例化,容器運行servlet實例的init()方法進行初始化,服務請求到達時,調用service()方法,由service()方法自動運行與請求對應的doXXX()方法(即doGet或doPost),當服務器決定將實例銷燬時,調用其destroy()方法。
Servlet被裝載後,Servlet容器創建一個Servlet實例並且調用Servlet的init()方法進行初始化。在Servlet的整個生命週期內,init()方法只被調用一次。
四、用戶登錄響應的實現
本文建立了一個簡單的網頁交互—-用戶登錄響應,先看看登錄頁面,用戶輸入相應的用戶名和密碼,當用戶名存在且密碼正確時,可進入正式頁面(本文用“歡迎光臨!”頁面代替),若用戶不存在或者密碼錯誤時,會彈出相應的錯誤提示界面。
1、預備知識
(1)Servlet讀取客戶端發送過來的數據
客戶端發送到服務器的數據分爲顯式數據和隱式數據,顯式數據是指用戶通過瀏覽器主動向服務器提交的以超鏈接或表單顯式提交的信息,從服務器的角度看,這些只不過是get或者post請求,在NetBeans IDE中,使用Servlet技術處理客戶端請求時,只需在其processRequest中編寫邏輯代碼即可。隱式數據是指瀏覽器在用戶沒有意識到的提交的其他信息,如請求頭的相關信息,獲取請求頭的信息編程如下:
創建一個名爲“ShowHeadServlet”的Servlet,代碼如下:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
try{
Enumeration allHeaderName=request.getHeaderNames();
out.print("<table>");
while(allHeaderName.hasMoreElements()){
String headerName=(String)allHeaderName.nextElement();
String headerValue=request.getHeader(headerName);
out.print("<tr>");
out.print("<td>"+headerName+"</td>");
out.print("<td>"+headerValue+"</td>");
out.print("<tr>");
}
out.print("<table>");
}finally{
out.close();
}
}
右鍵點擊ShowHeadServlet的運行文件,顯示如下:
(2)響應的重定向和請求的轉發
1)請求的轉發:RequestDispatcher對象是一個Web資源的包裝器,可以用來把當前請求轉發到該資源。 這種轉發是在服務器端控制權的轉向,客戶端發來的請求將交由新的頁面進行處理。 使用請求轉發,在客戶的瀏覽器地址欄中不會顯示轉發後的資源地址。 使用請求轉發,可以將前一個頁面的數據、狀態等信息傳到轉發的頁面。
2)響應的重定向:sendRedirect()方法實際是服務器向瀏覽器發送一個特殊的響應頭(Location,狀態碼302), 它命令瀏覽器連接到新的位置。 因此,使用這種方法在瀏覽器的地址欄中可以看到地址的變化。 重定向是作爲不同請求來看待的,因此,所有請求作用域的參數在重定向到下一個頁面時都會失效。 使用sendRedirect()方法重定向時,資源不能位於WEB-INF目錄中。
2、具體實現
(1)建立項目
打開NetBeans IDE,新建一個Java Web項目,其中index.jsp爲歡迎頁面,login.jsp爲登錄頁面,ShowHeadServlet.java用於顯示隱式信息,ShowMsgServlet1.java用於從登錄界面到其他界面的邏輯編程,項目的框架圖如下:
(2)核心代碼
a)index.jsp歡迎頁面
<body>
<h1>歡迎光臨!</h1>
</body>
b)login.jsp登錄頁面
<body>
<form name="frm" method="POST" action="ShowMsgServlet1">
<table frame="box" cellspacing="5" align="left">
<tr>
<td colspan="2" align="center"><p><h3>用戶登錄</h3></p></td>
</tr>
<tr>
<td><label for="username">用戶名</label></td>
<td><input type="text" name="username" value=""/></td>
</tr>
<tr>
<td><label for="userpass">密 碼</label></td>
<td><input type="password" name="userpass" value=""/></td>
</tr>
<tr>
<td colspan="2">
<input type="image" src="./newbtn.png" width=100%
height=80% border="0" value="登錄"
onclick="document.forms['frm'].submit();">
</td>
</tr>
<tr> </tr>
</table>
</form>
</body>
c)ShowMsgServlet1.java邏輯代碼
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");//設置編碼方式爲UTF-8,能正確顯示漢字
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
try{
String username=request.getParameter("username");
String userpass=request.getParameter("userpass");
if("admin".equalsIgnoreCase(username)&&"1234".equals(userpass)){
RequestDispatcher rd=request.getRequestDispatcher("index.jsp");
rd.forward(request, response);
}else{
out.print("用戶名或者密碼錯誤,請重新輸入!");
RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
rd.include(request, response);
}
out.printf(username);
}finally{
out.close();
}
}
(3)運行結果
a)成功登錄時
b)用戶名或者密碼錯誤時