亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

How Tomcat Works(十六)

系統(tǒng) 1889 0

本文接下來會(huì)介紹Host容器和Engine容器,在tomcat的實(shí)際部署中,總是會(huì)使用一個(gè)Host容器;本文介紹Host接口和Engine接口及其相關(guān)類

Host容器是org.apache.catalina.Host接口的實(shí)例,Host接口繼承自Container接口, 其定義如下

      
        public
      
      
        interface
      
       Host 
      
        extends
      
      
         Container {
   
      
      
        public
      
      
        static
      
      
        final
      
       String ADD_ALIAS_EVENT = "addAlias"
      
        ;
    
      
      
        public
      
      
        static
      
      
        final
      
       String REMOVE_ALIAS_EVENT = "removeAlias"
      
        ;
   
      
      
        public
      
      
         String getAppBase();
   
      
      
        public
      
      
        void
      
      
         setAppBase(String appBase);
   
      
      
        public
      
      
        boolean
      
      
         getAutoDeploy();
   
      
      
        public
      
      
        void
      
       setAutoDeploy(
      
        boolean
      
      
         autoDeploy);
    
      
      
        public
      
      
        void
      
      
         addDefaultContext(DefaultContext defaultContext);
   
      
      
        public
      
      
         DefaultContext getDefaultContext();
    
      
      
        public
      
      
         String getName();
    
      
      
        public
      
      
        void
      
      
         setName(String name);
   
      
      
        public
      
      
        void
      
      
         importDefaultContext(Context context);
    
      
      
        public
      
      
        void
      
      
         addAlias(String alias);
    
      
      
        public
      
      
         String[] findAliases();
    
      
      
        public
      
      
         Context map(String uri);
   
      
      
        public
      
      
        void
      
      
         removeAlias(String alias);

}
      
    

該接口中比較重要的方法是map()方法,該方法返回一個(gè)用來處理引入的HTTP請(qǐng)求的Context容器的實(shí)例,該方法的具體實(shí)現(xiàn)在StandardHost類中

在tomcat中org.apache.catalina.core.StandardHost類是Host接口的標(biāo)準(zhǔn)實(shí)現(xiàn),該類繼承自org.apache.catalina.core.ContainerBase類,實(shí)現(xiàn)了Host和Deployer接口

與StandardContext類和StandardWrapper類相似,StandardHost類的構(gòu)造函數(shù)會(huì)將一個(gè)基礎(chǔ)閥的實(shí)例添加到其管道對(duì)象中:

      
        public
      
      
         StandardHost() {

        
      
      
        super
      
      
        ();
        pipeline.setBasic(
      
      
        new
      
      
         StandardHostValve());

    }
      
    

基礎(chǔ)閥是org.apache.catalina.core.StandardHostValve類的實(shí)例

當(dāng)調(diào)用其start()方法時(shí),StandardHost實(shí)例會(huì)添加兩個(gè)閥,分別為ErrorReportValve類和ErrorDispatcherValve類的實(shí)例,這兩個(gè)閥均位于org.apache.catalina.valves包下

      
        public
      
      
        synchronized
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {
        
      
      
        //
      
      
         Set error report valve
      
      
        if
      
       ((errorReportValveClass != 
      
        null
      
      
        )
            
      
      && (!errorReportValveClass.equals(""
      
        ))) {
            
      
      
        try
      
      
         {
                Valve valve 
      
      =
      
         (Valve) Class.forName(errorReportValveClass)
                    .newInstance();
                addValve(valve);
            } 
      
      
        catch
      
      
         (Throwable t) {
                log(sm.getString
                    (
      
      "standardHost.invalidErrorReportValveClass"
      
        ,
                     errorReportValveClass));
            }
        }

        
      
      
        //
      
      
         Set dispatcher valve
      
      
        addValve(
      
        new
      
      
         ErrorDispatcherValve());

        
      
      
        super
      
      
        .start();

    }
      
    

