Servlet实现前后端交互的原理及过程解析
在日常调试项目时,总是利用tomcat去启动项目,并进行前后端联调,但对于前后端的请求响应的交互原理及过程并不是特别清晰。
为什么在前端发出相应请求,就能跳转到后端通过程序得到结果再响应到前端页面呢?!
为了加深对该过程的理解,故以tomcat为例,撰写此文。
一、Tomcat部分
Tomcat总体结构:
Server->Service->Connector&Container(Engine->Host->Context(Wrapper(Servlet)))
如图所示的Ttomcat结构图,其核心是Connector和Container组件,其中Connector组件可以被替换从而提供更多选择,因此一个Container可以选择对应多个Connector。
Server
多个Connector和一个Container就形成了一个Service,就有了对外提供服务的能力。而光有Service还不行,还必须给其一个生存环境去发挥去作用,这项生杀大权的掌握者就花落Server手中了。
因此,Tomcat的生命周期就由Server来控制。
Server的作用很简单,就是对外提供接口让其他程序能够访问到其中的Service集合,同时维护包含的所有Service的生命周期,如初始化、找到对应service和结束服务等。
Service
对于Service来说,主要是对外提供服务,其中的Connector主要是负责对外交流,而Container则是处理内部事务。一个Service可有多个Connector,但只能有一个Container。
Connector
对于Connector来说,它将在某个指定的端口上来监听客户请求,把从socket传递过来的数据封装成Request,传递给Engine来进行处理,并从Engine处获得响应并返回给客户。Tomcat通常会用到两种Connector:Http Connector,在端口8080处监听来自客户browser的http请求;AJP Connector,在端口8009处监听来自其他webServer的Servlet/jsp代理请求。
Container
在Container核心组件中,包含了以下几个核心部分:Wrapper、Host、Engine、Context。
其中Engine是负责处理所有相关联的service请求,并将结果返回给service。而Connector则是作为service和engine之间的桥梁。一个engine下可以配置一个默认主机,每个虚拟主机都有一个域名。当engine接收到一个请求时,它会将该请求匹配到虚拟主机(host)上,然后将请求交给host来处理。若无法匹配到虚拟主机,则将其交给默认host来处理,以线程方式来启动host。
Host代表一个虚拟主机,每个虚拟主机和某网络域名相匹配。每个虚拟主机下可以有一个或多个web应用,每个web应用对应于一个context,相对应有contextpath。当主机接收到请求时,会将该请求匹配到某个context上,然后把请求交给该context来处理。
一个Context对应于一个web应用。一个web应用由一个或多个servlet组成。context在创建时将根据配置文件$ CATALINA_HOME/conf/web.xml和$ WEBAPP_HOME/WEB-INF/web.xml载入Servlet类。当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类,如果找到,则执行该类,获得请求的回应,并返回。
Wrapper代表了一个Servlet,负责管理Servlet的装载、初始化、执行以及资源回收。wrapper的实现类是StandardWrapper,该类还实现了拥有一个Servlet初始化信息的ServletConfig。
Lifecycle:在编程中也有很多对象是具有生命周期的,从初始化、运行、回收等 会经历几个不同的阶段。 在tomcat中容器相关的好多组建都实现了Lifecycle接口,当tomcat启动时,其依赖的下层组件会全部进行初始化。 并且可以对每个组件生命周期中的事件添加监听器。例如当服务器启动的时候,tomcat需要去调用servlet的init方法和初始化容器等一系列操作,而停止的时候,也需要调用servlet的destory方法。而这些都是通过org.apache.catalina.Lifecycle接口来实现的。由这个类来制定各个组件生命周期的规范。
Tomcat-Servlet的过程:
1、Tomcat在启动时,会加载server;
2、Server启动时,会加载Service;
3、Service中会加载Container;
4、Container中的Wrapper含有Servlet;
5、在HttpServlet中含有一些doGet、doPost、service等方法,用来处理各种类型的请求。
Tomcat Server处理一个http请求的过程:
假设来自客户的请求为:
http://localhost:8080/test/index.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/test/index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7) path="/test"的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser
二、Serlvet原理
从Tomcat部分我们可以看出,browser的请求在层层传递下最终在Servlet处进行请求的处理及响应。因此本部分主要围绕传递过来的请求和响应部分来进行阐述。
1、认知Servlet
作为Javaweb三大组件(Servlet,Filter,Listener)之一的Servlet,每一个都是唯一的,所能处理的请求是不同的。
Servlet是一种独立于平台和协议的服务器端的java应用程序,运行于java服务器中,可以动态扩展服务器能力,并采用请求-响应模式来提供web服务。
Servlet是一个单实例多线程的。只能被实例化一次,而每次service服务会开启新线程进行处理新请求。
2、Servlet生命周期
前面说到,在Tomcat核心组件Container中,一个web应用由一个或多个Servlet组成,而一个Context对应一个web应用,在创建时会去根据配置文件$ CATALINA_HOME/conf/web.xml和$ WEBAPP_HOME/WEB-INF/web.xml载入Servlet类。
因此Servlet的生命周期由web容器来负责,根据web.xml来加载对应的Servlet类。Servlet核心代码如下:
在上图所示的五个方法中,其中init、service和destroy三个方法均为生命周期方法,在第一次被访问时出生,在关闭服务器时死亡。
init方法会在Servlet对象创建之后马上执行,且只执行一次。
destroy方法会在Servlet被销毁之前调用,也只执行一次。
对于service方法,则可以被多次调用,每次处理请求时都是在调用该方法。
getServletConfig可以获得Servlet的配置信息。
getServletInfo方法可以获得Servlet信息。
从Servlet.class文件中我们可以看到,与之相关联的由ServletConfig、ServletRequest、ServletResponse三个类,这三个类都是通过web容器传递给Servlet的。
其中,ServletConfig是在Servlet初始化时就通过web.xml文件解析传给了Servlet,后两个都是请求到达时调用Servlet.service时才传递过来的。
在第一部分讲解Wrapper时也说过,它代表了一个Servlet。通过查询源码发现,StandardWrapper和StandardWrapperFacede都实现了ServletConfig接口,而 StandardWrapperFacade 是 StandardWrapper 门面类(门面设计模式)。所以传给 Servlet 的是 StandardWrapperFacade 对象,这个类能够保证从 StandardWrapper 中拿到 ServletConfig 所规定的数据,而又不把 ServletConfig 不关心的数据暴露给 Servlet。
3、Servlet工作过程
1)browser发出一个http请求;
2)Tomcat的Connector组件监听到该请求,其主线程会创建HttpServletRequest对象和HTTPServletResponse对象;
3)从请求URL中找到正确Servlet后,Tomcat为其创建或分配一个线程,同时将2中对象传递给该线程;
4)Tomcat调用Servlet的service()方法,会根据请求参数的不同来调用doGet()或doPost()等方法,并将结果返回到HTTPServletResponse对象中;
5)Tomcat将响应结果返回到browser。
三、HTTP与服务器的交互方式
1、http简介
HTTP协议,即超文本传输协议,基于TCP/IP通信协议来传输数据,工作于客户端-服务端架构上,通过URL向Web服务器(Apache服务器等)传输请求并得到响应。默认端口为80,也可以设置为8080等。
HTTP三点注意事项:
HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2、http消息结构
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,
下图给出了请求报文的一般格式。
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
3、请求方式
HTTP1.0有三种:get、post、head;
HTTP1.1新增了五种:options、put、delete、trace和connect。
其中较为常用的为get、post、delete和put,这大致对应着对该资源的查、改、删、增四个操作。
1)Get请求用于向服务器进行信息获取,是安全和幂等的。它仅仅是为了获取信息,不会影响资源的状态;所谓幂等,即对于同一个URL的多个请求返回的结果都一致。
get请求会将数据附在URL之后,以?来进行分割,参数之间以&来进行连接。对于非英文字母/数字等,都需要进行格式的转换。而由于其在URL进行拼接,对于涉及到密码等请求,是不安全的。
在HTTP协议中对URL长度并没有作出限制,而URL的最大长度其实和用户浏览器以及web服务器有关。如IE为2048,Google为8182,Apache(Server)为8192。
2)Post请求表示向服务器提交数据的一种请求,可能修改服务器上的资源,类似数据库的insert一样。post对于数据的提交是放置在http包的包体当中的。理论上post请求是没有大小限制的,起限制作用的是服务器处理程序的处理能力。如IIS 6.0默认post数据最大为200KB,每个表单限制为100KB。post 的安全性比get高。
3)Put请求也是向服务端发送数据从而改变信息,类似于数据库的update一般。
4)Delete请求就是删除某一资源的,类似于数据库的delete操作。
四、SpringMVC下前后端交互过程
1、交互过程
由于目前接触的项目是建立在springMVC模式下的,故根据上图所示,在最后对SpringMVC下的请求响应过程进行解析:
1)用户发送一个URL请求到前端控制器DispatcherServlet;
2)前端控制器将请求发给处理器映射器HandlerMapping,它会根据xml配置、注解等进行查找hander;
3)处理器映射器返回执行链HandlerExecutionChain(里面有handler对象,在它之前有多个interceptor拦截器);
4)前端控制器通过处理器适配器HandlerAdapter去执行Handler,不同的Handler由不同的适配器执行;
5)通过Handler处理器,即我们熟悉的Controller来处理业务逻辑;
6)处理完之后,返回ModelAndView对象,其中有视图名称,模型数据等;
7)HandlerAdapter将ModelAndView返回给DispatcherServlet;
8)DispatcherServlet将得到的ModelAndView传递给视图解析器ViewResolver进行解析;
9)ViewResolver解析后返回具体的视图View;
10)前端控制器对视图View和数据进行渲染,将模型数据等填充到request域中;
11)将最终的视图返回给客户,产生response响应。
2、组件名词解释
前端控制器DispatcherServlet:接收请求响应结果,相当于转发器、中央处理器,减少了其他组件之间的耦合度;
处理器映射器HandlerMapping:根据请求URL查找handler;
处理器适配器HandlerAdapter:按特定规则去执行handler,故编写handler时按HandlerAdapter要求去做,这样适配器才可正确执行handler;
视图解析器ViewResolver:根据逻辑视图解析成真正的视图(View对象)
视图View:View是一个接口,实现类支持不同的View类型(jsp,PDF,Excel...)
因个人学识有限,若上述内容某处叙述不当,请指教!
Servlet实现前后端交互的原理及过程解析的更多相关文章
- Node之简单的前后端交互
node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学n ...
- Django之META与前后端交互
Django之META与前后端交互 1 提交表单之GET 前端提交数据与发送 1)提交表单数据 2)提交JSON数据 后端的数据接收与响应 1)接收GET请求数据 2)接收POST请求数据 3)响应请 ...
- 前后端交互实现(nginx,json,以及datatable的问题相关)
1.同源问题解决 首先,在同一个域下搭建网络域名访问,需要nginx软件,下载之后修改部分配置 然后再终端下cmd nginx.exe命令,或者打开nginx.exe文件,会运行nginx一闪而过, ...
- springboot+mybatis+thymeleaf项目搭建及前后端交互
前言 spring boot简化了spring的开发, 开发人员在开发过程中省去了大量的配置, 方便开发人员后期维护. 使用spring boot可以快速的开发出restful风格微服务架构. 本文将 ...
- 百度ueditor的图片上传,前后端交互使用
百度ueditor的使用 一个文本编辑器,看了网上很多文档写的很乱,这里拾人牙慧,整理下怎么使用. 这个东西如果不涉及到图片附件上传,其实很简单,就是几个前端文件,直接引用,然后配置下ueditor. ...
- SSM-网站后台管理系统制作(4)---Ajax前后端交互
前提:Ajax本身就为前后端交互服务的,实现功能:用户输入信息,实时判断用户的情况,这也是现在登录界面普遍流行的做法.前端js通过注释识别Controller层,该层查询返回,和之前Google验证码 ...
- 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)
这是 CMS 框架系列文章的第二篇,第一篇开源了该框架的代码和简要介绍了框架的目的.作用和思想,这篇主要解析如何把sql 转成标准 xml 配置文件和把前端post的增删改数据规范成方便后台解析的结构 ...
- thinkphp+jquery+ajax前后端交互注册验证
thinkphp+jquery+ajax前后端交互注册验证,界面如下 register.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...
- nodejs实现前后端交互
本人nodejs入门级选手,站在巨人(文殊)的肩膀上学习了一些相关知识,有幸在项目中使用nodejs实现了前后端交互,因此,将整个交互过程记录下来,方便以后学习. 本文从宏观讲述nodejs实现前后端 ...
随机推荐
- winxp退市是微软windows操作系统的滑铁卢
winxp退市是微软windows操作系统的滑铁卢 兵败如山倒,windowsxp退市.宣布微软时代结束,windows将逐步退出中国市场,取而代之将是中国人自己的操作系统.中国人努力.中国人加油,不 ...
- KMP算法完整教程 (上)
KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: 高级检索算法 功能: 字符串匹配查找 提出者: D.E.Knuth(克努兹),J.H.Mor ...
- 安卓解析json
重点是开启网络权限 难点是调用函数 开启网络权限 </application> <uses-permission android:name="android.permiss ...
- hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)
Mirror and Light Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- LodRunner实现大负载测试的四部曲(配置系统参数、配置LR、修改脚本、设置组策略)
见 http://www.51testing.com/?uid-97659-action-viewspace-itemid-210924 LoadRunner以下简称(LR)是目前业界最流行的压力测试 ...
- 事务基础知识-->Spring事务管理
Spring虽然提供了灵活方便的事务管理功能,但这些功能都是基于底层数据库本身的事务处理机制工作的.要深入了解Spring的事务管理和配置,有必要先对数据库事务的基础知识进行学习. 何为数据库事务 “ ...
- Spring配置文件总结
http://blog.csdn.net/zhejingyuan/article/details/41042789
- JAVASCRIPT 浏览器兼容性问题及解决方案列表
JAVASCRIPT 浏览器兼容性问题及解决方案列表(1)获取HTML元素只兼容IE:document.all.hello hello 兼容所有: document.getElementById(“h ...
- php 将一个字符串分割为组成它的字符
问: php里如何将一个字符串分割为组成它的字符? 比如hello -> [h, e, l, l, o] 以下有三种方法: 这是需要被分割的字符串: $str = 'Hello小样'; ...
- 分页技巧_改进JSP页面中的公共分页代码_实现分页时可以有自定义的过滤与排序条件
分页技巧__改进JSP页面中的公共分页代码 自定义过滤条件问题 只有一个url地址不一样写了很多行代码 public>>pageView.jspf添加 分页技巧__实现分页时可以有自定义的 ...