前言
好記性不如爛筆頭悼枢,而且學(xué)習(xí)了卻沒有做筆記總結(jié)脉课,就不算學(xué)習(xí)啤月。因此寫了一篇文章總結(jié)一下對 Servlet的理解。
什么是 Servlet
- 一個負(fù)責(zé)接收和響應(yīng)客戶端請求的 Java 程序
A servlet is a small Java program that runs within a Web server.
Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
打開 Servlet.java
的源碼嫉髓,可以看到這一段注釋。它說:Servlet 就是一個運(yùn)行在 Web 服務(wù)器中的 Java 程序邑闲。servlet 可以接收和響應(yīng) Web 客戶端的網(wǎng)絡(luò)請求算行。
- Java Web 的三大組件(Servlet、Filter苫耸、Listener)之一
Servlet 的架構(gòu)
Servlet 的繼承關(guān)系
public interface Servlet
public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable
public abstract class HttpServlet extends GenericServlet
所有的 Servlet 都需要實現(xiàn) Servlet
接口州邢。Servlet
接口定義了 Servlet 的生命周期方法
init(ServletConfig config)
service(ServletRequest req, ServletResponse res)
destroy()
Servlet 初始化時會調(diào)用 init(ServletConfig config)
方法;在 service(ServletRequest req, ServletResponse res)
方法中對客戶端的請求進(jìn)行處理褪子;如果 Servlet 不用了量淌,會調(diào)用 destroy()
方法銷毀,然后等待垃圾回收嫌褪。
GenericServlet
為了方便編寫 Servlet呀枢,創(chuàng)造了 GenericServlet
抽象類狐血,只需要實現(xiàn) public abstract void service(ServletRequest req, ServletResponse res)
方法即可假丧。
HttpServlet
HttpServlet
是和 HTTP 協(xié)議有關(guān)的 Servlet晶衷,只需要重寫幾個 HTTP 相關(guān)的方法
- doGet(HttpServletRequest req, HttpServletResponse resp)
- doPost(HttpServletRequest req, HttpServletResponse resp)
- doPut(HttpServletRequest req, HttpServletResponse resp)
- doDelete(HttpServletRequest req, HttpServletResponse resp)
和 Servlet 生命周期的相關(guān)方法
- init()
- destroy()
當(dāng)請求到來時但惶,會調(diào)用 service(ServletRequest req, ServletResponse res)
阔加,在 HttpServlet 中方法的實現(xiàn)如下
public void service(ServletRequest req, ServletResponse res) {
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
這個方法只做了兩件事
- ServletRequest 強(qiáng)轉(zhuǎn)為 HttpServletRequest请毛;ServletResponse 強(qiáng)轉(zhuǎn)為 HttpServletResponse
- 調(diào)用
service(HttpServletRequest req, HttpServletResponse resp)
方法伟葫,在這個方法中會對 HTTP 的請求進(jìn)行判斷官卡,然后調(diào)用對應(yīng)的doXX()
方法
protected void service(HttpServletRequest req, HttpServletResponse resp) {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
// ...
doGet(req, resp);
} else if (method.equals(METHOD_HEAD)) {
// ...
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
// ...
}
}
Servlet與線程安全
- 不要在Servlet中創(chuàng)建成員刻坊,創(chuàng)建局部變量即可
- 可以創(chuàng)建無狀態(tài)成員
- 可以創(chuàng)建有狀態(tài)的成員枷恕,但狀態(tài)必須為只讀的