您的位置:首页 > 运维架构 > 网站架构

Servlet的体系架构 以及 servlet的运行相关--笔记

2018-03-09 17:55 441 查看
    由于上一篇的侧重点在tomcat与servlet二者关系上面,所以虽然这出自同大牛的同一个博客,还是单独记叙一下。
    Servlet是一个接口类,其父类接口有: ServletConfig,ServletRequst;其祖父类接口有:ServeltContext,ServletResponse。   其中:ServletConfig 继承ServletContext,  ServletRequst 继承了ServletContext和ServletResponse。

           servlet规范就是基于这几个类运转的。    servlet主动关联的也有三个类:  分别是:ServletConfig,ServletRequest和ServletResponse。  这三个类都是通关过容器传递给Servelt,其中ServletConfig时候在Servlet初始化时就传给了Servlet。后两个是在请求到达的时候调用Servlet时传递过来的。
            ServletConfig是为了获取这个Servlet的一些配置属性,而这些配置属性可能在Servlet运行时被用到。   

            ServletContext的作用:   Servlet的运行模式时一个典型的“握手型的交互模式”运行模式。所谓“握手型的交互式”,就是两个模块为了交换数据通常都会准备一个交易场所,这个场景一直跟随这个交易过程直到交易完成为止。   这个交易场景的初始化是根据这次交易对象指定的参数来定制的,这些指定参数通常就是一个配置类。   因此交易场景就由ServletContext来描述,而定制的参数集合就由ServletConfig来描述。   而ServletRequest和  ServletResponse就是要交互的具体对象,它们通常都是作为交通工具来传递交互结果。 

            tomcat一接收到请求首先将会创建org.apache.coyot.Request和  org.apache.coyote.Response。这两个类是tomcat内部使用的描述一次请求和相应的信息类,都是轻量级的类,它们的作用就是在服务器收到请求后,经过简单解析将这个请求快速的分配给后续线程去处理,所以它们对象很小,很容易被jvm回收。一次请求对应的   Request和  Response 的类将会经过三次转化:    Socket  <===>  Http11Processer{org.apache.coyote.Request,org.apache.coyote.Request}  <==>(tomcat容器){Request,Response}  <==> (基于Servlet 的  Web应用){RequestFacade(HttpServletRequest实现类),ResponseFacade(HttpServletResponse的实现类)} 。 

      servelt的工作机制:

               当用户从浏览器向服务器发送了一个请求,通常会包含这些信息:   http://hostname:port/contextpath/servletpath,      hostname 和  port 是用来与服务器建立TCP连接,而后面的URL是用来选择服务器中那个子容器服务用户的请求。                                        服务器根据这个URL来正确定位Servlet容器是通过一个类:  org.apache.tomcat.util.http.Mapper,这个类保存了Tomcat的 container容器中的所有子容器的信息,当  org.apache.catalina.connector.Request类在进入Container容器之前,mapper将会根据这次请求的hostname和contextpath将host 和context容器设置到Request的mappingData属性中。  所以当Request进入Container容器之前,它要访问哪个子容器这时就已经确定了。       
                                        注意:   Mapper类中包含了containner所有子容器的信息,原因是  Mapper在初始化时,会将MapperListener类作为一个监听者加到整个Container容器中每个子容器中,这样只要任何一个容器发生变化,MapperListener都将会被通知,相应的保存容器关系的MapperListener的mapper的属性也会被修改。
                                    当请求到达最终的Wrapper容器后,还要完成一些步骤,必须要执行Filter链,以及要通知我们在web.xml中定义的listener。    之后请求到达最终的Servlet。    然后就是执行  Servlet的service方法,通常情况下,我们自定义的servlet并不是直接去实现javax.servlet.servet接口,而是去继承更简单的HttpServlet类或者GenericServlet类,我们可以由选择的覆盖相应方法去实现我们要完成的工作。                                        Servlet的却已经能够帮我们完成所有的工作了,但是现在的web应用很少有直接将交互页面都用servlet来实现,而是采用更加高效的MVC框架来实现,这些MVC框架的基本原理都是将所有的请求都映射到一个Servlet,然后去实现service方法,这个方法也就是MVC框架的入口。       当Servlet从Servlet容器中移除时,也就表明该Servlet的生命周期结束了,这时Servlet的destroy方法将被调用,做一些扫尾工作。 

              Session  与  Cookie:

                                Servlet能偶给我们提供两部分的数据:   一个是  在Servlet初始化时调用的  int方法时设置的ServletConfig,这个类基本上含有Servlet本身和Servlet所运行的Servlet容器中的基本信息。   ServletConfig的实际对象时StandardWrapperFacade。         还有一部分数据是由  ServletRequest类提供,它的实际对象是RequestFacade,主要是描述这次请求的HTTP协议的信息。 关于这一块还有一个让很多人迷惑的Session和   Cookie。
                                        Session  与  Cookie的作用都是为了保持访问用户与后端服务器的交互状态。   它们由各自的优点与缺陷,具有讽刺意味的是它们优点和它们的使用场景又是矛盾的。  
                                        有三种方式能够让Session正常工作:
                                                    1.基于URL  Path Parameter,默认就支持
                                                    2.基于Cookie,如果没有修改Context容器的cookies标识的话,默认也是支持的。
                                                   3.基于SSL,默认不支持,只有  connector.getAttribute("SSLEnabled")为TRUE  时才支持。
                                             第一种情况,当浏览器不支持Cookie功能时,浏览器会将用户的SessionCookieName重写到用户请求的URL参数中。它的传递格式如下:   /path/Servlet;name = vlaue;name2=value2?Name3= value3,其中“servlet;"后面的k-v 就是要传递的Path  Parameters,服务器会从这个Path  Parameters  中拿到用户配置的SessionCookieName.   关于这个  SessionCookieName,如果没有配置  session-config配置项,默认的SessionCookieName就是”JSESSIONID"。 接着,Request根据这个SessionCookieName到   Parameters拿到Session ID   并设置到  request.setRequestedSessionId()中。
                                               第二种情况:   客户端支持Cookie的话,Tomcat任然会解析Cookie中的Session ID,并会覆盖URL中的Session ID。 
                                                 第三种情况:  会根据  javax.servlet.requst.ssl_session属性值设置Session ID。 
                                        有了Session ID  服务器便可以创建HttpSession对象了。   第一次触发是通过   request.getSession()方法,如果当前的Session ID 还没有对应的HttpSession对象那么就创建一个新的,并将这个对象加到  org.apache.catalina.Manager的  sessions 容器中保存。   Manager类将管理所有Session的生命周期,Session过期将被回收,服务器关闭,Session将被序列化磁盘等。      
                                   session时序图  :  https://www.ibm.com/developerworks/cn/java/j-lo-servlet/image023.jpg

  整理自大牛博客:   https://www.cnblogs.com/licheng/p/6687326.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: