深入浅出Web容器-Tomcat原始码分析.ppt

上传人:max****ui 文档编号:15496847 上传时间:2020-08-13 格式:PPT 页数:52 大小:4.39MB
收藏 版权申诉 举报 下载
深入浅出Web容器-Tomcat原始码分析.ppt_第1页
第1页 / 共52页
深入浅出Web容器-Tomcat原始码分析.ppt_第2页
第2页 / 共52页
深入浅出Web容器-Tomcat原始码分析.ppt_第3页
第3页 / 共52页
资源描述:

《深入浅出Web容器-Tomcat原始码分析.ppt》由会员分享,可在线阅读,更多相关《深入浅出Web容器-Tomcat原始码分析.ppt(52页珍藏版)》请在装配图网上搜索。

1、深入淺出 Web 容器,Tomcat 原始碼分析,林信良 資深技術顧問 http:/openhome.cc caterpillaropenhome.cc,主題,Web 容器與 Servlet 從 HTTP 請求到 service() 在service()的前後 從 JSP 到 Servlet 自訂標籤處理,Web 容器與 Servlet,Web 容器與 Servlet,容器(Container)裝水的嗎?,別鬧了容器是個 Java 應用程式,介於 Servlet 與Web 伺服器之間,我管很多事,你不用認識 Web 伺服器,你只要認得我!,Web 容器與 Servlet,管很多事?哪些事啊?,

