1. 程式人生 > >JavaWeb基礎總結之Servlet(一)

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():獲取所有域屬性的名稱。

注:以上文章僅是個人學習過程總結,若有不當之處,望不吝賜教。