深刻拆解Tomcat & Jetty-学习笔记(1)模块一之必备基础

模块一 必备基础

01 HTTP协议必知必会的知识

http请求过程

  1. 用户经过浏览器进行了一个操做,好比输入网址并回车,或者是点击连接,接着浏览器获取了这个事件。
  2. 浏览器向服务端发出 TCP 链接请求。
  3. 服务程序接受浏览器的链接请求,并通过 TCP 三次握手创建链接。
  4. 浏览器将请求数据打包成一个 HTTP 协议格式的数据包。
  5. 浏览器将该数据包推入网络,数据包通过网络传输,最终达到端服务程序。
  6. 服务端程序拿到这个数据包后,一样以 HTTP 协议格式解包,获取到客户端的意图。
  7. 得知客户端意图后进行处理,好比提供静态文件或者调用服务端程序得到动态结果。
  8. 服务器将响应结果(多是 HTML 或者图片等)按照 HTTP 协议格式打包。
    1. 服务器将响应数据包推入网络,数据包通过网络传输最终达到到浏览器。
  9. 浏览器拿到数据包后,以 HTTP 协议的格式解包,而后解析数据,假设这里的数据是 HTML。
  10. 浏览器将 HTML 文件展现在页面上。
http请求响应实例

请求:请求行,请求头,请求体 响应:状态行,响应报文,报文主体java

cookie和session

Cookie 本质上就是一份存储在用户本地的文件,里面包含了每次请求中都须要传递的信息程序员

Session 能够理解为服务器端开辟的存储空间,里面保存了用户的状态web

当用户请求到来时,服务端能够把用户的请求和用户的 Session 对应起来。那么 Session 是怎么和请求对应起来的呢?答案是经过 Cookie,浏览器在 Cookie 中填充了一个 Session ID 之类的字段用来标识请求。spring

关于restful风格的理解

将网络上的信息实体看做是资源,能够是图片、文件、一个服务...资源用URI统一标识,URI中没有动词哦,这是由于它是资源的标识,那怎么操做这些资源呢,因而定义一些动做:GET、POST、PUT和DELETE。经过URI+动做来操做一个资源。浏览器

关于Http无状态的请求的理解

所谓的无状态说的是,为了完成一个操做,请求里包含了全部信息,你能够理解为服务端不须要保存请求的状态,也就是不须要保存session,没有session的好处是带来了服务端良好的可伸缩性,方便failover,请求被LB转到不一样的server实例上没有差异。从这个角度看,正是有了REST架构风格的指导,才有了HTTP的无状态特性,顺便提一下,REST和HTTP1.1出自同一人之手。可是理想是丰满的,现实是骨感的,为了方便开发,大多数复杂的Web应用不得不在服务端保存Session。为了尽可能减小Session带来的弊端,每每将Session集中存储到Redis上,而不是直接存储在server实例上。服务器

关于http长链接的理解以及1.0和1.1和2.0的区别

在 HTTP/1.0 时期,每次 HTTP 请求都会建立一个新的 TCP 链接,请求完成后以后这个 TCP 链接就会被关闭。这种通讯模式的效率不高 HTTP/1.1 中,引入了 HTTP 长链接的概念,使用长链接的 HTTP 协议,会在响应头加入 Connection:keep-alive。这样当浏览器完成一次请求后,浏览器和服务器之间的 TCP 链接不会关闭,再次访问这个服务器上的网页时,浏览器会继续使用这一条已经创建的链接,也就是说两个请求可能共用一个 TCP 链接。 HTTP/1.1中的长链接依然没有解决 head of line blocking 的问题,后面的链接必须等待前面的返回了才可以发送,这个问题直到HTTP/2.0采起二进制分帧编码方式才完全解决。restful

02.servlet规范和servlet容器

servlet和servlet容器的关系

Servlet 本质上是一个接口,实现了 Servlet 接口的业务类也叫 Servlet。Servlet 接口实际上是 Servlet 容器跟具体 Servlet 业务类之间的接口。Servlet 接口跟 Servlet 容器这一整套规范叫做 Servlet 规范,而 Servlet 规范使得程序员能够专一业务逻辑的开发,同时 Servlet 规范也给开发者提供了扩展的机制 Filter 和 Listener。cookie

