Servlet介紹(二)——Servlet中方法介紹
一.Servlet中常見方法介紹
Servlet是一個介面,我們先來看一看這個介面中有哪些方法。
還記得不記得Servlet的執行流程,WEB容器啟動時候會呼叫init()方法,宕機時候會呼叫destroy()方法,在有一個請求到來時候,會呼叫service()方法。
1.1init方法
在web伺服器載入這個servlet的時候,會立刻呼叫init方法, 我們可以看到init方法的引數是ServletConfig 。那這個ServletConfig是啥吶,從字面翻譯就是當前這個servlet的配置,沒錯,init會從web容器中得到這個初始化引數並且賦值給自己的servletconfig,是的,在servlet的實現類中有這個servletconfig屬性。
2.destroy方法
與init方法相反的是,在關閉web伺服器時候,容器會呼叫這個方法,如果你還有一些最後要做的那就在這做好了。
3.service方法
當有請求的時候,會呼叫service方法處理,可以看service的引數是ServletRequest和ServletResponse,分別包含請求資料和響應資料。
記住這個方法是有引數的。
這個方法會丟擲ServletException和IoException
二.HttpServlet中方法詳解
HTTPServlet可以說是Servlet最常用的一個實現類,用以處理常見的http協議,我再來掛一下HttpServlet中的方法
當然嘞,它有個屬性叫ServletConfig
2.1service方法(ServletRequest,ServletResponse)
這個方法就是實現的Servlet介面的service方法,也就是web容器會呼叫的那個service方法,來我們看看這個方法幹了啥
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
很簡單,它把ServletRequest和ServletRespouse物件分別封裝成了HttpServletRequest和HttpServletResponse,這樣就可以處理http請求了,然後它又幹了啥,呼叫了它的一個過載的service方法。
2.2Service方法(HttpServletRequest,HttpServletResponse)
這個類的方法是protected,啥意思,就是無關的類不能訪問到當前這個類,可以在這裡實現一些自己想要的功能,並且不能被本包以為的類隨意訪問,提高了安全性。
有的同學說,我就想在service方法中去實現一些功能,那我應該去重寫哪個service方法吶?
實現哪個service方法都能實現功能,但是我們建議實現protected的那個方法, 因此它封裝成了http請求和響應,更便於處理,並且對安全性加以提高。
如果不重寫的話,我們來看一看這個service方法它又幹了些啥?
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
它這又幹啥了,這就會到了http請求上了,http的請求方式有很多種,最常見的有get,post,delete,post等等方式,這個方法就是根據請求方式的不同,將請求派發到不同的方法中,當然我們最常見的還是get和post兩種方式
2.3post和get
這兩個方法是最常見的兩種請求方式,所以一般情況下我們只需要重寫這個兩個函式就行了,不用去修改service方法。
2.4init方法(帶引數)
這個init方法實現Servlet介面的方法, 那麼引數是什麼吶,前面講過是ServletConfig,這個類接受web容器傳過來的配置資訊,還記得每個Servlet的實現類裡面都有一個屬性叫做ServletConfig,我想你也猜到了這個方法的實現。
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
發沒發現,它也會呼叫一個過載的init()方法
2.5init方法(不帶引數)
假如現在沒有這個方法,你有一些操作要在初始的時候進行,那你就應該去重寫init(帶引數)的那個方法,但是總有人忘記了呼叫父類的init方法這不就出錯了嗎,我猜測Java設計人員為了避免,所以提供了一個空的init方法來供給呼叫。
所以如果非得有一些初始化行為,那就實現這個沒用引數的init方法吧。