第五章手書きTomcatノート


一、Tomcatとは何ですか.
Tomcatは本質的にオープンソース軽量級Webアプリケーションサーバであり、優れたサーブレットコンテナ実装である.
コア2点、Webサーバ、サーブレットコンテナ.
アリミドルウェアチーム:http://jm.taobao.org/about/
多くの会社が手書きや書き換えをしています例えばaliTomcat:https://help.aliyun.com/document_detail/90754.html
1、ネットの基礎知識:
ネットワーク通信、クライアントとサービス側の関係、javaではSocket通信が確立されており、一般的なSocketはTCPベースのプロトコルであることに注意してください.
第五章 手写Tomcat笔记_第1张图片
 
2、Tomcatの本質を復元する:
第五章 手写Tomcat笔记_第2张图片
 
二、手書きTomcat実現コード
1、手書きの第一歩:簡単なBIOの通信を完成する
//1、     ---JDK            API
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("       !");
while(!serverSocket.isClosed()){//     
    //2、        ,    socket:         --      
   Socket socket =  serverSocket.accept();
   //3、           
    executorService.execute(()->{
        try{
            InputStream inputStream = socket.getInputStream();
            System.out.println("    :");
            BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream,"utf-8"));
            //   
            String msg =null;
            StringBuilder requestInfo = new StringBuilder();
            while ( (msg=reader.readLine()) !=null ){
                if(msg.length()==0) break;
                requestInfo.append(msg).append("\r
");             }             System.out.println(requestInfo);             // ,             String firstline =requestInfo.toString().split("\r
")[0];             System.out.println(firstline);

2、Tomcatはブラウザとどのようにやり取りするか:
ブラウザ間の通信はHTTPプロトコルに適合しなければならず、応答情報はHTTPフォーマットの応答に加わる
//          ,        
    String firstline =requestInfo.toString().split("\r
")[0];     System.out.println(firstline);     //     if(firstline.length()<1){         return;     }     String servletPath = firstline.split(" ")[1];     //Servet     Map servletMapping=  (Map)webAppMap.get("servlet-mapping");     //Servlet     Map servletInstances=  (Map )webAppMap.get("servlet");     // url Servlet     if(servletMapping.containsKey(servletPath)){         String servletName = servletMapping.get(servletPath);         HttpServlet httpServlet =  (HttpServlet)servletInstances.get(servletName);         HttpServletRequest httpServletRequest =createRequest();         HttpServletResponse httpServletResponse = createResponse();         httpServlet.service(httpServletRequest,httpServletResponse);         OutputStream outputStream = socket.getOutputStream();         byte[] response =" !".getBytes();         outputStream.write("HTTP/1.1 200 OK \r
".getBytes());         outputStream.write("Content-Type:text/html;charset=utf-8 \r
".getBytes());         outputStream.write( ("Content-Length:"+response.length+"\r
").getBytes());         outputStream.write("\r
".getBytes());         outputStream.write(response);         outputStream.flush();         System.out.println("----END");     }else{         // “ ” ,HTTP         OutputStream outputStream = socket.getOutputStream();         byte[] response =" , Servlet !".getBytes();         outputStream.write("HTTP/1.1 200 OK \r
".getBytes());         outputStream.write("Content-Type:text/html;charset=utf-8 \r
".getBytes());         outputStream.write( ("Content-Length:"+response.length+"\r
").getBytes());         outputStream.write("\r
".getBytes());         outputStream.write(response);         outputStream.flush();         System.out.println("----END");     } }catch (IOException e){

3、Tomcatでコードを走らせる
クラス・ロード
public static void main(String[] args) throws  Exception{
    //0、    (   )、  、HashMap
    Map webAppMap = ProjectLoader.load();



public class ProjectLoader {
    public static Map load() throws Exception{
        //    Map,      
        Map webapp = new HashMap<>();
        Map servletInstances = new HashMap<>(); //servlet
        Map servletMapping = new HashMap<>(); //servlet-mapping
        //    
        String webappPath ="D:\\work_public\\servletdemo\\out\\artifacts\\servletdemo_war_exploded\\WEB-INF";
        //JDK       URL
        URL classFile = new URL("file:"+webappPath+"\\classes\\");
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{classFile});
        //  xml  
        //1.     
        SAXReader reader = new SAXReader();
        //2.      (xml)
        Document document = reader.read(new File(webappPath+"\\web.xml"));
        //3.     
        Element root = document.getRootElement();
        //4.           
        List childElements = root.elements();
        //5.     
        for (Element element:childElements) {
            //6.       servlet   
            if ("servlet".equals(element.getName())) {
                //  servlet-name  
                Element servletName = element.element("servlet-name");
                //  servlet-class  
                Element servletClass = element.element("servlet-class");
                String strServletName = servletName.getText();
                String strServletClass = servletClass.getText();
                System.out.println("servlet:"+strServletName+"="+strServletClass);
                //1.   JVM
                Class> classzz= urlClassLoader.loadClass(strServletClass);
                //2       (  ) -servlet;
                Servlet servlet  = (Servlet)classzz.newInstance();
                //web.xml servlet     hashmap
                servletInstances.put(strServletName, servlet);
            }
            //7.       servlet-mapping   
            if ("servlet-mapping".equals(element.getName())) {
                //  servlet-name  
                Element servletName = element.element("servlet-name");
                //  url-pattern  
                Element urlPattern = element.element("url-pattern");
                String strServletName = servletName.getText();
                String strUrlPattern = urlPattern.getText();
                //web.xml servlet Mapping  hashmap
                System.out.println("servlet-mapping:"+strUrlPattern+"="+strServletName);
                servletMapping.put(strUrlPattern,strServletName);
            }
        }
        webapp.put("servlet",servletInstances);
        webapp.put("servlet-mapping",servletMapping);
        return  webapp;
    }
}

要求アドレスを解析し、対応するサーブレットを見つけます.
//          ,        
String firstline =requestInfo.toString().split("\r
")[0]; System.out.println(firstline); // if(firstline.length()<1){     return; } String servletPath = firstline.split(" ")[1]; //Servet Map servletMapping=  (Map)webAppMap.get("servlet-mapping"); //Servlet Map servletInstances=  (Map )webAppMap.get("servlet");

4、パラメータを構築し、サーブレットのサービス方法を実行する
//      url   Servlet
if(servletMapping.containsKey(servletPath)){
    String servletName = servletMapping.get(servletPath);
    HttpServlet httpServlet =  (HttpServlet)servletInstances.get(servletName);
    HttpServletRequest httpServletRequest =createRequest();
    HttpServletResponse httpServletResponse = createResponse();
    httpServlet.service(httpServletRequest,httpServletResponse);
    OutputStream outputStream = socket.getOutputStream();
    byte[] response ="    !".getBytes();
    outputStream.write("HTTP/1.1 200 OK \r
".getBytes());     outputStream.write("Content-Type:text/html;charset=utf-8 \r
".getBytes());     outputStream.write( ("Content-Length:"+response.length+"\r
").getBytes());     outputStream.write("\r
".getBytes());     outputStream.write(response);     outputStream.flush();     System.out.println("----END");

単純なパラメータの構築
HttpServletRequest httpServletRequest =createRequest();HttpServletResponse httpServletResponse = createResponse();