国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

如何仿寫(xiě)簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解

這篇具有很好參考價(jià)值的文章主要介紹了如何仿寫(xiě)簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

仿寫(xiě)之前,我們要搞清楚都要用到哪些技術(shù)

  1. 自定義注解,比如Tomcat使用的是@Servlet,我們可以定義一個(gè)自己的@MyServlet
  2. 構(gòu)造請(qǐng)求體和返回體,比如tomcat使用HttpRequest,我們可以自己定義myHttpRequest
  3. java去遍歷一個(gè)指定目錄,然后獲取到.java文件,再獲取到帶有@MyServlet注解的類
  4. 然后將這個(gè)注解里的path和這個(gè)類本身映射成map
  5. 通過(guò)反射去調(diào)用該類的方法(doGet、doPost)
  6. 還需要用到socket來(lái)監(jiān)聽(tīng)消息,并且對(duì)監(jiān)聽(tīng)到的消息進(jìn)行處理

第一步:自定義注解

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyServlet {
    String path() default "";
}

第二步:定義HttpRequest以及HttpResponse、

public class MyHttpRequest {
    //定義一個(gè)map,用來(lái)存放請(qǐng)求體中的參數(shù),key是參數(shù)名稱,value是參數(shù)值
    public Map<String,String> map = new HashMap<>();

    public String getParameter(String key){
        return map.get(key);
    }
}
public class MyHttpResponse {
    public OutputStream outputStream;

    public static final String responsebody = "HTTP/1.1 200+\r\n" + "Content-Type:text/html+\r\n"
            + "\r\n";

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

第三步:遍歷整個(gè)目錄,把Java文件放入list中

    private static void func(File file){
        File[] files = file.listFiles();
        String s;
        for (File file1 : files) {
            if (file1.isDirectory()){
                func(file1);
            }
            if (file1.isFile()){
                //取src之后的名字
                s = file1.toString().split("src")[1];
                //去掉src后邊的第一個(gè)\,得到全類名
                s = s.substring(1);
                //判斷是不是以.java結(jié)尾的文件
                if (s.length() >=5 && s.substring(s.length() - 5).equals(".java")){
                    //把全類名中的\替換成.
                    s = s.replace('\\','.');
                    //去掉后綴名.java
                    s = s.substring(0,s.length()-5);
                    //把類名加入到list中
                    javaclasses.add(s);
                }

            }
        }
    }

第四步:找出帶有Servlet注解的Java文件,并把注解中的path,類對(duì)象放入到map中

    public static void getServlet() throws ClassNotFoundException {
        for (int i = 0; i < javaclasses.size(); i++) {
            String path = javaclasses.get(i);
            Class<?> cl = Class.forName(path);
            if (cl.isAnnotationPresent(MyServlet.class)){
                servletMap.put(cl.getAnnotation(MyServlet.class).path(),cl);
            }
        }
    }

第五步:創(chuàng)建socket連接

InetAddress localHost = InetAddress.getLocalHost();
        System.out.println("localhost" + localHost);
        ServerSocket serverSocket = new ServerSocket(8080, 10, localHost);
        System.out.println("等待建立連接");
        Socket server = serverSocket.accept();
        System.out.println("連接已建立");

第六步:定義線程接收?qǐng)?bào)文

        HttpAcceptThread httpAcceptThread = new HttpAcceptThread(server);
        Thread accept = new Thread(httpAcceptThread);
        accept.start();
        accept.join();

HttpAcceptThread類內(nèi)容如下:

class HttpAcceptThread implements Runnable{
    private Socket socket;
    ArrayList<String> strings = new ArrayList<>();

    public HttpAcceptThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        System.out.println("開(kāi)始接收http");
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String s;
            while ((s = reader.readLine()).length() != 0){
                try {
                    strings.add(s);
                    System.out.println(s);
                } catch (Exception e){
                    System.out.println("接收Http進(jìn)程結(jié)束");
                    break;
                }
            }
            System.out.println("接收http進(jìn)程結(jié)束");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

第七步:處理httprequest,也就是通過(guò)反射去調(diào)用doGet和doPost方法

這一步有些復(fù)雜,尤其是對(duì)url切割時(shí),但我給每一步都加了注釋,方便理解

? ? ? ? ? ? ?GET /address1?a=111&b=222

