Servlet

1.Tomcat与Servlet容器

TomCat->Container容器->Engine->Host->Servlet容器->Context->Wrapper

真正管理Servlet容器的是Context容器,一个Context对应一个Web工程。

2.TomCat容器启动过程

Tomcat7 增加了一个启动类 org.apache.catalina.startup.Tomcat

1 Tomcat tomcat = getTomcatInstance();
2 File appDir = new File(getBuildDirectory(), "webapps/examples");
3 tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
4 tomcat.start();

创建了一个Tomcat实例,新增了一个Web应用,然后启动Tomcat。

 1 public Context addWebapp(Host host, String url, String path){
 2     silence(url);
 3     Context ctx = new StandardContext();
 4     ctx.setPath(url);
 5     ctx.setDocBase(path);
 6     if(defaultRealm == null){
 7         initSimpleAuth();
 8     }
 9     ctx.setRealm(defaultRealm);
10     ctx.addLifecycleListener(new DefaultWebXmlListener());
11     ContextConfig ctxCfg = new ContextConfig();
12     ctx.addLifecycleListener(ctxCfg);
13     ctxCfg.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML");
14     if(host == null){
15         getHost().addChild(ctx);
16     }else{
17         host.addChild(ctx);
18     }
19     return ctx;
20 }

 

addWebapp方法中会新建一个Context    //一个Web应用对应一个Context容器

为Context配置了 应用的路径 并 指定了配置文件 ContextConfig //负责整个Web应用配置的解析工作

最后将这个Context加到父容器Host中。

3.Web应用的初始化过程

web应用的初始化工作是在ContextConfig中的configureStart方法中实现的,初始化主要是解析web.xml文件,这个文件描述了一个web应用的关键信息,也是一个web应用的入口。

Tomcat首先去找globalWebXml 然后去找hostWebXml 再去找WEB-INF/web.xml 

并将web.xml解析成相应的属性保存在WebXml对象中,接下来将WebXml对象中的属性设置到Context容器中,在这一步骤创建Servlet、filter、listener等。

这里WebXml的configureContext方法会将Servlet包装成Context中的StandardWrapper 并传入Context中

除Servelet包装成StandardWrapper并作为子容器添加到Context外,其他web.xml属性都被解析到Context中

一个web应用对应一个Context容器,容器的配置属性由应用的web.xml指定。

PS:web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。

4.创建Servlet实例

前面Servelet被包装成StandardWrapper并作为子容器添加到Context容器中,但是它还没有被实例化。

如果web.xml中Servlet的load-on-startup配置项大于0,那么在Context容器启动时就会被实例化。

通过StandardWrapper的initServlet方法 初始化Servlet 该方法调用Servlet的init方法,同时将包装了StandardWrapper对象的StandardWrapperFacade 传给Servlet,这样Servlet对象就初始化完成了。

5.Servlet体系结构

与Servlet主动关联的三个类,ServletConfig ServletRequest ServletResponse

ServletConfig是在Servlet初始化的时候传递给Servlet的 //即上述的StandardWrapperFacade ,而后两者是在请求到达时调用Servlet传递过来的

ServletConfig中包含一些获取Servlet的配置属性的方法。这些配置属性可能在Servlet运行时被用到。

6.Servlet如何工作

浏览器发往服务器的一个url  http://hostname:port/contextpath/servletpath

hostname与port用来与服务器建立TCP连接,后面的URL用来选择服务器中哪个子容器服务用户的请求。

TomCat 7中的org.apache.tomcat.util.http.mapper这个类,保存了Tomcat的Container容器中的所有子容器的信息,在org.apache.catalina.connector.Request类进入Container容器之前,Mapper将会根据这次请求的hostname和contextpath将host和context容器设置到Request的mappingData属性中,所以当Request进入Container容器之前,对于要访问哪个子容器就已经确定了。接下来根据url来匹配在每个Servlet/*此处指的是Context中的各个Wrapper*/ 中配置的<url-pattern>

7.关于URL匹配

<url-pattern>的解析规则,对Servlet和Filter是一样的,匹配的规则有入下三种:

  • 精确匹配:如/foo.htm只会匹配foo.htm这个URL
  • 路径匹配:如/foo/*会匹配以foo为前缀的URL
  • 后缀匹配:如*.htm会匹配所有以.htm为后缀的URL

Servlet的匹配规则,精确匹配>路径匹配(更精确的优先)>后缀匹配     一次请求只会成功匹配到一个Servlet

Filter的匹配规则,只要匹配成功,这些Filter都会在请求链上被调用

 


 才能这种东西 本来就是靠自己挖掘创造的 我也不是什么天才 我只是比任何人都拼命工作 一步一个脚印走过来了 等我回头一看 背后没有一个身影 那帮懒惰的人在山脚念叨着 谁叫那家伙是天才 开什么玩笑 我最讨厌悠哉悠哉长大的慢性子 比我有时间 有精力 感情丰富的人 为什么比我懒惰 那就给我啊 要把这些东西都浪费掉的话 就通通给我 我还有很多很多想创造的东西 给我啊--------摘自《legal high II》 与诸君共勉


 

 

posted @ 2017-07-05 18:01  丨核桃牛奶  阅读(123)  评论(0编辑  收藏  举报