学习目标:
- 对网络部分知识的一个大的总结 —— 原理层面
- 对Tomcat的基本原理有所了解,打破神秘感 —— 代码层面
- 更好的进行web开发 —— 实践
Tomcat实现目标:
- 不考虑效率,不过多的考虑错误处理
- HTTP 1.0子集
1)支持GET方法,有限度的支持POST方法
1)Head支持粒度较差 - 尽可能围绕Tomcat+Servlet的标准走,但不遵守标准
- Tomcat + Web 应用并不是分离的
- 单一的的Web应用
- 没有配置 web.xml
多客户端的,客户端发送请求到我们写好的Tomcat,然后再接受来自Tomcat的响应
我们需要实现的有:
(1、2、7属于Http角度需要实现的功能,剩下的是站在Servlet标准的角度要实现的)
- TCP Server —— 拥有并发处理的功能,通过线程池来实现
- 接收并解析 HTTP 请求的能力—— HttpServletRequest 对象
- 实例化 HttpServletResponse对象的能力(空对象)
- 有能力区分是静态资源请求还是动态资源请求
- 假如是静态资源请求,需要读取静态资源内容
- 假如是动态资源请求,需要把request/response 交给正确的 Servlet 中 doGet/doPOST方法处理的能力
- 把HttpServletResponse 对象转换为 HTTP 响应并发送的能力
类设计
- Server:处理 TCP Server 的相关代码部分,整个程序的入口
- Transaction Task : 读取请求 - 发送响应的完整过程,提供给线程池去使用
- HttpServletRequest:请求内容的对象封装
- HttpServletResponse:相应内容的对象封装
- Servlet(接口) HttpServlet(抽象类)
—————————————————————————————————————— - StaticResourceServlet:内置的Servlet实现,专门用来处理静态资源
- NotFoundServlet:内置的Servlet实现,专门用来处理404的情况
- Web应用中的Servlet
HTTP请求:
HttpServletRequest.java :
响应
一些Servlet区别
关于 Servlet (Interface) 和HttpServlet (AbstractClass) 和应用中 XXXServlet 区别:
- Servlet 标准中定义的接口 Servlet(Interface)
里面包含三个方法: init() 、 service() 、 destroy() - HttpServlet (AbstractClass) 抽象类是实现了 Servlet(Interface)接口的
实现了 service()
根据请求的方法,分别调用 doGet / doPost
doGet / doPost 可供子类覆写 - 应用中的 XXXServlet 继承自 HttpServlet
默认覆写对应的 doGet / doPost 方法即可
代码
链接:https://pan.baidu.com/s/1wAXp-uyivegzs776lBgLCQ
提取码:ip72
环境搭建以及配置
打包
可以自己动手打包,模仿tomcat目录进行打包
手动打jar包
servlet-api 这个 jar 包存放的就是 servlet 标准的那套代码,就是代码中的standard包下的servlet
tomcat-core 对应的就是 tomcat 下的 servlet
tomcat是支持多web应用的,但是这里只有一个
然后就可以在命令行中运行起来了
当然,不打包也是可以运行的,这里是为了尽量模仿tomcat,tomcat远比这里模仿的东西要多得多
总结
- 从代码角度理解 HTTP 协议
- 打破对于 Tomcat 的神秘感
- 对于为什么在写 servlet 项目时会出现 404 问题有更深的了解
- 了解为什么 webapp 的目录结构必须按照标准
- 关于 servlet 的生命周期
类的实例化过程控制权被 Tomcat 收走了,我们写的 Servlet 类不是我们 new 出来的对象,而是 Tomcat 内部 new 的
这样就我们没有合适的时机对对象进行初始化操作,比如实例化之后,销毁之前
所以就有了 init() , destroy() 这两个方法
Tomcat 承诺,实例化 Servlet 对象以后,一定会调用一次 init() ,前提是 Servlet 对象都是单例(为了提升效率)
我们的应用,如果想在 Servlet 实例化之后做一些工作,就可以覆写 init() 方法
destroy() 同理,是在对象销毁之前调用的