   private static void requestHttp(Socket socket,String http) throws IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //GET /address1?a=111&b=222(拿獲取到的這個(gè)url舉例)
        //先通過(guò)空格判斷是GET還是POST
        String requestStyle = http.split(" ")[0];
        if (requestStyle.equals("GET")){
            //如果是GET,取空格后面部分,即/address1?a=111&b=222
            String httpPathAndParameter = http.split(" ")[1];
            //定義httpPath
            String httpPath;
            //創(chuàng)建httpRequest對(duì)象
            MyHttpRequest myHttpRequest = new MyHttpRequest();
            //通過(guò)索引位置判斷url里邊有沒(méi)有帶?
            if (httpPathAndParameter.indexOf("?") != -1){
                //如果有,由于有個(gè)/,因此我們要先拿到address1?a=111&b=222這部分
                httpPath = httpPathAndParameter.substring(1);
                //獲取問(wèn)號(hào)前面部分,即address1,\\作為轉(zhuǎn)義字符使用
                httpPath = httpPath.split("\\?")[0];
                System.out.println(httpPath);

                //獲取問(wèn)號(hào)后面部分的所有參數(shù)
                String parameterString = httpPathAndParameter.split("\\?")[1];
                //使用&分開(kāi)
                String[] parameters = parameterString.split("&");
                for (int i = 0; i < parameters.length; i++) {
                    //把參數(shù)及其值仿佛request的map中
                    myHttpRequest.map.put(parameters[i].split("=")[0],parameters[i].split("=")[1]);
                }
            } else {
                //如果不存在?,也就說(shuō)明不存在參數(shù),我們只需要獲取httpPath
                httpPath = httpPathAndParameter.substring(1);
                System.out.println(httpPath);
            }

            //創(chuàng)建HttpResponse對(duì)象
            OutputStream outputStream = socket.getOutputStream();
            MyHttpResponse myHttpResponse = new MyHttpResponse(outputStream);

            //反射調(diào)用doGet
            Class servletClass = servletMap.get(httpPath);
            Method doGet = servletClass.getMethod("doGet", MyHttpRequest.class, MyHttpResponse.class);
            doGet.invoke(servletClass.newInstance(),myHttpRequest,myHttpResponse);
        } else {
            //如果不是Get請(qǐng)求,也按照同樣的步驟,先取出/address1
            String httpPath = http.split(" ")[1];
            //去掉/,只留下address1
            httpPath = httpPath.substring(1);
            System.out.println(httpPath);

            MyHttpRequest myHttpRequest = new MyHttpRequest();
            OutputStream outputStream = socket.getOutputStream();
            MyHttpResponse myHttpResponse = new MyHttpResponse(outputStream);
            //根據(jù)httpPath取出類信息
            Class servletClass = servletMap.get(httpPath);
            //獲取doPost方法
            Method doPost = servletClass.getMethod("doPost", MyHttpRequest.class, MyHttpResponse.class);
            //調(diào)用doPost方法
            doPost.invoke(servletClass.newInstance(),myHttpRequest,myHttpResponse);
        }
    }

最后一步:把上面這些方法整合起來(lái),在主方法中調(diào)用,同時(shí)定義好全局變量

public class MyTomcat {
    //用于存放Java類的全類名
    public static ArrayList<String> javaclasses = new ArrayList<>();

    //用于存放Servlet的類對(duì)象,其中key是Servlet的url,value是servlet的類對(duì)象
    public static HashMap<String,Class> servletMap = new HashMap<>();

    public static void main(String[] args) throws ClassNotFoundException, IOException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        String inputPath = "D:\\JavaProject\\practice\\src\\tomcat";
        File file = new File(inputPath);
        //獲取.java后綴文件,并獲取全類名
        func(file);
        System.out.println(javaclasses);
        //獲取帶有servlet注解的類對(duì)象,并放到map中。
        getServlet();
        System.out.println(servletMap);

        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println("localhost" + localHost);
        ServerSocket serverSocket = new ServerSocket(8080, 10, localHost);

        System.out.println("等待建立連接");
        Socket server = serverSocket.accept();
        System.out.println("連接已建立");

        //定義線程接收http報(bào)文
        HttpAcceptThread httpAcceptThread = new HttpAcceptThread(server);
        Thread accept = new Thread(httpAcceptThread);
        accept.start();
        accept.join();

        //處理請(qǐng)求
        requestHttp(server,httpAcceptThread.strings.get(0));
    }

然后就可以進(jìn)行測(cè)試了,在測(cè)試類上方加上我們已經(jīng)定義好的@MyServlet注解

@MyServlet(path = "address1")
public class Servlet1 {

    public void doGet(MyHttpRequest request, MyHttpResponse response) throws IOException {
        System.out.println("address1 GET響應(yīng):");
        System.out.println("a=" + request.getParameter("a"));
        System.out.println("\n響應(yīng)的http如下:");
        String resp = MyHttpResponse.responsebody + "<!DOCTYPE html>\n" +
                "<html>\n" +
                "<head>\n" +
                "    <meta charset=\"utf-8\" />\n" +
                "</head>\n" +
                "<body>\n" +
                " \n" +
                "    <form name=\"my_form\" method=\"POST\">\n" +
                "        <input type=\"button\" value=\"按下\" onclick=\"alert('你按下了按鈕')\">\n" +
                "    </form>\n" +
                " \n" +
                "</body>\n" +
                "</html>";
        System.out.println(resp);
        response.outputStream.write(resp.getBytes());
        response.outputStream.flush();
        response.outputStream.close();
    }

    public void doPost(MyHttpRequest request, MyHttpResponse response) throws IOException {
        System.out.println("\n響應(yīng)的http如下:");
        String resp = MyHttpResponse.responsebody +
                "{\"sorry\":\"we only respond to method GET now\"},\r\n" +
                "";
        System.out.println(resp);
        response.outputStream.write(resp.getBytes());
        response.outputStream.flush();
        response.outputStream.close();
    }
}

然后啟動(dòng)項(xiàng)目

如何仿寫(xiě)簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解,tomcat,java

?可以看到本機(jī)ip地址,然后通過(guò)瀏覽器地址欄訪問(wèn)

如何仿寫(xiě)簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解,tomcat,java

?這樣就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的tomcat文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-662587.html

到了這里,關(guān)于如何仿寫(xiě)簡(jiǎn)易tomcat 實(shí)現(xiàn)思路+代碼詳細(xì)講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【仿寫(xiě)tomcat】一、tomcat工作流程

    【仿寫(xiě)tomcat】一、tomcat工作流程

    簡(jiǎn)介 作者前不久剛仿寫(xiě)了一個(gè)簡(jiǎn)易的tomcat,在此分享給各位,此篇為對(duì)tomcat的簡(jiǎn)介和流程分析,具體仿寫(xiě)內(nèi)容后續(xù)會(huì)貼在這里 掃描java文件,獲取帶有@WebServlet注解的類 tomcat簡(jiǎn)介 Tomcat 服務(wù)器是一個(gè)免費(fèi)的開(kāi)放源代碼的Web 應(yīng)用服務(wù)器,屬于輕量級(jí)應(yīng)用服務(wù)器,在中小型系統(tǒng)和

    2024年02月12日
    瀏覽(20)
  • 【仿寫(xiě)框架之仿寫(xiě)Tomact】一、Tomcat的工作流程

    【仿寫(xiě)框架之仿寫(xiě)Tomact】一、Tomcat的工作流程

    當(dāng)涉及到Java Web應(yīng)用程序的部署和運(yùn)行,Apache Tomcat無(wú)疑是一個(gè)備受歡迎的選擇。Tomcat作為一個(gè)開(kāi)源的、輕量級(jí)的Java Servlet容器和JavaServer Pages (JSP) 容器,扮演著連接用戶和應(yīng)用程序的重要角色。本篇文將向大家闡述Tomcat的執(zhí)行流程,從啟動(dòng)到請(qǐng)求處理再到關(guān)閉,幫助您更好地

    2024年02月12日
    瀏覽(23)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】 - 雙向鏈表 - 詳細(xì)實(shí)現(xiàn)思路及代碼

    【數(shù)據(jù)結(jié)構(gòu)與算法】 - 雙向鏈表 - 詳細(xì)實(shí)現(xiàn)思路及代碼

    前幾篇文章介紹了怎樣去實(shí)現(xiàn)單鏈表、單循環(huán)鏈表, 這篇文章主要介紹 雙向鏈表 以及實(shí)現(xiàn)雙向鏈表的步驟,最后提供我自己根據(jù)理解實(shí)現(xiàn)雙向鏈表的C語(yǔ)言代碼 。跟著后面實(shí)現(xiàn)思路看下去,應(yīng)該可以看懂代碼,看懂代碼后,就對(duì)雙向鏈表有了比較抽象的理解了,最后自己再

    2024年02月01日
    瀏覽(28)
  • 【仿寫(xiě)框架之仿寫(xiě)Tomact】一、詳解Tomcat的工作流程

    【仿寫(xiě)框架之仿寫(xiě)Tomact】一、詳解Tomcat的工作流程

    當(dāng)涉及到Java Web應(yīng)用程序的部署和運(yùn)行,Apache Tomcat無(wú)疑是一個(gè)備受歡迎的選擇。Tomcat作為一個(gè)開(kāi)源的、輕量級(jí)的Java Servlet容器和JavaServer Pages (JSP) 容器,扮演著連接用戶和應(yīng)用程序的重要角色。本篇文將向大家闡述Tomcat的執(zhí)行流程,從啟動(dòng)到請(qǐng)求處理再到關(guān)閉,幫助您更好地

    2024年02月12日
    瀏覽(25)
  • 用C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷的代碼及思路(詳細(xì)教程)

    1.當(dāng)選擇1的時(shí)候,輸入 年 ,打印輸入的這一年12月的日歷。 2.當(dāng)選擇2的時(shí)候,輸入 年-月 ,打印輸入這一年這一月的日歷。 實(shí)現(xiàn)效果: 選擇1時(shí) 選擇2時(shí) C語(yǔ)言根據(jù)日期判斷星期幾(使用基姆拉爾森計(jì)算公式) 算法如下: 基姆拉爾森計(jì)算公式 W= (d+2 m+3 (m+1)/5+y+y/4-y/100+y/400)%

    2024年02月11日
    瀏覽(24)
  • 【仿寫(xiě)tomcat】三、通過(guò)socket讀取http請(qǐng)求信息

    【仿寫(xiě)tomcat】三、通過(guò)socket讀取http請(qǐng)求信息

    這里我們也是創(chuàng)建一個(gè)專門(mén)管理socket的類 隨后在主方法中調(diào)用他,讓serverSocket監(jiān)聽(tīng)8080端口,并且一直嘗試獲取連接信息 接下來(lái)在SocketStore中添加處理請(qǐng)求的方法,這里面的主要邏輯就是讀取流數(shù)據(jù),而且我們知道HTTP協(xié)議是一行一行的(看f12就知道了),所以給數(shù)據(jù)拼上換行

    2024年02月12日
    瀏覽(22)
  • Linux系統(tǒng)部署Tomcat詳細(xì)教程(圖文講解)

    前言:本篇博客教大家如何一步一步使用Linux系統(tǒng)去部署自己的Tomcat服務(wù)器,每一行代碼都是我自己嚴(yán)格執(zhí)行過(guò)的,共分為了8點(diǎn)進(jìn)行闡述,邏輯清晰! 博主的其他部署教程: 1、Jenkins部署前后端分離項(xiàng)目:Jenkins部署前后端分離項(xiàng)目最全圖文教程(手把手教學(xué)) 2、Docker部署前

    2024年02月14日
    瀏覽(17)
  • python實(shí)現(xiàn)+leetcode題+合并兩個(gè)有序列表超詳細(xì)流程圖分析以及代碼思路

    python實(shí)現(xiàn)+leetcode題+合并兩個(gè)有序列表超詳細(xì)流程圖分析以及代碼思路

    給你兩個(gè)按非遞減順序排列的整數(shù)列表nums1和nums2,另有兩個(gè)整數(shù)m和n,分別表示nums1和nums2中的元素?cái)?shù)目。請(qǐng)你合并nums2到nums1中,使合并后的數(shù)組同樣按非遞減順序排列。 注意 :最終,合并后數(shù)組不應(yīng)由函數(shù)返回,而是存儲(chǔ)在數(shù)組nums1中。為了應(yīng)對(duì)這種情況,nums1的初始長(zhǎng)度為

    2023年04月09日
    瀏覽(20)
  • 基于SSM框架簡(jiǎn)易項(xiàng)目“書(shū)籍管理系統(tǒng)”,超詳細(xì)講解,附源碼

    基于SSM框架簡(jiǎn)易項(xiàng)目“書(shū)籍管理系統(tǒng)”,超詳細(xì)講解,附源碼

    目錄 我有話說(shuō): 1 項(xiàng)目簡(jiǎn)介 2 項(xiàng)目展示 2.1 首先創(chuàng)建數(shù)據(jù)庫(kù)和表信息 2.2 預(yù)先準(zhǔn)備操作 2.3?開(kāi)始配置項(xiàng)目 2.4 開(kāi)始web層 3 圖片展示 4 附上源碼文件(百度網(wǎng)盤(pán)): 首先 內(nèi)容比較多,篇幅比較長(zhǎng),有需要的可以耐心看完. 這個(gè)項(xiàng)目最開(kāi)始是跟著狂神寫(xiě)下來(lái)的,附上狂神的詳細(xì)視頻鏈接及詳

    2024年02月05日
    瀏覽(26)
  • 【仿寫(xiě)tomcat】六、解析xml文件配置端口、線程池核心參數(shù)

    【仿寫(xiě)tomcat】六、解析xml文件配置端口、線程池核心參數(shù)

    上一篇文章中我們用了Excutors創(chuàng)建了線程,這里我們將它改造成包含所有線程池核心參數(shù)的形式。 主方法中對(duì)多線程操作部分改為使用CompletableFuture執(zhí)行 現(xiàn)在我們有一個(gè)server.xml文件,我想解析其中的端口號(hào)以及線程池參數(shù) 如果想完成這個(gè)功能可以直接使用java本身自帶的工具

    2024年02月12日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包