Tomcat的運(yùn)行機(jī)制

2021-11-12 09:14 更新

Tomcat 的運(yùn)行機(jī)制

一、Tomcat運(yùn)行原理分析

1.Tomcat 是運(yùn)行在 JVM 中的一個(gè)進(jìn)程。它定義為【中間件】,顧名思義,是一個(gè)在Java項(xiàng)目與JVM之間的中間容器。

2.Web 項(xiàng)目的本質(zhì),是一大堆的資源文件和方法。Web 項(xiàng)目沒有入口方法 ( main 方法),,意味著 Web 項(xiàng)目中的方法不會自動運(yùn)行起來。

3.Web 項(xiàng)目部署進(jìn) Tomcat 的 webapp 中的目的是很明確的,那就是希望 Tomcat 去調(diào)用寫好的方法去為客戶端返回需要的資源和數(shù)據(jù)。

4. Tomcat 可以運(yùn)行起來,并調(diào)用寫好的方法。那么,Tomcat 一定有一個(gè) main 方法。

5. 對于Tomcat 而言,它并不知道我們會有什么樣的方法,這些都只是在項(xiàng)目被部署進(jìn) webapp下后才確定的,由此分析,必然用到了 Java 的反射來實(shí)現(xiàn)類的動態(tài)加載、實(shí)例化、獲取方法、調(diào)用方法。但是我們部署到 Tomcat 的中的Web項(xiàng)目必須是按照規(guī)定好的接口來進(jìn)行編寫,以便進(jìn)行調(diào)用

6.Tomcat 如何確定調(diào)用什么方法呢。這取決于客戶端的請求,http://127.0.0.1:8080/JayKing.Tomcat.Study/index.java?show 這樣的一個(gè)請求,通過 http 協(xié)議,在瀏覽器發(fā)往本機(jī)的 8080 端口,攜帶的參數(shù) show 方法,包含此方法的路徑為 JayKing.Tomcat.Study,文件名為:index.java。

二、模擬Tomcat運(yùn)行

1.客戶端類

package JayKing.Tomcat.Study;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
	private static int port = 5228;
	private static String host = "127.0.0.1";
    //http://127.0.0.1:8080/JayKing.Tomcat.Study/index.java?show
	public static void main(String[] args) {
		try {
			Socket con=new Socket(host,port);
			System.out.println("請輸入U(xiǎn)RL地址:");
			Scanner scanner=new Scanner(System.in);
			String info=scanner.nextLine().trim();
			Writer writer = new OutputStreamWriter(con.getOutputStream());
			writer.write(info);
			writer.flush();
			writer.close();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

2.服務(wù)器類

package JayKing.Tomcat.Study;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
 
public class TomcatTest {
	private static int post = 5228;
 
	private static UrlUtil urlutil = new UrlUtil();
 
	public static void main(String[] args) {
		System.out.println(" My Tomcat is Running");
		try {
			ServerSocket server = new ServerSocket(post);
			while (true) {
				Socket socket = server.accept();// 服務(wù)器每接受一次請求,就創(chuàng)建一個(gè)socket對象
				InputStream in = socket.getInputStream();
				BufferedReader br = new BufferedReader(
						new InputStreamReader(in));
				String info = null;
				String infoline = br.readLine();
				while (infoline != null) {
					info =info+infoline;
					infoline = br.readLine();
				}
				UrlBean url = urlutil.readString(info);
				if (url != null) {
					String path=url.getPath();
					String className = url.getFileName();
					String methodName = url.getParameter().trim();
					ClassLoader classloader=ClassLoader.getSystemClassLoader();	
					try {
						classloader.loadClass(path+"."+className);
						Class<?> getclass=Class.forName(path+"."+className);
						Method method=getclass.getMethod(methodName, null);
						method.invoke(getclass.newInstance(), null);
						
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (SecurityException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InstantiationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}		
				} else {
 
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

3.工具類

package JayKing.Tomcat.Study;
 
//格式:協(xié)議://主機(jī)號:端口號/目錄路徑/文件名
//例如: http://127.0.0.1:8080/Test/Manage/index.jsp
public class UrlUtil {
	public UrlBean readString(String info) {
		UrlBean url = null;
		int tag1 = info.indexOf(":");
		int tag2 = info.lastIndexOf(":");
		int tag3 = info.indexOf("/", tag2);
		int tag4 = info.lastIndexOf("/");
		int tag5 = info.indexOf("?");
		int tag6=info.lastIndexOf(".");
		String Protocol = info.substring(0, tag1);
		String Host = info.substring(tag1 + 3, tag2);
		String Port = info.substring(tag2 + 1, tag3);
		String Path = info.substring(tag3 + 1, tag4);
		String FileName = info.substring(tag4 + 1, tag6);
		String Parameter = info.substring(tag5 + 1, info.trim().length());
		if (Host != null && Path != null && FileName != null) {
			if (Protocol == null) {
				Protocol = "http";
			}
			if (Port == null) {
				Port = "8080";
			}
			url = new UrlBean(Protocol, Host, Port, Path, FileName, Parameter);
			return url;
		}
 
		return url;
 
	}
}

4.Model類 

package JayKing.Tomcat.Study;
 
//格式:協(xié)議://主機(jī)號:端口號/目錄路徑/文件名
//例如: http://127.0.0.1:8080/Test/Manage/index.jsp?a=1&b=2
public class UrlBean {
	private String Protocol;
	private String Host;
	private String Port;
	private String Path;
	private String FileName;
	private String Parameter;
 
	public UrlBean(String protocol, String host, String port, String path,
			String fileName, String parameter) {
		super();
		Protocol = protocol;
		Host = host;
		Port = port;
		Path = path;
		FileName = fileName;
		Parameter = parameter;
	}
 
	public UrlBean() {
	}
 
	public String getProtocol() {
		return Protocol;
	}
 
	public void setProtocol(String protocol) {
		Protocol = protocol;
	}
 
	public String getHost() {
		return Host;
	}
 
	public void setHost(String host) {
		Host = host;
	}
 
	public String getPort() {
		return Port;
	}
 
	public void setPort(String port) {
		Port = port;
	}
 
	public String getPath() {
		return Path;
	}
 
	public void setPath(String path) {
		Path = path;
	}
 
	public String getFileName() {
		return FileName;
	}
 
	public void setFileName(String fileName) {
		FileName = fileName;
	}
 
	public String getParameter() {
		return Parameter;
	}
 
	public void setParameter(String parameter) {
		Parameter = parameter;
	}
}

5.測試方法類 

package JayKing.Tomcat.Study;
public class index {
	public void show() {
		System.out.println("方法已經(jīng)被執(zhí)行!");
	}
}

6.運(yùn)行結(jié)果


 


三、Tomcat 原理總結(jié)

1. Tomcat 需要 main 方法啟動。

2. Tomcat 需要監(jiān)聽本機(jī)上的某個(gè)端口。

3. Tomcat 需要抓取此端口上來自客戶端的鏈接并獲得請求調(diào)用的方法與參數(shù)。

4. Tomcat 需要根據(jù)請求調(diào)用的方法,動態(tài)地加載方法所在的類,完成類的實(shí)例化并通過該實(shí)例獲得需要的方法最終將請求傳入方法執(zhí)行。

5. 將結(jié)果返回給客戶端( jsp/html 頁面、 json/xml 字符串)。



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號