干货!从Tomcat执行流程了解jsp是如何被解析的,错误提示是哪里生成的。
一.关于Tomcat组成
先上张图:Tomcat组成:
1. Server:代表整个 servlet 容器,如Tomcat,JBoss之类的。 2. Service:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求。 3. Connector:一个Connector将在某个指定的端口上监听客户请求,并且将获得的请求交给Engine来处理,从Engine获得获得回应并且返 回给客户。例如上图中,我们监听了8080和8081端口。 4. Engine:Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名,当Engine获得一个请求时,它把该请求匹配到某个 Host上,然后把该请求交给该Host来处理,Engine有一个默认(default)虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该Host来 处理。 5. Host:代表一个虚拟主机,即针对一个域名的专门的处理器,每个虚拟主机下可以部署一个或者多个WebApp,每个 WebApp对应一个Context,每个Context都有一个Context Path,当Host获得一个请求时,将把该请求匹配到某个Context上,然后 把该请求交给该Context来处理。 6. Context:一个Context 对应于一个Web Application,一个Web Application 由一个或者多个Servlet组成,Context在创建的时候将根据 配置文件 $CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servlet类。 如果找到,则执行该类,获得请求的回应,并且返回。二. 配置文件 $CATALINA_HOME/conf/server.xml 文件说明
该文件描述了如何启动Tomcat Server<Server port="8005" shutdown="SHUTDOWN" debug="0"> ...... <Service name="Tomcat-Standalone"> <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8080" minProcessors="5" maxProcessors="75" acceptCount="100" enableLookups="true" redirectPort="8443" debug="0" connectionTimeout="20000" useURIValidationHack="false" disableUploadTimeout="true" /> <Engine name="Standalone" defaultHost="localhost" debug="0"> <Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context path="" docBase="mycontext" debug="0"/> <Context path="/wsota" docBase="wsotaProject" debug="0"/> Host> Engine> Service> Server>
三. Context的部署配置文件web.xml的说明
一个Context对应一个Web App,每个Web App 是由一个或者多个Servlet组成,当一个Web App被初始化的时候,它将用自己的ClassLoader对象载入 "部署配置文件web.xml"中的定义的每个servlet类,它首先载入在$CATALINA_HOME/conf/web.xml中部署的servlet类,然后载入在自己的Web App根目录下的WEB-INF/web.xml中部署的servlet类。 web.xml文件有两个部分:Servlet类定义和servlet映射定义,每个被载入的Servlet类都有一个名字,且被填入该Context的映射表中,和某种URL PATTERN 对应,当该Context获得请求的时候,将查询mapping table。找到被请求的servlet,并执行以获得请求回应。 下面是$CATALINA_HOME/conf/web.xml中的内容<web-app> <servlet> <servlet-name>defaultservlet-name> <servlet-class> org.apache.catalina.servlets.DefaultServlet servlet-class> <init-param> <param-name>debugparam-name> <param-value>0param-value> init-param> <init-param> <param-name>listingsparam-name> <param-value>trueparam-value> init-param> <load-on-startup>1load-on-startup> servlet> <servlet> <servlet-name>invokerservlet-name> <servlet-class>org.apache.catalina.servlets.InvokerServlet servlet-class> <init-param> <param-name>debugparam-name> <param-value>0param-value> init-param> <load-on-startup>2load-on-startup> servlet> <servlet> <servlet-name>jspservlet-name> <servlet-class>org.apache.jasper.servlet.JspServletservlet-class> <init-param> <param-name>logVerbosityLevelparam-name> <param-value>WARNINGparam-value> init-param> <load-on-startup>3load-on-startup> servlet> <servlet-mapping> <servlet-name>defaultservlet-name> <url-pattern>/url-pattern> servlet-mapping> <servlet-mapping> <servlet-name>invokerservlet-name> <url-pattern>/servlet/*url-pattern> servlet-mapping> <servlet-mapping> <servlet-name>jspservlet-name> <url-pattern>*.jspurl-pattern> servlet-mapping> ... ... ... ... web-app>
四. Tomcat Server处理一个http请求的过程
假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为”"的Context去处理)
7) path=”/wsota”的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser