Java Servlet 入門

Many examples in this document are adapted from Java: How To Program (3rd Ed.), written by Deitel and Deitel, and Thinking in Java (2nd Edition), written by Bruce Eckel. All examples are solely used for educational purposes. Hopefully, I am not violating any copyright issue here. If so, please do email me.

Please install JDK 1.3.1_02 or later with Java Plugin to view this page. Also, this page is best viewed with browsers (for examples, Mozilla 0.99 or later, IE 6.x or later) with CSS2 support. This document is provided as is. You are welcomed to use it for non-commercial purpose.

在以下的範例中,我們假設你已經在你自己的電腦上面安裝好了 Apache Tomcat 而且 port 為 8080。
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu

請勿轉貼

看其他教材


目錄

  1. Hello World -- Servlet
  2. Servlet vs. CGI
  3. Servlet 的生命週期
  4. Greeting -- Servlet
  5. Servlet and DB
  6. 從 web.xml 讀取初始值
  7. 從 servlet 讀取一個檔案
  8. Cookie
  9. Session

Hello World -- Servlet

簡單的說, Java servlets 就像我們所寫的 CGI 程式一樣,它們是在 伺服器端執行的程式(它們也是 Java 的 applications 而不是 applets),也就是因此當後端 servlet 要連結資料庫(或者存取 檔案)時,它們並沒有像 applet 一樣的受到限制,也由於它們是在後端處理 而所處理後的結果是 HTML,servlets 的使用也不受 browser 的限制。 首先我們先看一個小程式 -- Hello World -- servlet 版。為了能夠 compile 以下程式, 我們假設你們已經安裝好了 Apache Tomcat 5.0.28 版,並已經設定了 CLASSPATH 的環境變數 set CLASSPATH=%CLASSPATH%;d:\tomcat\lib\common\servlet-api.jar.
//
// Hello World Servlet Version
//
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HelloServ extends HttpServlet
{
  // HttpServletRequest 是用來存放由使用者傳過來的資料
  // HttpServletResponse 是用來存放要回應給客戶端的資料
  // doGet 是給 GET 方法用的,而 doPost 是給 POST 方法用的。
  // 現在大多使用 service() 來取代 doGet and doPost
  public void doGet(HttpServletRequest req, HttpServletResponse res)
         throws ServletException, IOException
  {
    PrintWriter output;

    // 若要輸出中文字,記得要加 charset=Big5
    res.setContentType("text/html;charset=Big5");
    output = res.getWriter();

    StringBuffer buf = new StringBuffer();
    buf.append("<html><head><title>\n");
    buf.append("Hello World\n");
    buf.append("</title></head><body>\n");
    buf.append("<h1>大家好</h1>\n");
    buf.append("</body></html>\n");
    output.println(buf.toString());
    output.close();
  }
}
如果你已經把 Apache Tomcat 安裝好,而且你能正確無誤的把這個程式 在 tomcat\webapps\ROOT\WEB-INF\classes 的目錄 compile 好, 你可以

Servlet vs. CGI

有如之前所說的,Java Servelet 是因為 CGI 非常沒效率而設計出來的, 為了提昇效率,不論同時有多少服務請求(requests),只有一份該服務 的 Java Servelet 會載入 JVM 中。每一次當有服務請求時,則會產生一個 執行緒(thread)而不是一個新的處理程序(process),因此記憶體使用 減少,速度變快。另外,Java Servelet 具有永續性(persistent),即使 服務請求已經完成,Java Servelet 依舊存在。

讓我們利用 HelloServ.java 來試著表現出永續性。請宣告一個 HelloServ 的屬性 int count = 0;請注意,不是幫 main 宣告一個 local variable),並在 <h1></body> 之間加入

buf.append("accessed " + count++ + " times.");
並試著執行

Servlet 的生命週期

The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.

  1. If an instance of the servlet does not exist, the Web container
    1. Loads the servlet class.
    2. Creates an instance of the servlet class.
    3. Initializes the servlet instance by calling the init method. 你可以覆載 init() 方法,而 init() 內的 statements 在生命週期中只會被執行一次。 注意, init() 不是每一次收到服務請求時都會執行。 要如何測試這個 敘述為真?試著在 init() 宣告 int count2 = 5;,並在這之後,加上 count += count2;。想想看,如果 init() 在生命週期中只執行一次, 和每一次被呼叫時便執行一次的差別在哪裡?最後,執行程式然後驗證結果。
  2. Invokes the service method, passing a request and response object.
If the container needs to remove the servlet, it finalizes the servlet by calling the servlet's destroy method.

Greeting -- Servlet

以下只是使用 form 元件的部分範例,其他的元件請自行學習!

Servlet and DB

從 web.xml 讀取初始值

在 WEB-INF 的目錄內可以自訂一個 web.xml 檔,在這個檔案內, 你可以設定一些參數來控制 servlet 和 JSP 的執行。在以下的 範例中,我們利用 servlet 來讀取 web.xml 的初始值。

從 servlet 讀取一個檔案

假設你的 servlet 伺服器是 tomcat(安裝於 /usr/local/tomcat),又假設你所安裝 的 context 名稱為 myproject 而需要被讀取的檔案名稱為 test.txt,那麼請將 test.txt 置放於 /usr/local/tomcat/webapps/myproject 的目錄下,並在讀檔的那一行 更改成

File file=new File(getServletContext().getRealPath("/")+"test.txt");

其中 getServletContext().getRealPath("/") 會回傳 /usr/local/tomcat/webapps/myproject.

Cookie

The HTTP protocol does not support persistent information that could help a web server determine that a request is from a particular client. 例如,某些網頁需要知道使用者是否 已經登入,若已經登入便可以看網頁的內容,否則要求使用者登入。 一般來說,有兩種方式可以讓 web server 經由 persistent information 來判斷,而這兩種方法為 Cookie 和 Session。

Cookie 是儲存於客戶端(browser 內)的資料。由於這是一種由 伺服器端的程式傳送資料到客戶端的一種簡易的方式,因此被大量 的使用於 web 為主的系統中,例如客戶輸入的資料,客戶的偏好 等等。這些資料先由伺服器端的程式寫到客戶端,然後之後的聯繫便可以 從這些資料來提供不同的服務。例如我們可以將使用者的帳號以及 密碼存放在 cookie 內,下一次使用者要登入的時候,就可以從 cookie 來判斷,如果已經存在就不需要再輸入一次。

不過,cookie 也有一些限制,例如一個 cookie 不可以超過 4KB, 而瀏覽器也會對 cookie 的總數作限制,cookie 有可能會有不見的 時候,所以程式寫作的時候要謹慎。另外,由於 cookie 大家都能 讀取,因此也有安全上的考量。

Session


Last Updated: Tuesday, 30-Nov-2010 18:20:38 CST
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu