JavaWeb基礎總結之Servlet(一)
Http:常見響應碼:
- 200:請求成功
- 302/307:請求的資源變更
- 304:請求資源未變更
- 404:請求資源不存在
- 500:伺服器程式存在錯誤
Servlet:是SUN制定的一套開發動態Web頁面的規範。它是JavaEE技術中的一種。Tomcat伺服器實現了Servlet規範。
servlet的三種實現方式:
- 實現javax.servlet.Servlet
- 繼承javax.servlet.GenericServlet類
- 繼承javax.servlet.http.HttpServlet類
(1)實現javax.servlet.Servlet介面:
import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class ServletDemo implements Servlet { @Override public void init(ServletConfig config) throws ServletException { System.out.println("init..."); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("service..."); } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println("destory..."); } }
Servlet介面中有五個方法,其中生命週期的方法有三個:init(),service(),destory()。init()方法在第一次請求某一個servlet初始化。service()方法在每次請求該servlet時都會呼叫,destory()方法在物件銷燬時呼叫。這裡需要注意的是。Servlet類是由程式設計師寫的,但是物件是由伺服器建立的,並且由伺服器呼叫相應的方法。
(2)繼承javax.servlet.GenericServlet類:
import java.io.IOException; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class ServletDemo3 extends GenericServlet { private static final long serialVersionUID = 1L; @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("GenericServlet service..."); } }
GenericServlet類是一個抽象類,抽象方法為service方法,實際上我們繼承了該類之後只要重寫service方法即可以實現Servlet。
(3)繼承javax.servlet.http.HttpServlet類:(最常見的)。HttpServlet類是GenericServlet類的子類,提供瞭如下的請求方式:
供客戶端請求,實際上提供那麼多種請求方法名(GET,POST,DELETE等)的初衷是判斷請求的邏輯可以通過不同的方法名進行辨析,也就是當前的restful風格,但是大多數的開發者實際上還是使用POST,GET請求方式就取代了上述的這些方式,所以實際的開發中,如果你沒有采用restful風格的開發,你只需要重寫doGet和doPost方法即可。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo4 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
預設情況下,伺服器會在某一個Servlet第一次收到請求時建立他,當然也可以在web.xml對servlet進行配置,使伺服器啟動時就可以建立他(注意這裡僅僅指的是servlet物件被建立,而不是被請求,所以要看到明顯的效果就是在init()方法中做一些輸出即可,下面在servletDemo中加上啟動伺服器就建立的語句):
這樣在伺服器啟動的時候,該物件就會被建立,建立的時候也就執行了init()方法:
這裡切記不要在繼承GenericServlet類的時候加上該語句檢視是否建立,因為該類的init()方法中是預設的空操作:這個要注意。除非你重寫init()方法。
重寫init方法:
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServletDemo3 extends GenericServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throws ServletException {
System.out.println("重寫GenericServlet類的init()方法...");
}
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
System.out.println("GenericServlet service...");
}
}
伺服器啟動時,控制檯結果:
Servlet中的初始化引數獲取:當servlet配置了初始化引數之後,web容器(如tomcat)在建立servlet例項物件時,會自動將這些初始化引數封裝到ServletConfig物件中,並在呼叫servlet的init方法時,將ServletConfig物件傳遞給Servlet。進而,程式設計師通過Servlet物件得到當前servlet的初始化引數資訊。
私有的初始化引數獲取:
在init()方法中只需要通過下面語句獲得即可:
System.out.println(this.getInitParameter("name"));
或者是:
System.out.println(this.getServletConfig().getInitParameter("name"));
可以看出,得到servlet私有的初始化引數是通過得到ServletConfig物件,然後再從該物件中取到對應的值的。
公共的初始化引數獲取:
在init()方法中只需要通過以下語句即可得到公共初始化引數:
System.out.println(this.getServletContext().getInitParameter("hello"));
可以看出,得到公共的初始化引數是通過得到ServletContext物件,然後再從中獲取對應的值的。
JavaWeb的四大域物件:
- pageContext域:作用範圍是整個JSP頁面,是四大作用域中最小的一個;生命週期是當對JSP的請求時開始,當響應結束時銷燬。
- ServletRequest域:作用範圍是整個請求鏈(請求轉發也存在);生命週期是在service方法呼叫前由伺服器建立,傳入service方法。整個請求結束,request生命結束
- HttpSession域:作用範圍是一次會話。生命週期是在第一次呼叫request.getSession()方法時,伺服器會檢查是否已經有對應的session,如果沒有就在記憶體中建立一個session並返回。當一段時間內session沒有被使用(預設為30分鐘),則伺服器會銷燬該session。如果伺服器非正常關閉(強行關閉),沒有到期的session也會跟著銷燬。如果呼叫session提供的invalidate() ,可以立即銷燬session。注意:伺服器正常關閉,再啟動,Session物件會進行鈍化和活化操作。同時如果伺服器鈍化的時間在session 預設銷燬時間之內,則活化後session還是存在的。否則Session不存在。 如果JavaBean 資料在session鈍化時,沒有實現Serializable 則當Session活化時,會消失。
- ServletContext:作用範圍是整個Web應用。當Web應用被載入進容器時建立代表整個web應用的ServletContext物件,當伺服器關閉或Web應用被移除時,ServletContext物件跟著銷燬。
- 總結如下:
PageContext(jsp頁面),ServletRequest(一次請求),HttpSession(一次會話),ServletContext(整個web應用)。
所有域物件都有存取資料的功能,因為域物件內部有個map儲存結構儲存資料,下面以ServletContext物件具有的方法為例作簡單總結:
- void setAttribute(String name,Object value)將資料按鍵值對放入map,但是名字相同會被覆蓋。
- Object getAttribute(String name)取資料,需要注意的是這個函式返回的是物件,所以在獲取其對應的String時,要做相應的資料強制轉換為String。
- void removeAttribute(String name):用來移除ServletContext中的域屬性,如果引數name指定的域屬性不存在,那麼該方法什麼也不做。
- Enumeration getAttributeNames():獲取所有域屬性的名稱。
注:以上文章僅是個人學習過程總結,若有不當之處,望不吝賜教。