public interface Servlet {
    void init(ServletConfig config) throws ServletException;
    
    ServletConfig getServletConfig();
    
    void service(ServletRequest req, ServletResponse res)throws ServletException, IOException; String getServletInfo();
    
    void destroy();
}
复制代码
Servlet容器工程流程

  1. 当客户请求某个资源时,HTTP 服务器会用一个 ServletRequest 对象把客户的请求信息封装起来
  2. 而后调用 Servlet 容器的 service 方法,Servlet 容器拿到请求后,根据请求的 URL 和 Servlet 的映射关系,找到相应的 Servlet
  3. 若是 Servlet 尚未被加载,就用反射机制建立这个 Servlet,并调用 Servlet 的 init 方法来完成初始化
  4. 接着调用 Servlet 的 service 方法来处理请求,把 ServletResponse 对象返回给 HTTP 服务器,HTTP 服务器会把响应发送给客户端。
什么是ServletContext

Servlet 规范里定义了 ServletContext 这个接口来对应一个 Web 应用。Web 应用部署好后,Servlet 容器在启动时会加载 Web 应用,并为每一个 Web 应用建立惟一的 ServletContext 对象。你能够把 ServletContext 当作是一个全局对象,一个 Web 应用可能有多个 Servlet,这些 Servlet 能够经过全局的 ServletContext 来共享数据,这些数据包括 Web 应用的初始化参数、Web 应用目录下的文件资源等。因为 ServletContext 持有全部 Servlet 实例,你还能够经过它来实现 Servlet 请求的转发。网络

什么是Filter

Filter 是过滤器,这个接口容许你对请求和响应作一些统一的定制化处理,好比你能够根据请求的频率来限制访问,或者根据国家地区的不一样来修改响应内容。过滤器的工做原理是这样的:Web 应用部署完成后,Servlet 容器须要实例化 Filter 并把 Filter 连接成一个 FilterChain。当请求进来时,获取第一个 Filter 并调用 doFilter 方法,doFilter 方法负责调用这个 FilterChain 中的下一个 Filter。session

什么是Listener

Listener 是监听器,这是另外一种扩展机制。当 Web 应用在 Servlet 容器中运行时,Servlet 容器内部会不断的发生各类事件,如 Web 应用的启动和中止、用户请求到达等。 Servlet 容器提供了一些默认的监听器来监听这些事件,当事件发生时,Servlet 容器会负责调用监听器的方法。固然,你能够定义本身的监听器去监听你感兴趣的事件,将监听器配置在web.xml中。好比 Spring 就实现了本身的监听器,来监听 ServletContext 的启动事件,目的是当 Servlet 容器启动时,建立并初始化全局的 Spring 容器。

Filter和Listener以及(intercepter )拦截器的关系

1.Filter是Servlet规范的一部分,是Servlet容器Tomcat实现的。 2.Intercepter是Spring发明的。 3.它们的执行顺序是: Filter.doFilter(); HandlerInterceptor.preHandle(); Controller; HandlerInterceptor.postHandle(); DispatcherServlet 渲染视图 HandlerInterceptor.afterCompletion(); Filter.doFilter(); Servlet方法返回;

Filter 是干预过程的,它是过程的一部分,是基于过程行为的。 Listener 是基于状态的,任何行为改变同一个状态,触发的事件是一致的。

servlet容器和Spring容器和SpringMVC容器之间的关系

Servlet容器,是用于管理Servlet生命周期的。 Spring容器,是用于管理Spring Bean生命周期的,如service,dao等。 SpringMVC容器,适用于管理SpringMVC Bean生命周期的,如Controller,ViewResovler等。

