在上一篇文章文章中,Tomcat的请求处理到了JIoEndpoint$Worker#run()方法的handler.process(socket)这个调用中。
这个handler在JIoEndpoint中是这样定义的:
protected Handler handler = null;
这个Handler是在JIoEndpoint内部定义的一个接口,它的内部只有public boolean process(Socket socket);这一个方法。
那么这个handler到底在哪里实现的呢?
这个还要从org.apache.coyote.http11.Http11Protocol#init()中处理的,也就是在Tomcat的初始化过程中设置的。
endpoint.setHandler(cHandler);
这个cHandler就是设置的handler,它的定义如下:
protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);
这个Http11ConnectionHandler是一个Http11Protocol的内部类,它的process()方法如下所示:
public boolean process(Socket socket) { // 获取processor Http11Processor processor = recycledProcessors.poll(); try { if (processor == null) { // 如果为空创建一个 processor = createProcessor(); } if (processor instanceof ActionHook) { // 设置Http11Processor的一个成员变量started为true ((ActionHook) processor).action(ActionCode.ACTION_START, null); } // 设置SSL支持 if (proto.secure && (proto.sslImplementation != null)) { processor.setSSLSupport(proto.sslImplementation.getSSLSupport(socket)); } else { processor.setSSLSupport(null); } // 继续处理 processor.process(socket); return false; } catch (java.net.SocketException e) { Http11Protocol.log.debug( sm.getString("http11protocol.proto.socketexception.debug"), e); } catch (java.io.IOException e) { Http11Protocol.log.debug(sm.getString("http11protocol.proto.ioexception.debug"), e); } catch (Throwable e) { Http11Protocol.log.error(sm.getString("http11protocol.proto.error"), e); } finally { if (processor instanceof ActionHook) { // 设置Http11Processor的一个成员变量started为false ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); } // 回收processor recycledProcessors.offer(processor); } return false; }
首先,程序要创建一个Http11Processor对象,然后将它内部的一个标志started设为true,然后将socket对象传给Http11Processor#process()去继续请求流程。
最后请求结束后,程序会确保started设为false,并且会回收前面使用的Http11Processor对象。
于是,接下来请求就到了Http11Processor#process()这个方法了。
public void process(Socket socket) throws IOException { // 请求信息,request对象 RequestInfo rp = request.getRequestProcessor(); // 设定请求的状态为STAGE_PARSE rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // 设定远端地址 remoteAddr = null; remoteHost = null; localAddr = null; localName = null; remotePort = -1; localPort = -1; // IO设定 this.socket = socket; // 输入 inputBuffer.setInputStream(socket.getInputStream()); // 输出 outputBuffer.setOutputStream(socket.getOutputStream()); // 错误标志 error = false; keepAlive = true; // 保持连接的计数器 int keepAliveLeft = maxKeepAliveRequests; // 超时设置 int soTimeout = socket.getSoTimeout(); int oldSoTimeout = soTimeout; // 当前JIoEndpoint中的已经使用的Worker与总Worker的比例 int threadRatio = (endpoint.getCurrentThreadsBusy() * 100) / endpoint.getMaxThreads(); if (threadRatio > 75) {// 如果使用中的Worker比例高于75%,只保持连接1次 keepAliveLeft = 1; } if (soTimeout != oldSoTimeout) { try { socket.setSoTimeout(soTimeout); } catch (Throwable t) { log.debug(sm.getString("http11processor.socket.timeout"), t); error = true; } } // 是否被保持着连接 boolean keptAlive = false; while (started && !error && keepAlive) {// 循环处理请求 // Parsing the request header // 解析请求Header try { if (!disableUploadTimeout && keptAlive) { if (keepAliveTimeout > 0) { socket.setSoTimeout(keepAliveTimeout); } else if (soTimeout > 0) { socket.setSoTimeout(soTimeout); } } // 读取请求行 inputBuffer.parseRequestLine(); // 请求开始时间 request.setStartTime(System.currentTimeMillis()); keptAlive = true; if (!disableUploadTimeout) { socket.setSoTimeout(timeout); } // 读取Header inputBuffer.parseHeaders(); } catch (IOException e) { // 设置错误标志,跳出循环 error = true; break; } catch (Throwable t) { if (log.isDebugEnabled()) { log.debug(sm.getString("http11processor.header.parse"), t); } // 400 - 错误的请求 response.setStatus(400); error = true; } rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try { // 准备请求 prepareRequest(); } catch (Throwable t) { if (log.isDebugEnabled()) { log.debug(sm.getString("http11processor.request.prepare"), t); } response.setStatus(400); error = true; } // 设置是否请求存活 if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0) keepAlive = false; if (!error) { try { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); // adapter是org.apache.catalina.connector.CoyoteAdapter类的对象 adapter.service(request, response); if (keepAlive && !error) { // 判断是否有异常 error = response.getErrorException() != null || statusDropsConnection(response.getStatus()); } } catch (InterruptedIOException e) { error = true; } catch (Throwable t) { log.error(sm.getString("http11processor.request.process"), t); response.setStatus(500); error = true; } } // 结束请求 try { rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT); inputBuffer.endRequest(); } catch (IOException e) { error = true; } catch (Throwable t) { log.error(sm.getString("http11processor.request.finish"), t); response.setStatus(500); error = true; } try { rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT); outputBuffer.endRequest(); } catch (IOException e) { error = true; } catch (Throwable t) { log.error(sm.getString("http11processor.response.finish"), t); error = true; } if (error) { response.setStatus(500); } request.updateCounters(); rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); inputBuffer.nextRequest(); outputBuffer.nextRequest(); } rp.setStage(org.apache.coyote.Constants.STAGE_ENDED); // 回收 inputBuffer.recycle(); outputBuffer.recycle(); sslSupport = null; }
这里面需要重点说的是adapter.service(request, response);这一句,它对请求进行了进一步处理。这里的adapter是org.apache.catalina.connector.CoyoteAdapter类的对象,至于是哪里设定的这里就不详细介绍了,主要来看一下它的#service(org.apache.coyote.Request req, org.apache.coyote.Response res)方法。
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) throws Exception { // 对Coyote Request和Response进行封装 Request request = (Request) req.getNote(ADAPTER_NOTES); Response response = (Response) res.getNote(ADAPTER_NOTES); if (request == null) { // 重新创建封装的Coyote Request和Response对象 request = (Request) connector.createRequest(); request.setCoyoteRequest(req); response = (Response) connector.createResponse(); response.setCoyoteResponse(res); // 互相引用 request.setResponse(response); response.setRequest(request); req.setNote(ADAPTER_NOTES, request); res.setNote(ADAPTER_NOTES, response); req.getParameters().setQueryStringEncoding(connector.getURIEncoding()); } if (connector.getXpoweredBy()) { response.addHeader("X-Powered-By", "Servlet/2.5"); } boolean comet = false; try { req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName()); if (postParseRequest(req, request, res, response)) { // 调用Container继续请求 connector.getContainer().getPipeline().getFirst().invoke(request, response); if (request.isComet()) { if (!response.isClosed() && !response.isError()) { if (request.getAvailable()) { if (event(req, res, SocketStatus.OPEN)) { comet = true; res.action(ActionCode.ACTION_COMET_BEGIN, null); } } else { comet = true; res.action(ActionCode.ACTION_COMET_BEGIN, null); } } else { request.setFilterChain(null); } } } if (!comet) { response.finishResponse(); req.action(ActionCode.ACTION_POST_REQUEST, null); } } catch (IOException e) { ; } catch (Throwable t) { log.error(sm.getString("coyoteAdapter.service"), t); } finally { req.getRequestProcessor().setWorkerThreadName(null); // 回收 if (!comet) { request.recycle(); response.recycle(); } else { request.clearEncoders(); response.clearEncoders(); } } }
下面准备总结下之前的Tomcat请求处理过程,总结出一些宏观性的东西。
发表评论
-
出现java.lang.UnsupportedClassVersionError 错误的原因
2010-08-16 23:11 871出现java.lang.UnsupportedClassVer ... -
Tomcat请求处理(七) - Servlet实例的调用
2009-05-07 11:36 1131Tomcat请求处理中Servlet实例的调用是和Filter ... -
请求在Tomcat中传到了CoyoteAdapter的#service()方法中后,就要准备进入Pi
2009-05-07 11:35 1811首先,来看一下Servlet的载入过程。 具体是在org.ap ... -
Tomcat请求处理(五) -- 请求在容器间的流动
2009-05-07 11:34 1433请求在Tomcat中传到了CoyoteAdapter的#ser ... -
Tomcat请求处理(四) -- Request, Response, 和Pipeline
2009-05-07 11:33 12841. Request和Response 当处理请求的时候,To ... -
Tomcat请求处理(二) -- 请求处理框架
2009-05-07 11:30 991书接上文。 当Tomcat的Acceptor监听到有请求到来时 ... -
Tomcat请求处理(一) -- 服务器端口监听
2009-05-07 11:29 1401其实tomcat在哪个类中监听请求的代码很容易找到: 在org ... -
Tomcat启动部分源代码分析(五) -- 应用程序加载
2009-05-07 11:28 1199前面所叙述的tomcat启动 ... -
Tomcat启动部分源代码分析(四) -- 开启容器
2009-05-07 11:27 1205四. 开启容器 最后是Bootstrap#start()方法的 ... -
Tomcat启动部分源代码分析(三) -- 载入
2009-05-07 11:23 1195二. 载入 2. Bootstrap的#Bootstrap#l ... -
Tomcat启动部分源代码分析(二) -- 初始化
2009-05-07 11:20 1098二. 初始化 1. 首先是Bootstrap的#init()操 ... -
Tomcat启动部分源代码分析(一) -- 概览
2009-05-07 11:17 1432一. 概览 本文所涉及的Tomcat为6.0版本。 Tomca ... -
Tomcat的Session管理(二) - Session后台处理
2009-05-07 10:10 971Tomcat会开启一个后台线程每隔一段时间检查Session的 ... -
Tomcat的Session管理(一) - Session的生成
2009-05-07 10:02 1497Session对象的创建一般是源于这样的一条语句: Sessi ...
相关推荐
Coyote是Tomcat中的核心组件之一,主要负责处理HTTP请求和响应。它的设计目标是提供一个高性能、低级别的连接器,使得Tomcat可以高效地处理网络I/O操作。Coyote的设计模式采用了Java NIO(非阻塞I/O)技术,这使得它...
而Tomcat Coyote是Tomcat核心组件之一,它负责处理HTTP请求和响应,扮演着关键的角色。本文将深入探讨Tomcat Coyote.jar的内涵及其重要性。 Tomcat Coyote是Tomcat内部的一个子项目,它的主要任务是实现Servlet 3.1...
3. ** Coyote**:处理HTTP协议的连接器,负责接收和响应来自客户端的请求。 4. **Juli**:Tomcat的内置日志系统,用于记录服务器的活动和错误信息。 5. **Shared Libraries**:开发者可以将这些库放在特定的目录下,...
- **Connector**:处理HTTP请求和响应,是Tomcat与Web客户端通信的桥梁。 - ** Coyote**:Tomcat的HTTP/1.1连接器,负责监听和接受来自Web客户端的连接。 - **Juli**:Tomcat的日志框架,用于记录应用程序和...
3. ** Coyote**: Coyote是Tomcat的连接器组件,负责处理网络通信。它提供了一种机制,使得Tomcat能够监听和响应HTTP请求。 4. **Juli**: 这是Tomcat的日志系统,用于记录服务器的各种活动和错误信息。 5. **Common...
Tomcat Connectors,也称为Coyote,是Apache Tomcat服务器的核心组件之一,负责处理HTTP、AJP等网络协议的连接和通信。最新版本的`tomcat-connectors-1.2.40-src.zip`提供了这一关键模块的源代码,这对于开发者深入...
标签“tomcat-conne”虽然不完整,但显然指的是“Tomcat连接器”,这是Tomcat中负责处理网络连接的部分,包括两个主要组件:Coyote(处理HTTP/1.x协议)和Jasper(处理JSP)。Coyote提供了一个低级别的接口来处理...
Tomcat Connectors,通常也被称为Coyote,是Tomcat处理HTTP连接的组件,它负责监听来自客户端的请求,并将这些请求转发到Tomcat的内部处理引擎。Coyote提供了两种主要的连接器:JK和Apr,分别对应于Java的JNI接口和...
Adapter将Servlet容器的请求和响应对象转换为Coyote可以处理的格式,并将Coyote处理的结果转换回Servlet容器。在Tomcat中,每个Connector都有一个对应的Adapter。 2. **Protocol Handlers**:这些是处理特定网络...
- Catalina处理Servlet请求,Jasper编译并执行JSP,而Coyote负责与客户端进行网络通信。 2. **Tomcat 7.0.64版本特性**: - 改进了性能和稳定性,修复了多个安全漏洞。 - 支持Java EE 6 Web Profile,包括...
这些组件协同工作,接收请求,处理业务逻辑,并返回响应。 **3. 安装与配置** 在Windows环境下,用户可以通过解压"apache-tomcat-8.0.28-windows-x64.rar"文件来安装Tomcat。配置主要涉及设置环境变量,如CATALINA_...
Coyote处理网络I/O,提高了Tomcat的性能。 4. **Cluster**:如果配置了集群功能,Tomcat可以实现负载均衡和故障转移,以提高可用性和可扩展性。 5. **Manager**:这是一个Web应用程序管理工具,允许用户通过浏览器...
7. ** valves**:Valves是Tomcat处理请求的管道中的组件,它们按照一定的顺序处理每个请求。开发者可以通过自定义Valve来插入特定的行为。 8. ** Manager**:用于管理Web应用程序的生命周期,如部署、卸载和更新。`...
这些改进使得Tomcat在处理高并发请求时更加高效,同时也提升了开发者的体验。 总之,Apache Tomcat 8.0.30是64位Windows环境下的强大Java Web服务器,具备丰富的功能和良好的社区支持。正确配置和使用它,能为你的...
- ** Coyote**:处理HTTP连接的组件,负责监听端口并响应请求。 - **Jasper**:负责JSP编译成Servlet的引擎。 - **Commons Daemon**:用于Windows平台的服务控制。 5. **安全管理:** - **设置用户和角色**:...
2. **Tomcat架构**:Tomcat服务器主要由几个关键组件构成,包括Catalina(核心Servlet容器)、Jasper(JSP引擎)、 Coyote(HTTP/1.1协议处理)和Juli(日志系统)。这些组件协同工作,使得Tomcat能够处理Web应用...
对于开发者来说,Tomcat 8.5.69提供了丰富的API和工具,如JMX(Java Management Extensions)用于监控和管理服务器状态,以及 Catalina、Coyote和 Jasper等核心组件,它们分别处理Servlet容器、HTTP协议处理和JSP...
在Tomcat中,连接器主要负责处理来自网络的请求并将其传递给相应的Servlet容器,同时将Servlet的响应发送回客户端。关键组件包括 Coyote Connector(用于HTTP/HTTPS协议)和JMX(Java Management Extensions)支持,...
3. ** Coyote**:处理HTTP连接,是Tomcat接收和响应HTTP请求的组件。 4. **Juli**:这是Tomcat的日志系统,可以自定义日志输出格式和级别。 5. **Shared**:共享库,可以被所有Web应用程序使用。 在Apache Tomcat...
3. ** Coyote**:这是一个HTTP协议处理器,负责处理来自Web客户端的请求,并将响应返回给客户端。 4. **Juli**:这是Tomcat的内置日志框架,可以自定义配置以满足不同日志需求。 5. **Cluster**:在集群环境中,...