tomcat 学习 | DefaultServlet | tomcat 做文件服务器

本贴最后更新于 1730 天前,其中的信息可能已经时过境迁

开头说两句

Java 基础 Demo 站: https://www.javastudy.cloud
Java 中高级开发博客: https://www.lixiang.red
Java 学习公众号: java 技术大本营
java_subscribe

学习背景

前面,我们一起学习到了 tomcat 对 web 请求的处理
https://www.lixiang.red/articles/2019/08/14/1565794504734.html
通过学习我们可以知道在对 web 请求进行处理时,以 CoyoteAdapter.service 为入口,然后经历了各级 Container(Engine, Host , Context, wrapper)的 pipeline 中 valve 来进行处理,到最后的时候,会经过 ApplicationFilterChain 到达我们的过滤器链,最后到 Servlet, 这个 servlet 就是最后处理请求的地方

ApplicationFilterChain

最原始的 web 应用,其实是 web.xml 和 servlet 的组合. 所有和 web 相关的配置都在 web.xml 里面,现在用了 spring-boot 之后,我们看不到 web.xml 了,但并不代表他不存在了.web.xml 里面的东西都是在的.
在 Web 整个请求的过程中,我们从过滤器链执行完之后,调用 Servlet 开始处理逻辑
ApplicationFilterChain 的主要字段有四个, filters,pos, n , servlet
filters: 当前过滤器链中有的过滤器
pos: 代表当前执行的过滤器的位置
n: 代表这个过滤器链中总共有多少个过滤器
servlet: 当过滤器执行到最后一个的时候,即 pos = n 的时候,就调用 servlet 的实例,执行 servlet 方法

源码如下:
/**
     * Filters.
     */
    private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];


    /**
     * The int which is used to maintain the current position
     * in the filter chain.
     */
    private int pos = 0;


    /**
     * The int which gives the current number of filters in the chain.
     */
    private int n = 0;


    /**
     * The servlet instance to be executed by this chain.
     */
    private Servlet servlet = null;

可以看到, 在过滤器链执行结束的时候,会调用 servlet.service 方法
image.png

框架的通用封装方法

我们在 ApplicationFilterConfig 这个类中可以看到,过滤器主要是调用 doFilter 方法进行处理
image.png
但是在 doFilter 方法中,我们看到,只有一些通用的逻辑,并没有实际的处理,而是把逻辑下放到 internalDoFilter 里面
image.png
在 tomcat 源码中,对 internalDoFilter 做了直接实现. 在通用封装中,我们会把 internalDoFilter 做成一个抽象方法,然后交于子类去实现, 这样可以定义不同的子类去实现不同的逻辑.如我们以前讲的初始化的时候 init 方法的实现
image.png

DefaultServlet

我们在 Servlet 声明,都是在 web.xml 之中,所以我们要去 web.xml 里面去找,这个 web 应用有哪些 servlet,我们找到了 DefaultServlet, 其实还有一个 jspServlet,这里就不展开了
image.png
同样还有配套的 servletMapping ,当没有别的 servlet 处理请求时,就使用这个 defaultServlet 来处理
image.png
我们可以通过类关系图,看到 DefaultServlet 的继承关系
image.png
通过类关系图,他在通用的 Servlet 的基础之上添加了 Http 的处理
我们从入口 service 方法可以看到:
image.png
然后在父类方法中可以看到:
image.png
然后会调用实现类的 doGet 方法,我们回到 DefaultServlet 中,看看 doGet 方法,可以看到,实际上是对服务器资源的处理
image.png
我们细致分析下来,可以划分为以下几段,从请求资源的定位,到获取资源的属性,到获取资源的内容,到最后设置 response 的输出
image.png

tomcat 做文件服务器

经过上面对 DefaultServlet 的分析,我们可以发现,他就是一个资源服务器,所以我们可以直接用 tomcat 做一个文件服务器,如下图所示,我们在 webapps 下面新建了一个文件夹
image.png
然后启动 tomcat,访问我们的资源
image.png
提示: content-type

最后说两句

通过这一系列学习,我们学习了 tomcat 请求从入口,到最后的 servlet 处理,大家有什么想法,可以分享给小刀:best396975802

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3170 引用 • 8209 回帖 • 2 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...