1. 程式人生 > >第二十五章:Servlet上

第二十五章:Servlet上

作者:java_wxid

Servlet技術
a)什麼是Servlet
1、Servlet是一個介面(JavaEE規範)
2、Servlet是執行在伺服器(Tomcat或其他的伺服器)上的小程式。
3、Servlet程式用來接收使用者的請求,和給客戶端響應資料。(接收請求,回傳響應)

b)手動實現Servlet程式
1、編寫一個類去實現Servlet介面
2、實現介面中的service方法
3、到web.xml中去配置訪問地址

Servlet程式

public class HelloServlet implements Servlet {
	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		System.out.println("hello world!!");
	}
}

web.xml中的配置:

   <!-- 
    servlet配置一個Servlet程式,給Tomcat伺服器配置
    -->
    <servlet>
    	<!-- servlet-name給這個servlet啟一個名稱,一般值是類名 -->
    <servlet-name>HelloServlet</servlet-name>
    <!-- servlet-name是Servlet程式的全類名 -->
    	<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
    </servlet> 
    <!-- servlet-mapping用來配置servlet程式的訪問地址 -->
    <servlet-mapping>
    	<!-- servlet-name表示給誰配置訪問地址 -->
    <servlet-name>HelloServlet</servlet-name>
 <!-- 
url-pattern配置訪問地址
地址的格式:http://ip:port/工程名/資源名		
在伺服器上。/ 斜槓 == 表示地址:http://ip:port/工程名/		
/hello ====== 表示http://ip:port/工程名/hello		
也就是說,我們在瀏覽器位址列上輸入訪問地址:
http://ip:port/工程名/hello 就可以訪問這個HelloServlet程式。
如果將專案部署到伺服器上預設訪問的是index.html,如果沒有index檔案則會報錯
-->	
    	<url-pattern>/hello</url-pattern>
    </servlet-mapping>

常見錯誤: servlet-name標籤配置不統一
在這裡插入圖片描述
常見錯誤二:servlet-class標籤全類名標籤錯誤
在這裡插入圖片描述
常見錯誤三:url-pattern沒有以斜槓打頭
在這裡插入圖片描述
c)解析url到servlet訪問細節
在這裡插入圖片描述
d)Servlet的生命週期(瞭解內容,面試)
1 先執行Servlet的構造器
2 執行init初始化方法
工程啟動之後,我們第一次訪問Servlet程式的時候執行 1 和 2兩個步驟
3 執行service 業務方法
每次呼叫都會執行service方法
4 執行destroy銷燬方法
當web工程停止的時候(重新部署)

e)模擬GET請求和POST請求的分發

public class HelloServlet implements Servlet {
	/**
	 * service方法是業務處理方法,每次請求都會呼叫
	 */
	@Override
	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
//		System.out.println("3 service業務處理方法");
		// 想辦法知道到底請求進來到底是GET。還是POST
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		//getMethod 可以獲取請求的方式,GET或POST
		String method = httpRequest.getMethod();
		// System.out.println( method );
		
		// 可能一般GET請求,和POST請求,需要做的工作不同
		if ("GET".equals(method)) {
			// 做GET請求的處理
			doGet();
		} else if ("POST".equals(method)) {
			// 做POST請求的處理
			doPost();
		}
	}
	
	public void doGet() {
		System.out.println("這是GET請求的功能");
	}
	
	public void doPost() {
		System.out.println("這是POST請求的功能");
	}
}

f)通過繼承HttpServlet實現Servlet程式
在開發的時候。為了讓開發程式碼更佳簡潔,方便,然後規範中提供了一個類叫HttpServlet類。
我們只需要繼承HttpServlet類,就可以實現Servlet程式了
1、編寫一個類去繼承HttpServlet
2、重寫doGet或doPost方法
3、去web.xml中去配置請求地址
原始碼:

public class HelloServlet2 extends HttpServlet {
	/**
	 * doGet方法,在請求進來 是GET請求的時候,呼叫
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("這是繼承HttpServlet 實現的 GET功能");
	}
	/**
	 * doPost方法,在請求進來 是POST請求的時候,呼叫
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("這是繼承HttpServlet 實現的 POST功能");
	}   
}

web.xml中的配置:

<servlet>
		<servlet-name>HelloServlet2</servlet-name>
		<servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>HelloServlet2</servlet-name>
		<!-- 在伺服器中 / 斜槓 ===== 表示http://ip:port/工程名/
			/hello2	===>>>> http://ip:port/工程名/hello2
		 -->
		<url-pattern>/hello2</url-pattern>
</servlet-mapping>

表單:

<form action="http://localhost:8080/day06/hello2" method="post">
    		<input type="submit" />
</form>

g)使用Eclipse建立Servlet程式
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
Servlet類的繼承體系
在這裡插入圖片描述
ServletConfig類
ServletConfig類從類名中就感覺它是Servlet程式的配置資訊。
這個ServletConfig只能由Tomcat伺服器負責建立。每次Tomcat建立Servlet程式的時候,就會建立ServletConfig物件,然後呼叫init初始化方法進行初始化操作。

a)ServletConfig類的三大作用
1、獲取在web.xml中配置的Servlet-name的別名
2、獲取在web.xml中配置的初始化引數init-param
3、獲取ServletContext物件

原始碼:

public class ConfigServlet extends HttpServlet {

	public void init(ServletConfig config) throws ServletException {
//		1、獲取在web.xml中配置的Servlet-name的別名
		System.out.println("servlet-name的值:" + config.getServletName());
//		2、獲取在web.xml中配置的初始化引數init-param
		System.out.println("初始化引數user的值:" + config.getInitParameter("user"));
		System.out.println("初始化引數url的值:" + config.getInitParameter("url"));
//		3、獲取ServletContext物件
		System.out.println( config.getServletContext() );
	}

}

web.xml中的配置:

<servlet>
    <servlet-name>ConfigServlet</servlet-name>
    <servlet-class>com.atguigu.servlet.ConfigServlet</servlet-class>
    <!-- 
    	init-param
    		配置配置初始化引數(由鍵值對組成)
     -->
    <init-param>
    	<!-- param-name是引數名 -->
    	<param-name>user</param-name>
    	<!-- param-value是引數值 -->
    	<param-value>root</param-value>
    </init-param>
    <!-- 
    	init-param
    		配置配置初始化引數(由鍵值對組成)
     -->
    <init-param>
    	<!-- param-name是引數名 -->
    	<param-name>url</param-name>
    	<!-- param-value是引數值 -->
    	<param-value>jdbc:mysql://localhost:3306/test</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>ConfigServlet</servlet-name>
    <url-pattern>/configServlet</url-pattern>
  </servlet-mapping>

注意點:
在這裡插入圖片描述
在這裡插入圖片描述
ServletContext類
a)什麼是ServletContext?
1、ServletContext是一個介面
2、ServletContext在一個web工程中只有一個物件例項(Tomcat伺服器負責建立)。
3、ServletContext是一個域物件。

什麼是域物件?
域物件是可以像map一樣存取資料的物件
setAttribute 儲存資料 put
getAttribute 獲取資料 get
removeAttribute 刪除資料 remove
域指的是這些存取的資料的操作範圍。ServletContext物件的資料操作範圍是整個web工程。
ServletContext物件在web工程啟動的時候建立。在web工程停止的時候銷燬。

b)ServletContext類的四個作用
1、獲取在web.xml中配置的上下文初始化引數 context-param
2、獲取工程路徑地址
3、獲取工程釋出之後在伺服器上的絕對路徑
4、像map一樣存取資料。

ServletContext作用的演示原始碼:

public class ContextServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		//獲取ServletContext物件
		ServletContext servletContext = getServletContext();		
//		1、獲取在web.xml中配置的上下文初始化引數	context-param
		String password = servletContext.getInitParameter("password");
		String url = servletContext.getInitParameter("url");
		System.out.println( "上下文引數password的值:" + password );
		System.out.println( "上下文引數url的值:" + url );
//		2、獲取工程路徑地址
		System.out.println("當前工程路徑是:" + servletContext.getContextPath());
//		3、獲取工程釋出之後在伺服器上的絕對路徑
		// / 斜槓表示到http://ip:port/工程名/	對映到程式碼的webContent目錄	
		// getRealPath 獲取在伺服器上的絕對路徑。
		System.out.println( "/ 根 的絕對路徑是:" + servletContext.getRealPath("/") );
		System.out.println("/css的絕對路徑是:" + servletContext.getRealPath("/css"));
		System.out.println("/imgs/11.jpg的絕對路徑是:" + servletContext.getRealPath("/imgs/11.jpg"));
		System.out.println( servletContext.getRealPath("/1.js") );
	}
}

web.xml配置檔案內容:

<context-param>
		<param-name>password</param-name>
		<param-value>root</param-value>
	</context-param>
	<context-param>
		<param-name>url</param-name>
		<param-value>jdbc:mysql://localhost:3306/contextServlet</param-value>
	</context-param>

像map一樣存取資料:

Context1的程式碼:

public class Context1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {	
		ServletContext context = getServletContext();
		System.out.println( context );
		// 獲取屬性值:
		System.out.println("在儲存屬性前 Context1 裡獲取abc的屬性值:" + context.getAttribute("abc"));		
		context.setAttribute("abc", "麥當勞是誰開的?麥當娜開的!因為他們都姓麥!");	
		System.out.println("在儲存屬性後 Context1 裡獲取abc的屬性值:" + context.getAttribute("abc"));
	}	
}

Context2的程式碼:

public class Context2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {		
		ServletContext context = getServletContext();
		System.out.println( context );
		// 獲取屬性值:
		System.out.println("Context2 裡獲取abc的屬性值:" + context.getAttribute("abc"));
	}
}

點選:Http協議