开头说两句
Java 基础 Demo 站: https://www.javastudy.cloud
Java 中高级开发博客: https://www.lixiang.red
Java 学习公众号: java 技术大本营
学习背景
前面,我们一起学习到了 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 方法
框架的通用封装方法
我们在 ApplicationFilterConfig 这个类中可以看到,过滤器主要是调用 doFilter 方法进行处理
但是在 doFilter 方法中,我们看到,只有一些通用的逻辑,并没有实际的处理,而是把逻辑下放到 internalDoFilter 里面
在 tomcat 源码中,对 internalDoFilter 做了直接实现. 在通用封装中,我们会把 internalDoFilter 做成一个抽象方法,然后交于子类去实现, 这样可以定义不同的子类去实现不同的逻辑.如我们以前讲的初始化的时候 init 方法的实现
DefaultServlet
我们在 Servlet 声明,都是在 web.xml 之中,所以我们要去 web.xml 里面去找,这个 web 应用有哪些 servlet,我们找到了 DefaultServlet, 其实还有一个 jspServlet,这里就不展开了
同样还有配套的 servletMapping ,当没有别的 servlet 处理请求时,就使用这个 defaultServlet 来处理
我们可以通过类关系图,看到 DefaultServlet 的继承关系
通过类关系图,他在通用的 Servlet 的基础之上添加了 Http 的处理
我们从入口 service 方法可以看到:
然后在父类方法中可以看到:
然后会调用实现类的 doGet 方法,我们回到 DefaultServlet 中,看看 doGet 方法,可以看到,实际上是对服务器资源的处理
我们细致分析下来,可以划分为以下几段,从请求资源的定位,到获取资源的属性,到获取资源的内容,到最后设置 response 的输出
tomcat 做文件服务器
经过上面对 DefaultServlet 的分析,我们可以发现,他就是一个资源服务器,所以我们可以直接用 tomcat 做一个文件服务器,如下图所示,我们在 webapps 下面新建了一个文件夹
然后启动 tomcat,访问我们的资源
提示: content-type
最后说两句
通过这一系列学习,我们学习了 tomcat 请求从入口,到最后的 servlet 处理,大家有什么想法,可以分享给小刀:best396975802
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于