每當(dāng)引入一個(gè)HTTP請(qǐng)求,都會(huì)調(diào)用Host實(shí)例的invoke()方法,這里是StandardHost的父類ContainerBase類的invoke()方法,而ContainerBase類的invoke()方法會(huì)調(diào)用StandardHost實(shí)例的基礎(chǔ)閥StandardHostValve實(shí)例的invoke()方法;StandardHostValve類的invoke()方法會(huì)調(diào)用StandardHost類的map()方法來獲取相應(yīng)的Context實(shí)例來處理HTTP請(qǐng)求

      
        public
      
      
         Context map(String uri) {

        
      
      
        if
      
       (debug > 0
      
        )
            log(
      
      "Mapping request URI '" + uri + "'"
      
        );
        
      
      
        if
      
       (uri == 
      
        null
      
      
        )
            
      
      
        return
      
       (
      
        null
      
      
        );

        
      
      
        //
      
      
         Match on the longest possible context path prefix
      
      
        if
      
       (debug > 1
      
        )
            log(
      
      "  Trying the longest context path prefix"
      
        );
        Context context 
      
      = 
      
        null
      
      
        ;
        String mapuri 
      
      =
      
         uri;
        
      
      
        while
      
       (
      
        true
      
      
        ) {
            context 
      
      =
      
         (Context) findChild(mapuri);
            
      
      
        if
      
       (context != 
      
        null
      
      
        )
                
      
      
        break
      
      
        ;
            
      
      
        int
      
       slash = mapuri.lastIndexOf('/'
      
        );
            
      
      
        if
      
       (slash < 0
      
        )
                
      
      
        break
      
      
        ;
            mapuri 
      
      = mapuri.substring(0
      
        , slash);
        }

        
      
      
        //
      
      
         If no Context matches, select the default Context
      
      
        if
      
       (context == 
      
        null
      
      
        ) {
            
      
      
        if
      
       (debug > 1
      
        )
                log(
      
      "  Trying the default context"
      
        );
            context 
      
      = (Context) findChild(""
      
        );
        }

        
      
      
        //
      
      
         Complain if no Context has been selected
      
      
        if
      
       (context == 
      
        null
      
      
        ) {
            log(sm.getString(
      
      "standardHost.mappingError"
      
        , uri));
            
      
      
        return
      
       (
      
        null
      
      
        );
        }

        
      
      
        //
      
      
         Return the mapped Context (if any)
      
      
        if
      
       (debug > 0
      
        )
            log(
      
      " Mapped to context '" + context.getPath() + "'"
      
        );
        
      
      
        return
      
      
         (context);

    }
      
    

在tomcat4中, StandardHost的父類ContainerBase類會(huì)調(diào)用其addDefaultMapper()方法創(chuàng)建一個(gè)默認(rèn)映射器,默認(rèn)映射器的類型由mapperClass屬性的值決定

      
        protected
      
      
        void
      
      
         addDefaultMapper(String mapperClass) {

        
      
      
        //
      
      
         Do we need a default Mapper?
      
      
        if
      
       (mapperClass == 
      
        null
      
      
        )
            
      
      
        return
      
      
        ;
        
      
      
        if
      
       (mappers.size() >= 1
      
        )
            
      
      
        return
      
      
        ;

        
      
      
        //
      
      
         Instantiate and add a default Mapper
      
      
        try
      
      
         {
            Class clazz 
      
      =
      
         Class.forName(mapperClass);
            Mapper mapper 
      
      =
      
         (Mapper) clazz.newInstance();
            mapper.setProtocol(
      
      "http"
      
        );
            addMapper(mapper);
        } 
      
      
        catch
      
      
         (Exception e) {
            log(sm.getString(
      
      "containerBase.addDefaultMapper"
      
        , mapperClass),
                e);
        }

    }
      
    

變量mapperClass的值定義在StandardHst類中

private String mapperClass =
??????? "org.apache.catalina.core.StandardHostMapper";

在tomcat4中,StandardHost類的start()方法會(huì)在方法末尾調(diào)用addDefaultMapper()方法,確保默認(rèn)映射器的創(chuàng)建完成

當(dāng)然,StandardHostMapper類中最重要的方法是map()方法,下面是map()方法的實(shí)現(xiàn)

      
        public
      
       Container map(Request request, 
      
        boolean
      
      
         update) {
        
      
      
        //
      
      
         Has this request already been mapped?
      
      
        if
      
       (update && (request.getContext() != 
      
        null
      
      
        ))
            
      
      
        return
      
      
         (request.getContext());

        
      
      
        //
      
      
         Perform mapping on our request URI
      
      
        String uri =
      
         ((HttpRequest) request).getDecodedRequestURI();
        Context context 
      
      =
      
         host.map(uri);

        
      
      
        //
      
      
         Update the request (if requested) and return the selected Context
      
      
        if
      
      
         (update) {
            request.setContext(context);
            
      
      
        if
      
       (context != 
      
        null
      
      
        )
                ((HttpRequest) request).setContextPath(context.getPath());
            
      
      
        else
      
      
        
                ((HttpRequest) request).setContextPath(
      
      
        null
      
      
        );
        }
        
      
      
        return
      
      
         (context);

    }
      
    