2、你沒想過 HTTP 那些麻煩的東西是怎麼變成 Java 物件的嗎?你以為 Servlet 中的 Request 與 Response 是怎麼來的?,Web 容器與 Servlet,看起來好像很複雜?,要了解我的內在確實不容易,那先從簡單的開始好了,知道一個Servlet是實作 Servlet 介面嗎?,.,來個簡化版的,if(servlets.get(servletName) = null) servlet = (Servlet) myClass.newInstance(); servlets.put(servletName, servlet); servlet.init(new Config

3、(myClass); else servlet = servlets.get(servletName); servlet.service( (ServletRequest) requestFacade, (ServletResponse) responseFacade);,public void destroy() for(Servlet servlet : servlets.values() servlet.destroy(); ,至少你要知道init()、service()與destroy(),Web 容器與 Servlet,你管的就是這些?,當然更多!不只ServletRequest、S

4、ervletResponse、ServletConfig、Servlet這些,對了!這個範例改寫自這邊 ,從 HTTP 請求到 service(),我實際上很強壯的啦.XD,從 HTTP 請求到 service(),當請求來到時是 Worker Thread 模式,public void run() while (running) / Allocate a new worker thread MasterSlaveWorkerThread workerThread = createWorkerThread(); / Accept the next incoming connection fro

5、m the server socket . Socket socket = acceptSocket(); workerThread.assign(socket); . ,沒原始碼沒真相.XD,採用Thread Pool.XD,從 HTTP 請求到 service(),接下來快轉一下來到了Http11Processor,我應該說過我負責建立Request與Response物件吧這個類別剖析HTTP並設定Request、Response,從 HTTP 請求到 service(),在Http11Processor的process()中,呼叫 adapter.service(),adapter.se

6、rvice(request, response);,再來的話這邊的request、response會被org.apache.catalina.connector套件中的Request、Response包裹起來.,WHY?,從 HTTP 請求到 service(),package org.apache.catalina.connector; public class Request implements HttpServletRequest ,package org.apache.catalina.connector; public class Response implements HttpS

7、ervletResponse ,從 HTTP 請求到 service(),再快轉一下Request與Response送到容器ContainerBase,最後來到StandardWrapper 你要注意一下loadServlet()方法 回憶 Servlet第一次被請求時會被載入 建立ServletConfig 執行init() 呼叫service(),public class StandardWrapper extends ContainerBase implements ServletConfig, Wrapper, NotificationEmitter ,if (classLoader

8、!= null) classClass = classLoader.loadClass(actualClass); else classClass = Class.forName(actualClass); . / Instantiate and initialize an instance of the servlet class try servlet = (Servlet) classClass.newInstance(); . try servlet.init(facade); servlet.service(req, res); ,facade 參考至實作 ServletConfig

9、 的實例 protected StandardWrapperFacade facade = new StandardWrapperFacade(this);,從 HTTP 請求到 service(),SingleThreadModel 怎麼實現?你可以自己找找看,喵好複雜Orz,已經省略了很多細節了你可以用這個流程來研究一些更深入的XD,在service()的前後,在service()的前後,你知道在Servlet前可以套用Filter吧!,好像是有這麼一回事XD,實現了Interceptor Filter模式,當我們又來到Servlet,在service()的前後,GenericServle

10、t類別 還實作了ServletConfig介面,將容器呼叫init()方法時所傳入的ServletConfig實例封裝起來 service()方法直接標示為abstract而沒有任何的實作 HTTP相關服務流程定義在HttpServlet的service()方法,在service()的前後,protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException String method = req.getMethod(); / 取得請求的方法 i

11、f (method.equals(METHOD_GET) / HTTP GET / 略. doGet(req, resp); / 略 . else if (method.equals(METHOD_HEAD) / HTTP HEAD / 略 . doHead(req, resp); else if (method.equals(METHOD_POST) / HTTP POST / 略 . doPost(req, resp); else if (method.equals(METHOD_PUT) / HTTP PUT / 略 . ,protected void doGet(HttpServlet

12、Request req, HttpServletResponse resp) throws ServletException, IOException String protocol = req.getProtocol(); String msg = lStrings.getString(http.method_get_not_supported); if (protocol.endsWith(1.1) resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); else resp.sendError(HttpServletR

13、esponse.SC_BAD_REQUEST, msg); ,在service()的前後,這實現了Template Method模式。,現在好像談過了幾個模式?Worker Thread、Interceptor Filter、Template Method,在service()的前後,來談一下Session怎麼建好了知道Session預設用Cookie儲存Session Id吧,餅乾我知道,在service()的前後,if (connector.getEmptySessionPath() ,public Session createSession(String sessionId) Sessi

14、on session = createEmptySession() session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis(); session.setMaxInactiveInterval(this.maxInactiveInterval); if (sessionId = null) sessionId = generateSessionId(); session.setId(sessionId); sessionCounter+; return (sess

15、ion); ,在service()的前後,你應該看一下org.apache.catalina. session.StandardSession,了解Session怎麼儲存好吧!接下來換個口味好了,Servlet 談好久了要來談一下 JSP 嗎? XD,從 JSP 到 Servlet,跟你下棋的其實是一隻貓.,從 JSP 到 Servlet,在我的世界中真正服務的只有Servlet沒有JSP,使用JSP不是比較簡單嗎? ,從 JSP 到 Servlet, SimpleJSP ,從 JSP 到 Servlet,package org.apache.jsp; import javax.servlet

16、.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent / 略. public void _jspInit() / 略. public void _jspDestroy() public void _jspService(HttpServletRequest reques

17、t, HttpServletResponse response) throws java.io.IOException, ServletException / 略. ,從 JSP 到 Servlet,從 JSP 到 Servlet,public abstract class HttpJspBase extends HttpServlet implements HttpJspPage / 略. public final void init(ServletConfig config) throws ServletException super.init(config); jspInit(); _j

18、spInit(); / 略. public final void destroy() jspDestroy(); _jspDestroy(); public final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException _jspService(request, response); / 略. ,從 JSP 到 Servlet,在之間宣告的程式碼,都將轉譯為Servlet中的類別成員或方法 之間所包括的內容,將被轉譯為Servlet

19、原始碼_jspService()方法中的內容 運算式元素中的運算式,會直接轉譯為out物件print()輸出時的指定內容,從 JSP 到 Servlet,隱含物件,其實就是_jspService()中的區域參考名稱,application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut();,原則上是因為都是轉成Servlet只不過角色職責不同這是另一個故事了,這麼說Se

20、rvlet作的到的,JSP都作的到 ,自訂標籤處理,我討厭義大利麵.,自訂標籤處理,別傻了.我只處理 Java 的東西每個標籤後面都還是 Java 物件在處理事情。XD,聽說使用 JSTL 就不用吃義大利麵 那是新的 HTML 標籤嗎?。XD,自訂標籤處理,自訂標籤處理,當JSP網頁中包括Simple Tag自訂標籤 ,在轉譯之後. 建立自訂標籤處理器實例。 呼叫標籤處理器的setJspContext()方法設定PageContext實例。 如果是巢狀標籤中的內層標籤,則還會呼叫標籤處理器的setParent()方法,並傳入外層標籤處理器的實例。 設定標籤處理器屬性(例如這邊是呼叫IfTag的

21、setTest()方法來設定)。 呼叫標籤處理器的setJspBody()方法設定JspFragment實例。 呼叫標籤處理器的doTag()方法。 銷毀標籤處理器實例。,cc.openhome.WhenTag _jspx_th_f_005fwhen_005f0 = new cc.openhome.WhenTag(); . _jspx_th_f_005fwhen_005f0.setJspContext(_jspx_page_context); _jspx_th_f_005fwhen_005f0.setParent(_jspx_parent); _jspx_th_f_005fwhen_005f0

22、.setTest(); _jspx_th_f_005fwhen_005f0.setJspBody(new Helper(); _jspx_th_f_005fwhen_005f0.doTag(); , $user.name登入成功 . ,這代表用Simple Tag實作標籤時,你的標籤處理器不能太肥大,自訂標籤處理,當JSP中遇到TagSupport自訂標籤時 嘗試從標籤池(Tag Pool)找到可用的標籤物件,如果找到就直接使用,如果沒找到就建立新的標籤物件。 呼叫標籤處理器的setPageContext()方法設定PageContext實例。 如果是巢狀標籤中的內層標籤,則還會呼叫標籤處理器

23、的setParent()方法,並傳入外層標籤處理器的實例。 設定標籤處理器屬性(例如這邊是呼叫IfTag的setTest()方法來設定)。 呼叫標籤處理器的doStartTag()方法,並依不同的傳回值決定是否執行本體或呼叫doAfterBody()、doEndTag()方法(稍後詳述)。 將標籤處理器實例置入標籤池中以便再度使用。,org.apache.taglibs.standard.tag.rt.core.WhenTag _jspx_th_c_005fwhen_005f0 = (org.apache.taglibs.standard.tag.rt.core.WhenTag) _005fj

24、spx_005ftagPool_005fc_005fwhen_0026_005ftest.get( org.apache.taglibs.standard.tag.rt.core.WhenTag.class); . _005fjspx_005ftagPool_005fc_005fwhen_0026_005ftest.reuse( _jspx_th_c_005fwhen_005f0);,這代表用TagSupport實作標籤時,必須注意是否要重置標籤處理器的狀態。 Pool的工作是由org.apache.jasper. runtime.TagHandlerPool完成,自訂標籤處理,自訂標籤處理,

25、public Tag get(Class handlerClass) throws JspException Tag handler = null; synchronized( this ) if (current = 0) handler = handlerscurrent-; return handler; try Tag instance = (Tag) handlerClass.newInstance(); public void reuse(Tag handler) synchronized( this ) if (current (handlers.length - 1) hand

26、lers+current = handler; return; ,自訂標籤處理,是啦!不過Tag File 會被我轉成 Simple Tag 的實作XD,我記得還有個 Tag File 的東西,package org.apache.jsp.tag.web; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class Errors_tag extends javax.servlet.jsp.tagext.SimpleTagSupport implements org.apache.jasper.runtime.JspSourceDependent ,最後,因為我代勞太多事了你以為有些行為很奇怪但其實看一下原始碼就什麼都知道了,我為什麼要了解這麼多細節,Thanks,52,林信良 http:/openhome.cc caterpillaropenhome.cc,

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!