3.1 servlet基本結構
下面的代碼顯示了一個簡單servlet的基本結構。該servlet處理的是get請求,所謂的get請求,如果你不熟悉http,可以把它看成是當用戶在瀏覽器地址欄輸入url、點擊web頁面中的鏈接、提交沒有指定method的表單時瀏覽器所發出的請求。servlet也可以很方便地處理post請求。post請求是提交那些指定了method=“post”的表單時所發出的請求,具體請參見稍后幾節的討論。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class someservlet extends httpservlet {
public void doget(httpservletrequest request,
httpservletresponse response)
throws servletexception, ioexception {
// 使用“request”讀取和請求有關的信息(比如cookies)
// 和表單數據
// 使用“response”指定http應答狀態代碼和應答頭
// (比如指定內容類型,設置cookie)
printwriter out = response.getwriter();
// 使用 "out"把應答內容發送到瀏覽器
}
}
如果某個類要成為servlet,則它應該從httpservlet 繼承,根據數據是通過get還是post發送,覆蓋doget、dopost方法之一或全部。doget和dopost方法都有兩個參數,分別為httpservletrequest 類型和httpservletresponse 類型。httpservletrequest提供訪問有關請求的信息的方法,例如表單數據、http請求頭等等。httpservletresponse除了提供用于指定http應答狀態(200,404等)、應答頭(content-type,set-cookie等)的方法之外,最重要的是它提供了一個用于向客戶端發送數據的printwriter 。對于簡單的servlet來說,它的大部分工作是通過println語句生成向客戶端發送的頁面。
注意doget和dopost拋出兩個異常,因此你必須在聲明中包含它們。另外,你還必須導入java.io包(要用到printwriter等類)、javax.servlet包(要用到httpservlet等類)以及javax.servlet.http包(要用到httpservletrequest類和httpservletresponse類)。
最后,doget和dopost這兩個方法是由service方法調用的,有時你可能需要直接覆蓋service方法,比如servlet要處理get和post兩種請求時。
3.2 輸出純文本的簡單servlet
下面是一個輸出純文本的簡單servlet。
3.2.1 helloworld.java
package hall;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class helloworld extends httpservlet {
public void doget(httpservletrequest request,
httpservletresponse response)
throws servletexception, ioexception {
printwriter out = response.getwriter();
out.println("hello world");
}
}
3.2.2 servlet的編譯和安裝
不同的web服務器上安裝servlet的具體細節可能不同,請參考web服務器文檔了解更權威的說明。假定使用java web server(jws)2.0,則servlet應該安裝到jws安裝目錄的servlets子目錄下。在本文中,為了避免同一服務器上不同用戶的servlet命名沖突,我們把所有servlet都放入一個獨立的包hall中;如果你和其他人共用一個服務器,而且該服務器沒有“虛擬服務器”機制來避免這種命名沖突,那么最好也使用包。把servlet放入了包hall之后,helloworld.java實際上是放在servlets目錄的hall子目錄下。
大多數其他服務器的配置方法也相似,除了jws之外,本文的servlet和jsp示例已經在bea weblogic和ibm websphere 3.0下經過測試。websphere具有優秀的虛擬服務器機制,因此,如果只是為了避免命名沖突的話并非一定要用包。
對于沒有使用過包的初學者,下面我們介紹編譯包里面的類的兩種方法。
一種方法是設置classpath,使其指向實際存放servlet的目錄的上一級目錄(servlet主目錄),然后在該目錄中按正常的方式編譯。例如,如果servlet的主目錄是c:\javawebserver\servlets,包的名字(即主目錄下的子目錄名字)是hall,在windows下,編譯過程如下:
dos> set classpath=c:\javawebserver\servlets;%classpath%
dos> cd c:\javawebserver\servlets\hall
dos> javac yourservlet.java
第二種編譯包里面的servlet的方法是進入servlet主目錄,執行“javac directory\yourservlet.java”(windows)或者“javac directory/yourservlet.java”(unix)。例如,再次假定servlet主目錄是c:\javawebserver\servlets,包的名字是hall,在windows中編譯過程如下:
dos> cd c:\javawebserver\servlets
dos> javac hall\yourservlet.java
注意在windows下,大多數jdk 1.1版本的javac要求目錄名字后面加反斜杠(\)。jdk1.2已經改正這個問題,然而由于許多web服務器仍舊使用jdk 1.1,因此大量的servlet開發者仍舊在使用jdk 1.1。
最后,javac還有一個高級選項用于支持源代碼和.class文件的分開放置,即你可以用javac的“-d”選項把.class文件安裝到web服務器所要求的目錄。
3.2.3 運行servlet
在java web server下,servlet應該放到jws安裝目錄的servlets子目錄下,而調用servlet的url是http://host/servlet/servletname。注意子目錄的名字是servlets(帶“s”),而url使用的是“servlet”。由于helloworld servlet放入包hall,因此調用它的url應該是http://host/servlet/hall.helloworld。在其他的服務器上,安裝和調用servlet的方法可能略有不同。
大多數web服務器還允許定義servlet的別名,因此servlet也可能用http://host/any-path/any-file.html形式的url調用。具體如何進行配置完全依賴于服務器類型,請參考服務器文檔了解細節。
3.3 輸出html的servlet
大多數servlet都輸出html,而不象上例一樣輸出純文本。要輸出html還有兩個額外的步驟要做:告訴瀏覽器接下來發送的是html;修改println語句構造出合法的html頁面。
第一步通過設置content-type(內容類型)應答頭完成。一般地,應答頭可以通過httpservletresponse的setheader方法設置,但由于設置內容類型是一個很頻繁的操作,因此servlet api提供了一個專用的方法setcontenttype。注意設置應答頭應該在通過printwriter發送內容之前進行。下面是一個實例:
hellowww.java
package hall;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class hellowww extends httpservlet {
public void doget(httpservletrequest request,
httpservletresponse response)
throws servletexception, ioexception {
response.setcontenttype("text/html");
printwriter out = response.getwriter();
out.println("<!doctype html public \"-//w3c//dtd html 4.0 " +
"transitional//en\">\n" +
"<html>\n" +
"<head><title>hello www</title></head>\n" +
"<body>\n" +
"<h1>hello www</h1>\n" +
"</body></html>");
}
}
3.4 幾個html工具函數
通過println語句輸出html并不方便,根本的解決方法是使用javaserver pages(jsp)。然而,對于標準的servlet來說,由于web頁面中有兩個部分(doctype和head)一般不會改變,因此可以用工具函數來封裝生成這些內容的代碼。
雖然大多數主流瀏覽器都會忽略doctype行,但嚴格地說html規范是要求有doctype行的,它有助于html語法檢查器根據所聲明的html版本檢查html文檔合法性。在許多web頁面中,head部分只包含<title>。雖然許多有經驗的編寫者都會在head中包含許多meta標記和樣式聲明,但這里只考慮最簡單的情況。
下面的java方法只接受頁面標題為參數,然后輸出頁面的doctype、head、title部分。清單如下:
servletutilities.java
package hall;
public class servletutilities {
public static final string doctype =
"<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">";
public static string headwithtitle(string title) {
return(doctype + "\n" +
"<html>\n" +
"<head><title>" + title + "</title></head>\n");
}
// 其他工具函數的代碼在本文后面介紹
}
hellowww2.java
下面是應用了servletutilities之后重寫hellowww類得到的hellowww2:
package hall;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class hellowww2 extends httpservlet {
public void doget(httpservletrequest request,
httpservletresponse response)
throws servletexception, ioexception {
response.setcontenttype("text/html");
printwriter out = response.getwriter();
out.println(servletutilities.headwithtitle("hello www") +
"<body>\n" +
"<h1>hello www</h1>\n" +
"</body></html>");
}
}
注冊會員,創建你的web開發資料庫,