servlet/tomcat等容器/springMVC之间的关系

Servlet是什么?

Servlet是JavaEE规范的一种,主要是为了扩展Java作为Web服务的功能,统一接口。由其他内部厂商如tomcat,jetty内部实现web的功能。如一个http请求到来:
容器将请求封装为servlet中的HttpServletRequest对象,调用init(),service()等方法输出response,由容器包装为httpresponse返回给客户端的过程。

servlet工作模式.jpg

在Servlet规范中,提供了ServletContext,ServletRequest,ServletResponse,Filter等诸多接口。
基本类图和调用关系如下:
image.png

请求调用关系

下面简要介绍下接口的作用,生命周期和使用:
Servlet:
作用:用于处理请求(service方法)
生命周期:加载实例化、初始化、处理客户端请求、销毁。
加载实例化主要是交由web容器完成,而其他三个阶段则对应Servlet的init、service和destroy方法。Servlet对象被创建出来后需要对其进行初始化操作,初始化工作可以放在以ServletConfig类型为参数的ini方法中,ServletConfig为web.xml配置文件中配置的对应的初始化参数,由web容器完成web.xml配置读取并封装成ServletConfig对象;当Servlet初始化完成后,开始接受客户端的请求,这些请求被封装成ServletRequest类型的请求对象和ServletResponse类型的响应对象,通过service方法处理请求并响应客户端;当一个Servlet需要从web容器中移除时,就会调用对应的destroy方法用于释放所有的资源,并且调用destroy方法之前要保证所有正在执行service方法的线程都完成执行。
使用:servlet规范中定义了GenericServlet接口,定义了通用,协议独立的servlet,他们的子接口HttpServlet就是用来处理http请求的Servlet,根据http协议扩展了不同方式的请求处理方法,如doPost,doGet.

ServletContext:Servlet与Servlet容器之间直接通信的接口,一个web应用只独有一个ServletContext.
作用:

  • 用于在web应用范围内存取共享数据,如setAttribute(String name, Object object),getAttribute()
  • 获取当前Web应用的资源,如getContextPath()
  • 获取服务器端的文件系统资源,如getResourceAsStream()
  • 输出日志,如log(String msg) : 向Servlet的日志文件中写日志
  • 在具体ServletContext 实现中,提供了添加Servlet,Filter,Listener到ServletContext里面的方法
    生命周期:和web应用的生命周期一样
    使用:一般由web容器实现,如tomcat

Filter:
作用:用于Web容器对请求和响应做统一处理,例如统一改变HTTP请求内容和响应内容,它可以作用在某个Servlet或一组Servlet
生命周期:加载实例化、初始化(init)、处理客户端请求(doFilter)、销毁(destroy)
使用:在doFilter方法中调用chain.doFilter(request, response)之前的代码可用来做一些请求校验,之后代码可用来做一些响应包装。

ServletRequest:封装了客户端请求的所有信息,如果使用HTTP协议通信则包括HTTP协议的请求行和请求头。HTTP协议对应请求对象类型是HttpServletRequest类
作用:

  • 获取HTTP协议请求头部,如getHeader、getHeaders
  • 获取请求路径,如getContextPath、getServletPath
  • 获取cookie的方法,如getCookies
  • 获取session的方法,如getSession,session是存储在服务器内存中,返回响应的时候会写入浏览器一个sessionId的cookie,用来标示这一个会话

生命周期:只在servlet的service方法或过滤器的doFilter方法作用域内有效,除非启用了异步处理调用了ServletRequest接口对象的startAsync方法,此时request对象会一直有效,直到调用AsyncContext的complete方法。另外,web容器通常会为了性能而不销毁ServletRequest接口的对象,而是重复利用ServletRequest接口对象。

ServletResponse:Servlet通过ServletResponse对象来生成响应结果。
作用:定义了一系列与生成响应结果相关的方法,如:

  • setCharacterEncoding() —— 设置相应正文的字符编码。响应正文的默认字符编码为ISO-8859-1;
  • setContentLength() —— 设置响应正文的长度;
  • setBufferSize() —— 设置用于存放响应正文数据的缓冲区的大小
  • getBufferSize() —— 获得用于存放响应正文数据的缓冲区的大小;
  • reset() —— 清空缓冲区内的正文数据,并且清空响应状态代码及响应头
  • resetBuffer() —— 仅仅清空缓冲区的正文数据,不清空响应状态代码及响应头;
  • flushBuffer() —— 强制性地把缓冲区内的响应正文数据发送到客户端;
  • isCommitted() —— 返回一个boolean类型的值,如果为true,表示缓冲区内的数据已经提交给客户,即数据已经发送到客户端;
  • getOutputStream() —— 返回一个ServletOutputStream对象,Servlet用它来输出二进制的正文数据;
  • getWriter() —— 返回一个PrinterWriter对象,Servlet用它来输出字符串形式的正文数据;

为了提高输出数据的效率,ServletOutputStream和PrintWriter首先把数据写到缓冲区内。当缓冲区内的数据被提交给客户后,ServletResponse的isComitted方法返回true。

