手動實現簡單的tomcat服務器

手動實現tomcat服務器的流程:

  

 分析具體的實現步驟:

1,瀏覽器和後端服務如何實現通訊,首先傳輸的數據要遵循http協議,經過tcp也就是咱們常說的套接字編程來實現,具體的底層數據傳輸確定就是咱們的輸入輸出流來實現了。html

2,咱們再來看後臺服務器的實現邏輯,首先咱們要定義兩個對象,一個request,一個response分別用來存放請求的參數以及返回的參數。java

3,建立一個ServerSocket,等待瀏覽器的鏈接和數據傳輸,當經過輸入流讀取到數據,放入到request對象。web

4,瀏覽器的請求類型通常分爲get和post兩種,因此咱們須要一個mpper映射類來根據瀏覽器的訪問路徑來分發具體處理的類或者方法。編程

5,處理以後獲取處理的結果,並放到response對象,經過輸出流返回給瀏覽器。後端

下面是具體的代碼實現:

1,reques類瀏覽器

package com.liuyi;

import java.io.InputStream;

public class MyRequest {

    //請求方法  GET/POST
    private String requestMethod;
    //請求地址
    private String requestUrl;

    public MyRequest(InputStream inputStream) throws Exception{
        //緩衝區域
        byte[] buffer = new byte[1024];
        //讀取數據的長度
        int len = 0;
        //定義請求的變量
        String str = null;

        if((len = inputStream.read(buffer))>0){
            str = new String(buffer,0,len);
        }
        // GET / HTTP/1.1
       String data =  str.split("\n")[0];
       String[] params =  data.split(" ");
        this.requestMethod = params[0];
        this.requestUrl = params[1];
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }
}

2,response類tomcat

package com.liuyi;

import java.io.OutputStream;

public class MyResponse {

    private OutputStream outputStream;

    public MyResponse(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    public void write(String str) throws  Exception{
        StringBuilder builder = new StringBuilder();
        builder.append("HTTP/1.1 200 OK\n")
                .append("Content-Type:text/html\n")
                .append("\r\n")
                .append("<html>")
                .append("<body>")
                .append("<h1>"+str+"</h1>")
                .append("</body>")
                .append("</html>");
        this.outputStream.write(builder.toString().getBytes());
        this.outputStream.flush();
        this.outputStream.close();
    }
}

3,Mapping類,定義請求路徑和請求處理類的關係服務器

package com.liuyi;

import java.util.HashMap;

public class MyMapping {

    public static HashMap<String,String> mapping = new HashMap<String,String>();

    static {
     //這裏請改爲本身servlet實現類的徹底限定名 mapping.put(
"/mytomcat","com.liuyi.MyServlet"); } public HashMap<String,String> getMapping(){ return mapping; } }

4,定義HpptServlet抽象類,實現get和post的分發(根據不一樣的請求方式調用不一樣的方法進行處理)app

package com.mashibing;

public abstract class MyHttpServlet {

    //定義常量
    public static final String METHOD_GET = "GET";
    public static final String METHOD_POST = "POST";

    public abstract void doGet(MyRequest request,MyResponse response) throws  Exception;
    public abstract void doPost(MyRequest request,MyResponse response) throws  Exception;


    /**
     * 根據請求方式來判斷調用哪一種處理方法
     * @param request
     * @param response
     */
    public void service(MyRequest request,MyResponse response) throws Exception{
        if(METHOD_GET.equals(request.getRequestMethod())){
            doGet(request,response);
        }else if(METHOD_POST.equals(request.getRequestMethod())){
            doPost(request,response);
        }
    }
}

5,定義本身的servletsocket

package com.liuyi;

public class MyServlet extends MyHttpServlet{
    @Override
    public void doGet(MyRequest request, MyResponse response) throws Exception {
        response.write("mytomcat get");
    }

    @Override
    public void doPost(MyRequest request, MyResponse response) throws Exception {
        response.write("post tomcat");
    }
}

6,定義服務端的接受程序,接受socket請求

package com.liuyi;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
    /**
     * 定義服務端的接受程序,接受socket請求
     * @param port
     */
    public static void startServer(int port) throws Exception{

        //定義服務端套接字
        ServerSocket serverSocket = new ServerSocket(port);
        //定義客戶端套接字
        Socket socket = null;

        while (true){
            socket = serverSocket.accept();

            //獲取輸入流和輸出流
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();

            //定義請求對象
            MyRequest request = new MyRequest(inputStream);
            //定義響應對象
            MyResponse response = new MyResponse(outputStream);

            String clazz = new MyMapping().getMapping().get(request.getRequestUrl());
            if(clazz!=null){
                Class<MyServlet> myServletClass = (Class<MyServlet>)Class.forName(clazz);
                //根據myServletClass建立對象
                MyServlet myServlet = myServletClass.newInstance();
                myServlet.service(request,response);
            }

        }
    }

    //運行啓動
    public static void main(String[] args) {
        try {
            startServer(10086);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

總結:

  本案例只是實現了簡單的tomcat和servlet,僅僅只是爲了讓咱們學習servlet和tomcat沒有那麼多的疑惑,學起來會更容易。實際工做中固然也不會這樣去寫,

可是若是你認值把這個代碼敲一遍,並理解爲何這樣寫,那麼對你學習java web確定會有很大的幫助。

相關文章
相關標籤/搜索