Tomcat程式碼實現
最近開課學到了Tomcat,對這個挺感興趣,就跟著網上的教程自己實現了一遍。
眾所周知,Tomcat是一個滿足Servlet規範的容器,在Java Web的專案中大量使用;一般來說,我們需要將Web應用打包成War檔案部署到Tomcat伺服器中,通過制定對映關係來制定路徑,指明被哪個方法處理。Tomcat對於實際的請求會做出以下的操作:
- 提供Socket服務,不過是支援HTTP的Socket
- 進行請求的下發
- 將請求與響應封裝成response和request
下面上程式碼:
一.封裝請求物件
import java.io.IOException;
import java.io.InputStream;
//封裝請求物件,通過輸入流,對 HTTP 協議進行解析,拿到 HTTP 請求頭的方法以及 URl
public class MyRequest {
private String url;
private String method;
public MyRequest(InputStream inputStream) throws IOException {
String httpRequest = " ";
byte[] httpRequestBytes = new byte[1024];
int length;
if ((length = inputStream.read(httpRequestBytes)) > 0) {
httpRequest = new String(httpRequestBytes, 0, length);
}
String httpHead = httpRequest.split("\n")[0];
url = httpHead.split("\\s")[1];
method = httpHead.split("\\s")[0];
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
}
//通過Socket中的輸入輸出流,進行對網址的解析,分別將url和method進行分離。
二.封裝響應物件
import java.io.IOException;
import java.io.OutputStream;
//封裝響應物件,基於HTTP協議的格式進行輸出
public class MyResponse {
private OutputStream outputStream;
public MyResponse(OutputStream outputStream){
this.outputStream = outputStream;
}
public void write (String content) throws IOException{
StringBuffer httpResponse = new StringBuffer();
httpResponse.append("HTTP/1.1 200 OK\n")
.append("Content-Type: text/html\n")
.append("\r\n")
.append("<html><body>")
.append(content)
.append("<body><html>");
outputStream.write(httpResponse.toString().getBytes());
outputStream.close();
}
}
//基於HTTP協議格式進行寫入操作
三.Servlet請求處理基類
import java.io.IOException;
public class MyServlet {
public void doGet(MyRequest myRequest,MyResponse myResponse){
try{
myResponse.write(" get Hello World");
}catch (IOException e){
e.printStackTrace();
}
}
public void doPost(MyRequest myRequest,MyResponse myResponse){
try{
myResponse.write(" post Hello World");
}catch (IOException e){
e.printStackTrace();
}
}
public void service(MyRequest myRequest,MyResponse myResponse){
if(myRequest.getMethod().equalsIgnoreCase("post")){
doPost(myRequest,myResponse);
}else if(myRequest.getMethod().equalsIgnoreCase("get")){
doGet(myRequest,myResponse);
}
}
}
//Tomcat提供doPost(),doGet(),service()方法
四.Servletp配置
public class ServletMapping {
private String servletName;
private String url;
private String clazz;
public ServletMapping(String servletName,String url,String clazz){
this.servletName = servletName;
this.url = url;
this.clazz = clazz;
}
public String getServletName() {
return servletName;
}
public void setServletName(String servletName) {
this.servletName = servletName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
import java.util.ArrayList;
import java.util.List;
public class ServletMappingConfig {
public static List<ServletMapping> servletMappingList = new ArrayList<>();
static {
servletMappingList.add(new ServletMapping("Hello World","/world","MyServlet"));
}
}
//通過設定對映關係對方法進行map對映呼叫。
五.啟動類
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
//tomcat服務的啟動類
public class MyTomcat {
private int port ;
private Map<String,String> urlServletMap = new HashMap<>();
public static void main(String[] args) {
new MyTomcat(8080).start();
}
public MyTomcat(int port){
this.port = port;
}
public void start(){
//初始化 URL與對應處理的servlet的關係
initServletMapping();
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(port);
System.out.println("MyTomcat is start on " + port);
while(true){
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
MyRequest myRequest = new MyRequest(inputStream);
MyResponse myResponse = new MyResponse(outputStream);
dispatch(myRequest,myResponse);
socket.close();
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(serverSocket != null){
try{
serverSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
//初始化url 與對應servler的關係
private void initServletMapping(){
for(ServletMapping servletMapping : ServletMappingConfig.servletMappingList){
urlServletMap.put(servletMapping.getUrl(),servletMapping.getClazz());
}
}
//請求分發
private void dispatch(MyRequest myRequest,MyResponse myResponse){
String clazz = urlServletMap.get(myRequest.getUrl());
//利用反射例項化具體的servlet處理請求
try{
Class<MyServlet> myServletClass =(Class<MyServlet>) Class.forName(clazz);
MyServlet myServlet = myServletClass.newInstance();
myServlet.service(myRequest,myResponse);
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
}
}
//解析HTTP協議,封裝請求/響應物件,使用反射的例項化進行對映。
相關文章
- java程式碼實現檢視Tomcat記憶體使用情況JavaTomcat記憶體
- Tomcat原始碼分析2 之 Protocol實現分析Tomcat原始碼Protocol
- Promise 程式碼實現Promise
- Tomcat實現Web SocketTomcatWeb
- Tomcat如何實現WebSocketTomcatWeb
- 實現彩色二維碼程式碼實
- Locust 程式碼指令碼實現指令碼
- OutputStreamWriter介紹&程式碼實現和InputStreamReader介紹&程式碼實現
- 如何實現程式碼高亮
- HashTable實現程式碼分享
- AsyncTask實現程式碼原理
- Kafka - SQL 程式碼實現KafkaSQL
- Tomcat中的session實現TomcatSession
- Linklist程式碼實現以及程式碼解讀
- centos下實現程式開機自啟動(tomcat為例)CentOSTomcat
- 【Tomcat】Tomcat工作原理及簡單模擬實現Tomcat
- DES原理及程式碼實現
- AES和DES程式碼實現
- vysor原理與程式碼實現
- 機器學習程式碼實現 SVM (5)機器學習
- JavaScript 實現sprintf 功能程式碼JavaScript
- js 實現程式碼雨效果JS
- tomcat熱部署的實現原理Tomcat熱部署
- 如何在TOMCAT中實現SSO?Tomcat
- javaScript實現utf8解碼程式碼JavaScript
- 微信小程式元件化(下):程式碼實現微信小程式元件化
- 2、實現tomcat+mysql實現jps的連線TomcatMySql
- mybatis實現變數定義,實現sql業務程式碼MyBatis變數SQL
- 瀑布流程式碼實現及思路
- CNN介紹及程式碼實現CNN
- Mars Chen影片XML程式碼實現XML
- FFmpeg程式碼實現視訊剪下
- Python課程程式碼實現Python
- BiLSTM介紹及程式碼實現
- 微信開發者工具實現程式碼加固
- java 橋接模式實現程式碼Java橋接模式
- 「gRPC」 Gateway的實現程式碼RPCGateway
- OpenGL實現貪吃蛇程式碼