注意,這里map()方法僅僅是簡單地調(diào)用了Host實(shí)例的map()方法

org.apache.catalina.core.StandardHostValve類是StandardHost實(shí)例的基礎(chǔ)閥,當(dāng)有引入的HTTP請(qǐng)求時(shí),會(huì)調(diào)用StandardHostValve類的invoke()方法對(duì)其進(jìn)行處理

      
        public
      
      
        void
      
      
         invoke(Request request, Response response,
                       ValveContext valveContext)
        
      
      
        throws
      
      
         IOException, ServletException {

        
      
      
        //
      
      
         Validate the request and response object types
      
      
        if
      
       (!(request.getRequest() 
      
        instanceof
      
       HttpServletRequest) ||
            !(response.getResponse() 
      
        instanceof
      
      
         HttpServletResponse)) {
            
      
      
        return
      
      ;     
      
        //
      
      
         NOTE - Not much else we can do generically
      
      
                }

        
      
      
        //
      
      
         Select the Context to be used for this Request
      
      
        StandardHost host =
      
         (StandardHost) getContainer();
        Context context 
      
      = (Context) host.map(request, 
      
        true
      
      
        );
        
      
      
        if
      
       (context == 
      
        null
      
      
        ) {
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 sm.getString(
      
      "standardHost.noContext"
      
        ));
            
      
      
        return
      
      
        ;
        }

        
      
      
        //
      
      
         Bind the context CL to the current thread
      
      
                Thread.currentThread().setContextClassLoader
            (context.getLoader().getClassLoader());

        
      
      
        //
      
      
         Update the session last access time for our session (if any)
      
      
        HttpServletRequest hreq =
      
         (HttpServletRequest) request.getRequest();
        String sessionId 
      
      =
      
         hreq.getRequestedSessionId();
        
      
      
        if
      
       (sessionId != 
      
        null
      
      
        ) {
            Manager manager 
      
      =
      
         context.getManager();
            
      
      
        if
      
       (manager != 
      
        null
      
      
        ) {
                Session session 
      
      =
      
         manager.findSession(sessionId);
                
      
      
        if
      
       ((session != 
      
        null
      
      ) &&
      
         session.isValid())
                    session.access();
            }
        }

        
      
      
        //
      
      
         Ask this Context to process this request
      
      
                context.invoke(request, response);

    }
      
    

在tomcat4中,invoke()方法會(huì)調(diào)用StandardHost實(shí)例的map()方法獲取一個(gè)相應(yīng)的Context實(shí)例;然后獲取與該request對(duì)象相關(guān)聯(lián)的session對(duì)象,并調(diào)用其access()方法,access()方法會(huì)修改session對(duì)象的最后訪問時(shí)間;最后調(diào)用Context實(shí)例的invoke()來處理HTTP請(qǐng)求

接下來描述Engine容器,Engine容器是org.apache.catalina.Engine接口的實(shí)例,Engine容器也就是Tomcat的servlet引擎

      
        public
      
      
        interface
      
       Engine 
      
        extends
      
      
         Container {
    
      
      
        public
      
      
         String getDefaultHost();
   
      
      
        public
      
      
        void
      
      
         setDefaultHost(String defaultHost);
    
      
      
        public
      
      
         String getJvmRoute();
  
      
      
        public
      
      
        void
      
      
         setJvmRoute(String jvmRouteId);
    
      
      
        public
      
      
         Service getService();
   
      
      
        public
      
      
        void
      
      
         setService(Service service);
   
      
      
        public
      
      
        void
      
      
         addDefaultContext(DefaultContext defaultContext);
    
      
      
        public
      
      
         DefaultContext getDefaultContext();
    
      
      
        public
      
      
        void
      
      
         importDefaultContext(Context context);

}
      
    

在Engine容器中,可以設(shè)置一個(gè)默認(rèn)的Host容器或一個(gè)默認(rèn)的Context容器,注意,Engine容器可以與一個(gè)服務(wù)實(shí)例相關(guān)聯(lián)

