tomcat源码解析第6课-一次http请求过程

目录
1、启动8080端口监听http请求时序图
2、启动8080端口监听http请求代码解析
3、http请求时序图
4、http请求request和response的封装
5、查找自定义过滤器和servlet
6、自定义的过滤器和servlet调用

一、启动8080端口监听http请求时序图

在这里插入图片描述

二、启动8080端口监听http请求代码解析

NioEndpoint的方法startInternal启动socket的监听,监听http请求

@Override
    public void startInternal() throws Exception {

        if (!running) {
            running = true;
            paused = false;

            processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                    socketProperties.getProcessorCache());
            eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                            socketProperties.getEventCache());
            nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                    socketProperties.getBufferPool());

            // Create worker collection
            if ( getExecutor() == null ) {
                createExecutor();
            }

            initializeConnectionLatch();

            // Start poller threads
            pollers = new Poller[getPollerThreadCount()];
            for (int i=0; i<pollers.length; i++) {
                pollers[i] = new Poller();
                Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
                pollerThread.setPriority(threadPriority);
                pollerThread.setDaemon(true);
                pollerThread.start();
            }
            //开启线程监听http请求
            startAcceptorThreads();
        }
    }

NioEndpoint的内部类Acceptor,启动监听,在浏览器输入http地址,此内部类接受到请求

protected class Acceptor extends AbstractEndpoint.Acceptor {

        @Override
        public void run() {

            int errorDelay = 0;

            // Loop until we receive a shutdown command
            while (running) {

                // Loop if endpoint is paused
                while (paused && running) {
                    state = AcceptorState.PAUSED;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }

                if (!running) {
                    break;
                }
                state = AcceptorState.RUNNING;

                try {
                    //if we have reached max connections, wait
                    countUpOrAwaitConnection();

                    SocketChannel socket = null;
                    try {
                        // Accept the next incoming connection from the server
                        // 监听http请求
                        socket = serverSock.accept();
                    } catch (IOException ioe) {
                        // We didn't get a socket
                        countDownConnection();
                        if (running) {
                            // Introduce delay if necessary
                            errorDelay = handleExceptionWithDelay(errorDelay);
                            // re-throw
                            throw ioe;
                        } else {
                            break;
                        }
                    }
                    // Successful accept, reset the error delay
                    errorDelay = 0;

                    // Configure the socket
                    if (running && !paused) {
                        // setSocketOptions() will hand the socket off to
                        // an appropriate processor if successful
                        //重要的方法,将socket连接添加到一个缓存队列,这里使用的是生产者和消费者模式
                        //关于生产者和消费者的学习地址
                        //http://blog.csdn.net/c275046758/article/details/50492107
                        if (!setSocketOptions(socket)) {
                            closeSocket(socket);
                        }
                    } else {
                        closeSocket(socket);
                    }
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }
            }
            state = AcceptorState.ENDED;
        }
        。。。。。
    }

三、http请求时序图在这里插入图片描述

四、http请求request和response的封装

在这里插入图片描述
类AbstractProtocol,完成tomcat的不能被继承org.apache.coyote.Request和org.apache.coyote.Response的初始化

@Override
        public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {
          。。。。。
                if (processor == null) {
                //初始化tomcat内部的request和response
                    processor = getProtocol().createProcessor();
                    register(processor);
                }
                SocketState state = SocketState.CLOSED;
                do {
                //重点
                    state = processor.process(wrapper, status);

        }

类CoyoteAdapter,完成org.apache.coyote.Request、org.apache.coyote.Response到org.apache.catalina.connector.Request、org.apache.catalina.connector.Response的转换;

@Override
    public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
            throws Exception {

        Request request = (Request) req.getNote(ADAPTER_NOTES);
        Response response = (Response) res.getNote(ADAPTER_NOTES);
		//request和response的转换
        if (request == null) {
            // Create objects
            request = connector.createRequest();
            request.setCoyoteRequest(req);
            response = connector.createResponse();
            response.setCoyoteResponse(res);

            // Link objects
            request.setResponse(response);
            response.setRequest(request);
        }
        try {
            // Parse and set Catalina and configuration specific
            // 查找servlet
            postParseSuccess = postParseRequest(req, request, res, response);
            if (postParseSuccess) {
                //check valves if we support async
                request.setAsyncSupported(
                        connector.getService().getContainer().getPipeline().isAsyncSupported());
                // 重点
                connector.getService().getContainer().getPipeline().getFirst().invoke(
                        request, response);
            }
          
    }

StandardContextValve类,如果访问的是WEB-INF目录则阻止

 public final void invoke(Request request, Response response)
        throws IOException, ServletException {
        // 对指定的访问目录做控制 WEB-INF or META-INF
        MessageBytes requestPathMB = request.getRequestPathMB();
        if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
                || (requestPathMB.equalsIgnoreCase("/META-INF"))
                || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
                || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

五、查找自定义的过滤器和servlet

CoyoteAdapter类的方法postParseRequest,查找servlet

protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
            org.apache.coyote.Response res, Response response) throws IOException, ServletException {
。。。。。。。。。。
        while (mapRequired) {
            // 查找到servlet
            connector.getService().getMapper().map(serverName, decodedURI,
                    version, request.getMappingData());
}

六、自定义的过滤器和servlet的调用

类ApplicationFilterChain,调用自定义的过滤器和自定义servlet

private void internalDoFilter(ServletRequest request,
                                  ServletResponse response)
        throws IOException, ServletException {
                if( Globals.IS_SECURITY_ENABLED ) {
                    final ServletRequest req = request;
                    final ServletResponse res = response;
                    Principal principal =
                        ((HttpServletRequest) req).getUserPrincipal();

                    Object[] args = new Object[]{req, res, this};
                    SecurityUtil.doAsPrivilege ("doFilter", filter, classType, args, principal);
                } else {
                //调用自定义过滤器
                    filter.doFilter(request, response, this);
                }
            } catch (IOException | ServletException | RuntimeException e) {
                throw e;
            } catch (Throwable e) {
                e = ExceptionUtils.unwrapInvocationTargetException(e);
                ExceptionUtils.handleThrowable(e);
                throw new ServletException(sm.getString("filterChain.filter"), e);
            }
            return;
        }

            } else {
            //调用自定义servlet
                servlet.service(request, response);
            }
     
    }

一次http请求参考资料:https://blog.csdn.net/c275046758/article/details/51347545

猜你喜欢

转载自blog.csdn.net/csdnjquery163com/article/details/82874554
今日推荐