1. 程式人生 > >Servlet呼叫過程詳解

Servlet呼叫過程詳解

Servlet是java程式設計中的核心內容,對於初學者而言清晰的瞭解servlet的呼叫過程,明白從客戶端到伺服器的互動過程是至關重要的。下面通過一個簡單的登陸例項的程式碼與圖的結合詳述一下servlet是怎樣被呼叫的。在介紹這個過程之前我們先來簡單瞭解下java開發相關的相關資訊。servlet的呼叫過程是由客戶端,容器(以Tomcat為例),xml檔案,java類,html檔案幾者合作參與完成,我們所要說的servlet的呼叫過程其實也就是這幾者之間的關係,他們之間的順序作用關係如下:

1.客戶端通過傳送請求給Tomcat,Tomcat傳送客戶端的請求頁面給客戶端。

2.使用者對請求頁面進行相關操作後將頁面提交給Tomcat,Tomcat將其封裝成一個HttpRequest物件,然後對請求進行處理,。

3.Tomcat截獲請求,根據action屬性值查詢xml檔案中對應的servlet-name,再根據servlet-name查詢到對應的java類(如果是第一次,Tomcat則會將servlet編譯成java類檔案,所以如果servlet有很多的話第一次執行的時候程式會比較慢)。

4.Tomcat例項化查詢到的java類,注意該類只例項化一次。

5.呼叫java類物件的service()方法(如果不對service()方法進行重寫則根據提交的方式來決定執行doPost()方法還是doGet()方法)。

6.通過request物件取得客戶端傳過來的資料,對資料進行處理後通過response物件將處理結果寫回客戶端。

下面是我們的程式碼示例:

(1)客戶端程式碼

<!DOCTYPE html>
<html>
  <head>
    <title>Login.html</title>
	<script language="javascript" type="text/javascript">
	      function CheckEmpty (){

			var username = document.getElementById("username1").value;
			var password = document.getElementById("password1").value;
						
			if(username == ""){
				alert("使用者名稱不能為空");
				return;
			} else if(password == "")
			{
				alert("密碼不能為空");
				return;
			}
			formSub();
		}
		
		function formSub(){
			LoginForm.submit();
		}

	</script>
  </head>
  
  <body >
  	<form action="LoginServlet"
method="post" name="LoginForm"> 使用者名稱:<input tyep="text" id="username1" name="username"><p> 密 碼:<input type="password" id="password1" name="password"><br> <input type="button" value="登陸" onClick="return CheckEmpty()"> </form> </body> </html>

注意上面程式碼中的紅色部分,這就是我們進行servlet定位的url,配置檔案也就是通過這個url來從眾多的servlet中找到我們所需要的servlet的。這個url並沒有固定的書寫,只要與配置檔案中的url-pattern對應就沒有問題。

(2)配置檔案程式碼

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  
  <welcome-file-list>
    <welcome-file>Login.html</welcome-file>
  </welcome-file-list>
  
  <servlet>
    <servlet-name>MyLoginServlet</servlet-name>
    <servlet-class>LoginServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyLoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>	
</web-app>

配置檔案所起的作用更像是是一個排程站,他負責將不同的頁面與不同的servlet進行對接,以便於servlet可以對客戶端提交過來的資料進行處理。

(3)servlet程式碼

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class LoginServlet extends HttpServlet {

	//建構函式
	public LoginServlet() {
		super();
	}

	//解構函式
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}
	//重寫doGet方法
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
			
		actionFuc(request,response,"Get");
		
	}

	// 重寫doPost方法
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		actionFuc(request,response,"Post");
	}
	//重寫service方法
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException{
		
		actionFuc(request,response,"Service");
	}
	
	//重寫初始化方法
	public void init() throws ServletException {
		// Put your code here
	}
	/**
	 * 我們自己定義的測試函式,該函式用來測試不同的提交方法(get提交還是post提交),
	 * 以及驗證service方法被重寫後就不會再呼叫doGet和doPost方法
	 */
	private void actionFuc(HttpServletRequest request, HttpServletResponse response,String method)
				throws IOException{
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		System.out.println("username=" + username);
		System.out.println("password=" + password);
		
		response.setContentType("text/html");
		
		response.getWriter().println(method + "Login Success!");
		
	}
}

通過對service方法進行重寫進一步驗證了,當請求被提交給servlet的時候首先呼叫的是java類物件的service方法,如果該方法不被重寫則會根據頁面的提交方式呼叫doGet或doPost方法,但是當service被重寫後則會執行service方法體中的內容,不再呼叫doGet或doPost方法。