Tomcat/Jetty启动,对于每一个WebApp,依次进行初始化工做:

  1. 对每一个WebApp,都有一个WebApp ClassLoader,和一个ServletContext

  2. ServletContext启动时,会扫描web.xml配置文件,找到Filter、Listener和Servlet配置

  3. 若是Listener中配有spring的ContextLoaderListener

    • ContextLoaderListener就会收到webapp的各类状态信息。
    • 在ServletContext初始化时,ContextLoaderListener也就会将Spring IOC容器进行初始化,管理Spring相关的Bean。
    • ContextLoaderListener会将Spring IOC容器存放到ServletContext中
  4. 若是Servlet中配有SpringMVC的DispatcherServlet

    • DispatcherServlet初始化时(其一次请求到达初始化,延迟加载)。
    • 其中,DispatcherServlet会初始化本身的SpringMVC容器,用来管理Spring MVC相关的Bean。
    • SpringMVC容器能够经过ServletContext获取Spring容器,并将Spring容器设置为本身的根容器。而子容器能够访问父容器,从而在Controller里能够访问Service对象,可是在Service里不能够访问Controller对象。

附一个描述关系的图 blog.csdn.net/zhanglf02/a…

纯手工打造一个Servlet

基本步骤
  1. 下载并安装 Tomcat。
  2. 编写一个继承 HttpServlet 的 Java 类。
  3. 将 Java 类文件编译成 Class 文件。
  4. 创建 Web 应用的目录结构,并配置web.xml。
  5. 部署 Web 应用。
  6. 启动 Tomcat。
  7. 浏览器访问验证结果。
  8. 查看 Tomcat 日志。
目录介绍
  1. /bin:存放 Windows 或 Linux 平台上启动和关闭 Tomcat 的脚本文件。
  2. /conf:存放 Tomcat 的各类全局配置文件,其中最重要的是server.xml。
  3. /lib:存放 Tomcat 以及全部 Web 应用均可以访问的 JAR 文件。
  4. /logs:存放 Tomcat 执行时产生的日志文件。
  5. /work:存放 JSP 编译后产生的 Class 文件。
  6. /webapps:Tomcat 的 Web 应用目录,默认状况下把 Web 应用放在这个目录下。
日志目录介绍

这里简要介绍各个文件的含义。

  1. catalina.xxx.log主要是记录 Tomcat 启动过程的信息,在这个文件能够看到启动的 JVM 参数以及操做系统等日志信息。
  2. catalina.outcatalina.out是 Tomcat 的标准输出(stdout)和标准错误(stderr),这是在 Tomcat 的启动脚本里指定的,若是没有修改的话 stdout 和 stderr 会重定向到这里。因此在这个文件里能够看到咱们在MyServlet.java程序里打印出来的信息:MyServlet 在处理 get 请求…
  3. localhost.xx.log主要记录 Web 应用在初始化过程当中遇到的未处理的异常,会被 Tomcat 捕获而输出这个日志文件。
  4. localhost_access_log.xx.txt存放访问 Tomcat 的请求日志,包括 IP 地址以及请求的路径、时间、请求协议以及状态码等信息。
  5. manager.xxx.log/host-manager.xxx.log存放 Tomcat 自带的 Manager 项目的日志信息。
web.xml配置和 @WebServlet注解配置

如下两种配置均可以将servlet注给servlet容器

<servlet>      
     <servlet-name>myServlet</servlet-name>      
     <servlet-class>MyServlet</servlet-class>   
 </servlet>    
 <servlet-mapping>     
     <servlet-name>myServlet</servlet-name>   
     <url-pattern>/myservlet</url-pattern>   
 </servlet-mapping>
复制代码
@WebServlet("/myAnnotationServlet")
public class AnnotationServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //TODO
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //TODO

}  
复制代码
注意

Servlet接口中定义了service方法,没有doGet/doPost。HttpServlet是一个实现类,实现了service方法,同时留出了doGet/doPost方法让程序员来实现。

备注

本文是我我的学习了李号双老师的专栏课程以后,结合专栏文章和老师对同窗答疑整理的学习笔记。仅供分享。更多精彩内容,你们能够扫描下方二位码,在极客时间订阅李号双老师的《深刻拆解Tomcat & Jetty》。获取一手学习资料。

相关文章
相关标签/搜索