org.apache.catalina.core.StandardEngine類是Engine接口的標(biāo)準(zhǔn)實(shí)現(xiàn),在實(shí)例化的時(shí)候,StandardEngine類會(huì)添加一個(gè)基礎(chǔ)閥

      
        public
      
      
         StandardEngine() {

        
      
      
        super
      
      
        ();
        pipeline.setBasic(
      
      
        new
      
      
         StandardEngineValve());

    }
      
    

org.apache.catalina.core.StandardEngineValve類是StandardEngine容器的基礎(chǔ)閥,下面是它的invoke()方法的實(shí)現(xiàn)代碼

      
        public
      
      
        void
      
      
         invoke(Request request, Response response,
                       ValveContext valveContext)
        
      
      
        throws
      
      
         IOException, ServletException {
        
      
      
        //
      
      
         Validate the request and response object types
      
      
        if
      
       (!(request.getRequest() 
      
        instanceof
      
       HttpServletRequest) ||
            !(response.getResponse() 
      
        instanceof
      
      
         HttpServletResponse)) {
            
      
      
        return
      
      ;     
      
        //
      
      
         NOTE - Not much else we can do generically
      
      
                }

        
      
      
        //
      
      
         Validate that any HTTP/1.1 request included a host header
      
      
        HttpServletRequest hrequest =
      
         (HttpServletRequest) request;
        
      
      
        if
      
       ("HTTP/1.1".equals(hrequest.getProtocol()) &&
      
        
            (hrequest.getServerName() 
      
      == 
      
        null
      
      
        )) {
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_BAD_REQUEST,
                 sm.getString(
      
      "standardEngine.noHostHeader"
      
        ,
                              request.getRequest().getServerName()));
            
      
      
        return
      
      
        ;
        }

        
      
      
        //
      
      
         Select the Host to be used for this Request
      
      
        StandardEngine engine =
      
         (StandardEngine) getContainer();
        Host host 
      
      = (Host) engine.map(request, 
      
        true
      
      
        );
        
      
      
        if
      
       (host == 
      
        null
      
      
        ) {
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_BAD_REQUEST,
                 sm.getString(
      
      "standardEngine.noHost"
      
        ,
                              request.getRequest().getServerName()));
            
      
      
        return
      
      
        ;
        }

        
      
      
        //
      
      
         Ask this Host to process this request
      
      
                host.invoke(request, response);

    }
      
    

在驗(yàn)證了request和response對(duì)象的類型后,invoke()方法會(huì)通過調(diào)用Engine實(shí)例的map()方法獲取Host對(duì)象;得到Host對(duì)象以后,調(diào)用其invoke()方法處理請(qǐng)求

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創(chuàng)?

轉(zhuǎn)載請(qǐng)注明出處 博客園 刺猬的溫馴?

本人郵箱: ? chenying998179 # 163.com ( #改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3249152.html

How Tomcat Works(十六)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产精品欧美日韩视频一区 | 日本夜爽爽一区二区三区 | 亚洲高清中文字幕一区二区三区 | 免费高清毛片 | 神马影院我不卡影院 | 国产黄色自拍视频 | 精品国产免费第一区二区三区日韩 | 久久久久精彩视频 | 亚洲国产爱久久全部精品 | 乱子伦xxx欧美 | 欧美一区二区在线免费观看 | 亚洲欧美精品综合中文字幕 | 中文久久| 国内精品伊人久久久久7777人 | 午夜免费体验区 | 天天射天天爱天天干 | 99在线观看精品免费99 | 2021福利视频 | 欧美大成色www永久网站 | 亚洲国产最新在线一区二区 | 欧美成人久久久 | 国产一区二区三区在线观看精品 | 欧美成人特黄级毛片 | 一区二区精品视频 | 亚洲国产另类久久久精品小说 | 综合国产福利视频在线观看 | 成人网欧美亚洲影视图片 | 外国成人网在线观看免费视频 | 国产这里只有精品 | 午夜精品久久久久久久99 | 欧美久草视频 | 亚洲高清视频在线观看 | 成人在线91 | 成人免费黄色小视频 | 青草社区视频 | 曹逼视频 | 久久厕所精品国产精品亚洲 | 一区二区视频在线播放 | 2021在线永久免费视频 | 91热国内精品永久免费观看 | 永久黄网站色视频免费观看99 |