- 浏览: 208151 次
- 性别:
- 来自: 福建省
文章分类
最新评论
-
c929833623:
...
Mysql JDBC驱动源码分析(Statement,ResultSet的创建)四 -
pythonlord:
顶 很有帮助,感谢楼主,好人一生平安
Mysql JDBC驱动源码分析(加载驱动)一 -
kiaonly:
代码有错误,我戳。
解释器模式(Interpreter)---java与模式(例子) -
wyzxzws:
小鸟学习了!
JAVA编码问题记录 -
xiaotao.2010:
写的不错! 弱弱说一句 建议使用URL二次转码, 这样可以避免 ...
JAVA编码问题记录
一,经过以上文章(JIoEndpoint$Worker#run)执行,就成功把socket交给tomcat中的coyote包执行
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler#process(Socket socket)
public boolean process(Socket socket) { Http11Processor processor = recycledProcessors.poll(); try { if (processor == null) { //创建Http11Processor processor = createProcessor(); } if (processor instanceof ActionHook) { //标记process started为ture意为开始处理 ((ActionHook) processor).action(ActionCode.ACTION_START, null); } if (proto.secure && (proto.sslImplementation != null)) { //支持ssl processor.setSSLSupport (proto.sslImplementation.getSSLSupport(socket)); } else { processor.setSSLSupport(null); } //继续往下处理 processor.process(socket); return false; } catch(java.net.SocketException e) { // SocketExceptions are normal Http11Protocol.log.debug (sm.getString ("http11protocol.proto.socketexception.debug"), e); } catch (java.io.IOException e) { // IOExceptions are normal Http11Protocol.log.debug (sm.getString ("http11protocol.proto.ioexception.debug"), e); } // Future developers: if you discover any other // rare-but-nonfatal exceptions, catch them here, and log as // above. catch (Throwable e) { // any other exception or error is odd. Here we log it // with "ERROR" level, so it will show up even on // less-than-verbose logs. Http11Protocol.log.error (sm.getString("http11protocol.proto.error"), e); } finally { // if(proto.adapter != null) proto.adapter.recycle(); // processor.recycle(); if (processor instanceof ActionHook) {//设置started为false表示处理完毕 ((ActionHook) processor).action(ActionCode.ACTION_STOP, null); } recycledProcessors.offer(processor); } return false; }
在创建Http11Processor的时候,进行了一系列的对象的初始化如下:
ublic Http11Processor(int headerBufferSize, JIoEndpoint endpoint) { this.endpoint = endpoint; //org.apache.coyote.Request request = new Request(); //输入流 inputBuffer = new InternalInputBuffer(request, headerBufferSize); request.setInputBuffer(inputBuffer); //org.apache.coyote.Response response = new Response(); response.setHook(this); //输出流 outputBuffer = new InternalOutputBuffer(response, headerBufferSize); response.setOutputBuffer(outputBuffer); request.setResponse(response); initializeFilters(); // Cause loading of HexUtils int foo = HexUtils.DEC[0]; }
Http11Processor#process(Socket socket)
public void process(Socket socket) throws IOException { RequestInfo rp = request.getRequestProcessor(); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // Set the remote address remoteAddr = null; remoteHost = null; localAddr = null; localName = null; remotePort = -1; localPort = -1; // Setting up the I/O this.socket = socket; //对scoket流进行设置处理 inputBuffer.setInputStream(socket.getInputStream()); outputBuffer.setOutputStream(socket.getOutputStream()); // Error flag error = false; keepAlive = true; // 连接的计数器 int keepAliveLeft = maxKeepAliveRequests; //超时设置 int soTimeout = socket.getSoTimeout(); int oldSoTimeout = soTimeout; // 当前JIoEndpoint中的已经使用的Worker与总Worker的比例 int threadRatio = (endpoint.getCurrentThreadsBusy() * 100) / endpoint.getMaxThreads(); // 如果使用中的Worker比例高于75%,只保持连接1次 if (threadRatio > 75) { 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 try { if (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); } //解析头部文件 inputBuffer.parseHeaders(); } catch (IOException e) { error = true; break; } catch (Throwable t) { if (log.isDebugEnabled()) { log.debug(sm.getString("http11processor.header.parse"), t); } // 400 - Bad Request response.setStatus(400); error = true; } if (!error) { // Setting up filters, and parse some request headers rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try { //开始准备请求,就是在里面把需要的信息设置进需要处理的对象inputbuffer outputbuffer,request,response等 prepareRequest(); } catch (Throwable t) { if (log.isDebugEnabled()) { log.debug(sm.getString("http11processor.request.prepare"), t); } // 400 - Internal Server Error response.setStatus(400); error = true; } } if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0) keepAlive = false; // Process the request in the adapter if (!error) { try { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); // adapter是 org.apache.catalina.connector.CoyoteAdapter类的对象 //这里面还对coyote.Request/Response转换成 //org.apache.catalina.connector.Request/Response //这一步是请求的下一步执行 adapter.service(request, response); // Handle when the response was committed before a serious // error occurred. Throwing a ServletException should both // set the status to 500 and set the errorException. // If we fail here, then the response is likely already // committed, so we can't try and set headers. if(keepAlive && !error) { // Avoid checking twice. error = response.getErrorException() != null || statusDropsConnection(response.getStatus()); } } catch (InterruptedIOException e) { error = true; } catch (Throwable t) { log.error(sm.getString("http11processor.request.process"), t); // 500 - Internal Server Error response.setStatus(500); error = true; } } // Finish the handling of the request try { rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT); // If we know we are closing the connection, don't drain input. // This way uploading a 100GB file doesn't tie up the thread // if the servlet has rejected it. if(error) inputBuffer.setSwallowInput(false); //结束请求 inputBuffer.endRequest(); } catch (IOException e) { error = true; } catch (Throwable t) { log.error(sm.getString("http11processor.request.finish"), t); // 500 - Internal Server Error 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 there was an error, make sure the request is counted as // and error, and update the statistics counter if (error) { response.setStatus(500); } request.updateCounters(); rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); // Don't reset the param - we'll see it as ended. Next request // will reset it // thrA.setParam(null); // Next request inputBuffer.nextRequest(); outputBuffer.nextRequest(); } rp.setStage(org.apache.coyote.Constants.STAGE_ENDED); // Recycle //对流进行回收 inputBuffer.recycle(); outputBuffer.recycle(); this.socket = null; // Recycle ssl info sslSupport = null; }
接下去对这一步进行详解adapter.service(request, response);
org.apache.catalina.connector.CoyoteAdapter#service对org.apache.coyote.Request/org.apache.coyote.Response进行封装成org.apache.catalina.connector.Request/Response
/** * Service method. */ 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); if (request == null) { 进行封装成connector的reqeust.. // Create objects request = (Request) connector.createRequest(); request.setCoyoteRequest(req); response = (Response) connector.createResponse(); response.setCoyoteResponse(res); // Link objects request.setResponse(response); response.setRequest(request); // Set as notes req.setNote(ADAPTER_NOTES, request); res.setNote(ADAPTER_NOTES, response); // Set query string encoding req.getParameters().setQueryStringEncoding (connector.getURIEncoding()); } if (connector.getXpoweredBy()) { response.addHeader("X-Powered-By", "Servlet/2.5"); } boolean comet = false; try { // Parse and set Catalina and configuration specific // request parameters req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName()); //这里面有对sessionid的处理,以后详解 if (postParseRequest(req, request, res, response)) { // Calling the container //运用pipeline以及valve,使request/response在容器间处理,,,重点详解这一步 connector.getContainer().getPipeline().getFirst().invoke(request, response); if (request.isComet()) { if (!response.isClosed() && !response.isError()) { if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) { // Invoke a read event right away if there are available bytes 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 { // Clear the filter chain, as otherwise it will not be reset elsewhere // since this is a Comet request 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); // Recycle the wrapper request and response if (!comet) { request.recycle(); response.recycle(); } else { // Clear converters so that the minimum amount of memory // is used by this processor request.clearEncoders(); response.clearEncoders(); } } }
发表评论
-
Nginx1.1实现Resin4集群
2011-10-17 17:56 7285一,web服务器小论 以前的公司使用的web服务器是to ... -
Apache实现Tomcat集群
2010-06-08 20:14 1428一,配置介绍 1,linux 2,tomcat6. ... -
Tomcat源码---容器生命周期管理(Lifecycle)一
2010-03-31 11:12 4465一,tomcat中每一个容器 ... -
Tomcat源码---Session的分析一
2010-03-29 11:31 3842一,前面看了大致的tomcat的请求/响应,接下来的文章对to ... -
Tomcat源码---响应处理五
2010-03-25 16:01 1862一,响应工作我们应该从CoyoteAdapter#servic ... -
Tomcat源码---请求处理四(2)
2010-03-25 15:34 1613对以上的StandardWrapperValve#invok ... -
Tomcat源码---请求处理四(1)
2010-03-25 11:08 1642一,现在到了StandardWrapperValve# ... -
Tomcat源码---请求处理三
2010-03-25 10:39 1368一,这一章节主要讲request与response通过管道,阀 ... -
Tomcat源码---请求处理(接收,线程分配)一
2010-03-24 14:34 2826一,在以上文章中tomcat启动已经完毕,接着要做的是消息的请 ... -
Tomcat源码---容器启动六(4)
2010-03-24 11:14 1469现在容器已经启动成功的StanderService#start ... -
Tomcat源码---容器启动六(3)
2010-03-24 10:48 2291一,容器已经启动到部暑文件(webapps),接下去是Stan ... -
Tomcat源码---容器启动六(2)
2010-03-23 16:42 1502super.start()--->org.apach ... -
Tomcat源码---容器启动六(1)
2010-03-22 16:02 1528一,完成了以上的初始化工作,现在进行容器的启动工作由 ... -
Tomcat源码---初始化容器五
2010-03-22 15:03 1827一,上面文章完成了对server.xml载入以及解析,现在主要 ... -
Tomcat源码---载入相应的资源及解析四(2)
2010-03-19 16:47 1513一,根据以上文章所讲的对server.xml的解析作下简单的分 ... -
Tomat源码---载入相应的资源及解析四(1)
2010-03-19 16:22 1404一,进行了以上的类包加载后,现在主要的工作是载入server. ... -
Tomcat源码---启动.初始化(加载类包)分析三
2010-03-19 15:37 2224一,启动 Tomcat是从org.apache.catali ... -
Tomcat的简单了解二
2010-03-19 14:40 1836在查看源代码时,在网上找了一系列的文章,在些作详解: ... -
Tomcat中server.xml的配置分析一
2010-03-19 14:07 1818最近查看了tomcat6的源代码,了解了里面的大概 ...
相关推荐
9. **错误处理与日志系统**:Tomcat使用自定义的日志框架,源码中`logging`目录下的类定义了如何记录和处理错误信息。 10. **网络编程**:Tomcat底层使用NIO(非阻塞I/O)和BIO(阻塞I/O)模型,这在`java/org/...
通过对`apache-tomcat-9.0.8-src`源码的深入研究,我们可以了解到Tomcat如何处理网络请求,怎样管理Web应用,以及如何实现各种高级特性。这对于开发者来说是一份宝贵的学习资料,可以帮助他们更好地优化应用程序,...
`mod_jk`负责在HTTPD服务器端接收请求,然后将这些请求转发到Tomcat,而`jk`则在Tomcat端处理这些请求,并返回响应给`mod_jk`,再由`mod_jk`转发给客户端。 2. **版本兼容性** `tomcat-connectors-1.2.48-src`特别...
2. **HTTP链接**:Tomcat作为HTTP服务器,处理HTTP请求和响应。它通过解析HTTP协议来与客户端进行通信。lib目录下的httpcore.jar和httpclient.jar包含Apache HttpClient库,提供了高效的HTTP协议处理能力,使得...
这个压缩包包含了两个版本的Tomcat源码:apache-tomcat-7.0.62-src和apache-tomcat-6.0.39-src,这两个版本分别代表了Tomcat在不同时间点的开发状态和技术特性。 首先,让我们从Apache Tomcat 6.0.39源码开始分析。...
2. ** Coyote**:负责处理HTTP请求和响应。Coyote是Tomcat的网络连接器,它包含一个或多个处理器,如`Http11Processor`,这些处理器处理HTTP协议细节。`org.apache.coyote`包下的类与网络通信密切相关。 3. ** ...
通过分析源码,开发者可以学习到如何遵循Servlet和JSP规范进行服务器端开发,理解Tomcat如何处理请求、管理会话、调度线程等。此外,源码还便于开发者修复已知问题,优化性能,或添加特定的功能。 总之,`tomcat6-...
深入研究Tomcat源码有助于开发者理解Web应用服务器的内部运作机制,提升系统设计和优化能力,同时也有助于自定义扩展和调试,实现更高效、安全的Web服务。 总之,从Tomcat 6.0到9.0,每个版本都带来了技术的进步和...
7. **线程池**:Tomcat使用线程池模型处理并发请求,提高性能和响应速度。线程池大小可以在`server.xml`中调整。 8. **安全管理**:Tomcat支持角色基础的访问控制(RBAC),可以设置不同用户的访问权限,通过`...
3-5Tomcat响应请求源码与nio处理请求源码实现.mp4
在源码分析中,开发者可以深入了解Tomcat如何处理请求、响应,以及它如何管理Web应用程序的生命周期。此外,对于性能优化、自定义行为或解决特定问题,源码阅读也是非常有价值的。 7.0.59和7.0.69之间的差异可能...
对于初次接触Tomcat源码的开发者,可以从阅读`src/main/java`目录下的源码开始,重点关注`org.apache.catalina`包下的类,以及`org.apache.coyote`和`org.apache.jasper`等包。同时,`conf/server.xml`是配置整个...
Eclipse是一个广泛使用的Java集成开发环境(IDE),它支持直接导入和管理Tomcat源码。在Eclipse中,开发者可以通过导入“Existing Projects into Workspace”来加载Tomcat源码。然后,可以利用Eclipse的强大功能,如...
Tomcat作为Servlet和JSP容器,负责处理HTTP请求,解析请求到相应的Servlet或JSP页面,执行其中的Java代码,并将结果返回给客户端。 Apache Tomcat 6.0.37 版本是在2013年发布的一个稳定版本,支持Java EE 5规范。这...
通过研究Tomcat源码,开发者可以了解到HTTP请求的处理流程、Servlet容器的工作方式、以及如何高效地管理Web应用。此外,了解Tomcat源码还可以帮助开发者借鉴其设计模式和架构,以便在日常开发中构建更稳定、高效的...
在Tomcat中,Servlet用于处理HTTP请求并返回响应。 - **JSP**:JavaServer Pages是Java平台上的动态网页技术,允许开发者将HTML代码与Java代码混合编写,以实现动态内容的生成。 2. **Tomcat的结构**: - **conf*...
源码解析部分则是对Tomcat源码的深度剖析,涵盖了关键类和方法的作用、设计模式的运用以及性能优化技巧。这有助于开发者理解Tomcat内部的工作流程,例如,如何处理HTTP请求的生命周期,以及线程池是如何调度和管理的...
7. **Eclipse集成**:在Eclipse中导入Tomcat源码,可以方便地进行调试、代码分析和自定义修改。这需要配置Tomcat插件,设置源代码路径,以及正确配置项目的构建路径。 8. **部署与调试**:在Eclipse中如何部署Web...
深入学习jakarta-tomcat-connectors-1.2.15-src源码,可以提升对Tomcat工作流程的理解,包括请求的接收、处理、响应过程,以及如何通过连接器优化服务器性能。这对于进行性能调优、定制化开发或者排查系统问题都至关...
Apache Tomcat源码分析 Apache Tomcat是一款广泛应用的开源Java Servlet容器,它是Java EE Web应用程序的标准实现。Tomcat源码的深入理解对于Java Web开发者来说是至关重要的,它可以帮助我们了解HTTP服务器的工作...