生命周期:ServletResponse接口只在Servlet的service方法或过滤器的doFilter方法作用域内有效,除非它关联的ServletResponse接口调用了startAsync方法启用异步处理,此时ServletResponse接口会一直有效,直到调用AsyncContext的complete方法。另外,web容器通常会为了性能而不销毁ServletResponse接口对象,而是重复利用ServletResponse接口对象。

Listener:当触发某个事件,如servlet context初始化完成时,需要做一些事情,servlet规范中定义了若干个Listener用于监听这些事件。
作用:用于对特定对象的生命周期和特定事件进行响应处理,主要用于对Session,request,context等进行监控。

监听域对象自身的创建和销毁的事件监听器

  • ServletContextListener:ServletContext的创建和销毁:contextInitialized方法和contextDestroyed方法,作为定时器、加载全局属性对象、创建全局数据库连接、加载缓存信息等
  • HttpSessionListener:HttpSession的创建和销毁:sessionCreated和sessionDestroyed方法,可用于统计在线人数、记录访问日志等
  • ServletRequestListener: ServletRequest的创建和销毁:requestInitialized和requestDestroyed方法

监听域对象中的属性的增加和删除的事件监听器

  • ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener接口。
  • 实现方法:attributeAdded、attributeRemoved、attributeReplaced

监听绑定到HttpSeesion域中的某个对象的状态的事件监听器(创建普通JavaBean)

  • HttpSession中的对象状态:绑定→解除绑定;钝化→活化
  • 实现接口及方法:HttpSessionBindingListener接口(valueBound和valueUnbound方法)、HttpSessionActivationListener接口(sessionWillPassivate和sessionDidActivate方法)

tomcat是什么?

tomcat等容器其实就是web服务的实现,暴露端口,按照特定资源URL找到处理的servlet。然后处理请求。
web.xml其实tomcat在启动时候需要加载的配置欢迎页、Filter、Listener、Servlet等类的定义。当然不止加载这些东西,这些东西是需要加载到JVM堆内存中实例化的对象。
Tomcat启动时加载资源主要有三个阶段:

  • 第一阶段:JVM相关资源
(1)$JAVA_HOME/jre/lib/ext/*.jar
(2)系统classpath环境变量中的*.jar和*.class 
  • 第二阶段:Tomcat自身相关资源
(1)$CATALINA_HOME/common/classes/*.class  
(2)$CATALINA_HOME/commons/endorsed/*.jar   
(3)$CATALINA_HOME/commons/i18n/*.jar   
(4)$CATALINA_HOME/common/lib/*.jar   
(5)$CATALINA_HOME/server/classes/*.class   
(6)$CATALINA_HOME/server/lib/*.jar   
(7)$CATALINA_BASE/shared/classes/*.class   
(8)$CATALINA_BASE/shared/lib/*.jar 
  • 第三阶段:Web应用相关资源
(1)具体应用的webapp目录: /WEB-INF/classes/*.class   
(2)具体应用的webapp: /WEB-INF/lib/*.jar

在tomcat目录${CATALINA_HOME}/conf下和web应用目录${CATALINA_HOME}/webapps/WebDemo(WebDemo为web应用名)下都有web.xml这个文件,但是内容不一样。

Tomcat在激活、加载、部署web应用时,会解析加载${CATALINA_HOME}/conf目录下所有web应用通用的web.xml,然后解析加载web应用目录中的WEB-INF/web.xml。
其实根据他们的位置,我们就可以知道,conf/web.xml文件中的设定会应用于所有的web应用程序,而某些web应用程序的WEB-INF/web.xml中的设定只应用于该应用程序本身。

如果没有WEB-INF/web.xml文件,tomcat会输出找不到的消息,但仍然会部署并使用web应用程序,servlet规范的作者想要实现一种能迅速并简易设定新范围的方法,以用作测试,因此,这个web.xml并不是必要的,不过通常最好还是让每一个上线的web应用程序都有一个自己的WEB-INF/web.xml。

web.xml中可以配置web应用名称,图标,描述,ServletContext上下文参数,Fliter配置,Listener配置,Servlet配置,会话超时配置,MIME类型配置等等。

Spring MVC 是什么?

Spring MVC (SpringBoot)其实就是基于tomcat等这些web容器对我们的CS请求能做更多的事情,如校验,拦截(AOP思想),后期渲染等等,好让我们专注于业务的开发。
Springmvc的核心是一个DispatcherServlet,负责请求的解析,拦截,转发,响应等等。相关类图和请求处理流程为:



其中FrameworkServlet会和Spring的ApplicationContext联系起来,它实现了ApplicationContextAware接口。



当然Spring MVC框架也提供rest访问,从而可实现前后端的分离。
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestfulWebServiceController {

    @GetMapping("/message")
    public MyOutputResource getMessage() {
        return new MyOutputResource("Hello!");
    }
}

感谢您的阅读,我是Monica23334 || Monica2333 。立下每周写一篇原创文章flag的小姐姐,关注我并期待打脸吧~

参考资料:
Java Servlet 3.1 规范
servlet的本质是什么,它是如何工作的?
Servlet规范总结
【Java.Web】Servlet —— Servlet的类的体系结构
Servlet 工作原理解析
Cookie 与 Session 的区别
Session原理和Tomcat实现分析
An Introduction to Tomcat Servlet Interactions
关于web.xml配置的那些事儿
How Spring Web MVC Really Works

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容