1.1 接口Servlet
今天我們開始一個有趣的新話題——servlets。正是在 Java 中添加了 servlet,Java 才成為大型服務器應用程序的事實標準。世界上 80% 的企業軟件都是用 Java 編寫的。而在中國,一切都是100%。那麼什麼是servlet?
Servlet 正是將 Java 程序轉換為 Web 服務並允許它處理來自客戶端的請求的東西。是這樣的……
上世紀 90 年代,萬維網出現後,立即出現了網絡客戶端(瀏覽器)和網絡服務器。Web 服務器通常只是簡單地分發它們在 Internet 上存儲的文件:html 頁面、腳本、圖片等。
在某個時候,每個人都得出結論,有必要讓雙方都變得更聰明。JavaScript 被添加到 HTML 頁面,插件被添加到服務器 -響應特定請求而調用的特殊腳本,使服務器的行為更加靈活和智能。
所以servlet就是這樣一個Java 插件,內置Java web-server
並允許它在某些頁面請求時執行 Java 代碼。這段由從 Servlet 類繼承的類表示的 Java 代碼已經實現了其開發人員的預期。
正如您所知,最流行的 Java Web 服務器是Tomcat。順便說一句,為了紀念卡通“湯姆和傑瑞”中的貓湯姆而命名。
Tomcat 如何與 servlet 交互?事實上,這個過程是標準化的,稱為servlet 生命週期。其中,servlet是一個可加載對象,web服務器是一個servlet容器。
如果 servlet 尚未加載,則:
- servlet 類由容器加載。
- 容器創建 servlet 類(對象)的實例。
- 容器調用
init()
servlet 對像上的方法。該方法僅被調用一次。
標準工作週期 -服務客戶請求:
- 每個請求都在單獨的線程中處理。
- 容器調用
service()
servlet 上的一個方法並在那里傳遞 ServletRequest 和 ServletResponse 對象。 - 要終止 servlet,需要
destroy()
在 servlet 對像上調用一個方法。它只被調用一次。
servlet 終止的原因有很多:
- 程序員重新啟動 web 服務器,有必要優雅地關閉所有 servlet。
- 程序員加載新版本的 servlet,必須正確卸載舊版本。
- 等等。
請記住最主要的事情:Web 服務器及其 servlet 應該可以無故障地工作並重新啟動數月,每分鐘處理數千個請求。因此,加載、工作和卸載 servlet 的代碼應該始終編寫得非常高質量。
1.2 HttpServlet類
Servlet 類的存在是為了標準化 servlet 和容器的工作方式。程序員不直接使用此類。好吧,他們很少工作。最常用的類HttpServlet
繼承自Servlet。
這個類有幾個對我們有用的方法。你會經常使用它們:
方法 | 描述 | |
---|---|---|
1個 | init() |
加載 servlet 時調用一次 |
2個 | destroy() |
卸載 servlet 時調用一次 |
3個 | service(HttpRequest, HttpResponse) |
為 servlet 的每個新請求調用 |
4個 | doGet(HttpRequest, HttpResponse) |
為 servlet 的每個新 GET 請求調用 |
5個 | doPost(HttpRequest, HttpResponse) |
調用 servlet 的每個新 POST 請求 |
6個 | doHead(HttpRequest, HttpResponse) |
為 servlet 的每個新 HEAD 請求調用 |
7 | doDelete(HttpRequest, HttpResponse) |
為 servlet 的每個新 DELETE 請求調用 |
8個 | doPut(HttpRequest, HttpResponse) |
為 servlet 的每個新 PUT 請求調用 |
init()
和方法destroy()
繼承自 Servlet 類。因此,如果您決定在您的 servlet 中覆蓋它們,您還需要從基類中調用它們的實現。該命令用於此super.method name()
。
服務小程序示例:
public class FirstHttpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Getting the parameter “secret” from request
String secret = request.getParameter("secret");
// Put parameter “secret” into Http-session
HttpSession session = request.getSession(true);
session.setAttribute("secret", secret);
// Print HTML as response for browser
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Header</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet example "+ secret +"</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
}
1.3 service(HttpServletRequest, HttpServletResponse)方法
如果從 servlet 的角度來看客戶端請求的處理,那麼事情是這樣的。
對於每個客戶端請求,容器(Web 服務器)創建HttpServletRequest
和對象HttpServletResponse
,然後調用service(HttpServletRequest request, HttpServletResponse response)
相應的 servlet 上的方法。將這些對像傳遞給它,以便該方法可以從中獲取必要的數據request
並將工作結果放入response
.
該方法service()
具有默認實現。如果沒有重新定義,那麼它將被執行。他就是這麼做的。
該方法service()
根據請求(GET、POST、...)確定HTTP方法類型,並調用請求對應的方法。
方法 | 描述 | |
---|---|---|
1個 | service(HttpRequest, HttpResponse) |
為 servlet 的每個新請求調用 |
2個 | doGet(HttpRequest, HttpResponse) |
為 servlet 的每個新 GET 請求調用 |
3個 | doPost(HttpRequest, HttpResponse) |
調用 servlet 的每個新 POST 請求 |
4個 | doHead(HttpRequest, HttpResponse) |
為 servlet 的每個新 HEAD 請求調用 |
5個 | doDelete(HttpRequest, HttpResponse) |
為 servlet 的每個新 DELETE 請求調用 |
6個 | doPut(HttpRequest, HttpResponse) |
為 servlet 的每個新 PUT 請求調用 |
在您的班級中,您可以重新定義一個方法service()
,或者保留它,然後根據需要重新定義方法doGet()
, doPost()
, ...。
GO TO FULL VERSION