zoukankan      html  css  js  c++  java
  • Tomcat学习笔记(十二)

      Host和Engine容器 

    Context容器的父容器通常是Host容器。 
    Engine容器表示Catalina的整个servlet引擎。如果使用Engine容器,那么它总是处于容器层级的最顶层。默认情况下,Tomcat会使用Engine容器,并且有一个Host容器作为子容器。 

    Host接口继承Container接口

    public interface Host extends Container {
    ...
    }

    StandardHost类继承ContainerBase并且实现Host接口,与StandardContext和StandardWrapper类相似,StandardHost类会在构造方法会设置一个基础阀门添加到管道中。

    public StandardHost() {
            super();
            pipeline.setBasic(new StandardHostValve());
        }

    StandardHostValve类也和StandardContext,StandardWrapper相似,实现了一个invoke方法,基于具体的请求路径,选择合适的子容器处理请求,如果没有匹配的,则返回Http error。

    public final void invoke(Request request, Response response)
            throws IOException, ServletException {
    
            // Select the Context to be used for this Request
            Context context = request.getContext();
            if (context == null) {
                response.sendError
                    (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                     sm.getString("standardHost.noContext"));
                return;
            }
    
            // Bind the context CL to the current thread
            if( context.getLoader() != null ) {
                // Not started - it should check for availability first
                // This should eventually move to Engine, it's generic.
                if (Globals.IS_SECURITY_ENABLED) {
                    PrivilegedAction<Void> pa = new PrivilegedSetTccl(
                            context.getLoader().getClassLoader());
                    AccessController.doPrivileged(pa);                
                } else {
                    Thread.currentThread().setContextClassLoader
                            (context.getLoader().getClassLoader());
                }
            }
            if (request.isAsyncSupported()) {
                request.setAsyncSupported(context.getPipeline().isAsyncSupported());
            }
    
            boolean asyncAtStart = request.isAsync(); 
            boolean asyncDispatching = request.isAsyncDispatching();
            if (asyncAtStart || context.fireRequestInitEvent(request)) {
    
                // Ask this Context to process this request. Requests that are in
                // async mode and are not being dispatched to this resource must be
                // in error and have been routed here to check for application
                // defined error pages.
                try {
                    if (!asyncAtStart || asyncDispatching) {
                        context.getPipeline().getFirst().invoke(request, response);
                    } else {
                        // Make sure this request/response is here because an error
                        // report is required.
                        if (!response.isErrorReportRequired()) {
                            throw new IllegalStateException(sm.getString("standardHost.asyncStateError"));
                        }
                    }
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    // If a new error occurred while trying to report a previous
                    // error simply log the new error and allow the original error
                    // to be reported.
                    if (response.isErrorReportRequired()) {
                        container.getLogger().error("Exception Processing " +
                                request.getRequestURI(), t);
                    } else {
                        request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
                        throwable(request, response, t);
                    }
                }
    
                // Now that the request/response pair is back under container
                // control lift the suspension so that the error handling can
                // complete and/or the container can flush any remaining data
                response.setSuspended(false);
    
                Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
    
                // Protect against NPEs if the context was destroyed during a
                // long running request.
                if (!context.getState().isAvailable()) {
                    return;
                }
    
                // Look for (and render if found) an application level error page
                if (response.isErrorReportRequired()) {
                    if (t != null) {
                        throwable(request, response, t);
                    } else {
                        status(request, response);
                    }
                }
    
                if (!request.isAsync() && (!asyncAtStart || !response.isErrorReportRequired())) {
                    context.fireRequestDestroyEvent(request);
                }
            }
    
            // Access a session (if present) to update last accessed time, based on a
            // strict interpretation of the specification
            if (ACCESS_SESSION) {
                request.getSession(false);
            }
    
            // Restore the context classloader
            if (Globals.IS_SECURITY_ENABLED) {
                PrivilegedAction<Void> pa = new PrivilegedSetTccl(
                        StandardHostValve.class.getClassLoader());
                AccessController.doPrivileged(pa);                
            } else {
                Thread.currentThread().setContextClassLoader
                        (StandardHostValve.class.getClassLoader());
            }
        }

    ContextConfig类 
    主要加载一些配置属性 
    web.xml的加载

    /**
         * Identify the application web.xml to be used and obtain an input source
         * for it.
         */
        protected InputSource getContextWebXmlSource() {
            InputStream stream = null;
            InputSource source = null;
            URL url = null;
    
            String altDDName = null;
    
            // Open the application web.xml file, if it exists
            ServletContext servletContext = context.getServletContext();
            if (servletContext != null) {
                altDDName = (String)servletContext.getAttribute(
                                                            Globals.ALT_DD_ATTR);
                if (altDDName != null) {
                    try {
                        stream = new FileInputStream(altDDName);
                        url = new File(altDDName).toURI().toURL();
                    } catch (FileNotFoundException e) {
                        log.error(sm.getString("contextConfig.altDDNotFound",
                                               altDDName));
                    } catch (MalformedURLException e) {
                        log.error(sm.getString("contextConfig.applicationUrl"));
                    }
                }
                else {
                    stream = servletContext.getResourceAsStream
                        (Constants.ApplicationWebXml);
                    try {
                        url = servletContext.getResource(
                                Constants.ApplicationWebXml);
                    } catch (MalformedURLException e) {
                        log.error(sm.getString("contextConfig.applicationUrl"));
                    }
                }
            }
            if (stream == null || url == null) {
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("contextConfig.applicationMissing") + " " + context);
                }
            } else {
                source = new InputSource(url.toExternalForm());
                source.setByteStream(stream);
            }
            return source;
        }
       //常量类
        public final class Constants{
        ...
        public static final String ApplicationWebXml = "/WEB-INF/web.xml";
        ...
    }
  • 相关阅读:
    如何处理数集据不平衡的问题
    xgb&lgb&ctb区别
    LDA与gibbs采样
    撸了一个 Feign 增强包
    行为驱动模型-Behave
    MySQL 主从复制常见错误答疑
    POJ 1191
    POJ 1141
    HDU 1754
    POJ 3468
  • 原文地址:https://www.cnblogs.com/lzeffort/p/7148347.html
Copyright © 2011-2022 走看看