Servlet运行原理以及生命周期
一、Servlet生命周期:
Servlet加载、实例化、初始化、服务、销毁。
1、初始化init():
当服务启动时,Servlet被装入tomcat或者其他服务器容器时执行(服务器容器从启动到停止期间唯一的一次)init()初始化方法,负责初始化Servlet对象,无论有多少个请求访问Servlet,初始化init()只会启动一次,不会重复执行。
2、服务service:
服务service方法是Servlet核心,该方法有两个参数HttpServletRequest arg0, HttpServletResponse arg1:
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能(这种doXxx的方法也叫钩子方法如doGet,doPost)。
如果在继承HttpServlet的类中对Serlvet进行重写,那么客户端请求Serlvet的时候,就会
去子类中调用重写的service方法(一般不对Serlvet方法进行重写)
3、销毁destroy():
Serlvet在tomcat等服务器停止运行且卸载它时调用销毁destroy()方法,因为service方法运行时有可能有多个线程,当执行了销毁destroy()方法,这些线程就全部终止。
二、Servlet与Tomcat等服务器关系:
- web客户端 向Servlet容器(Tomcat)发出Http请求
- Servlet容器接收web客户端的请求
- Servlet容器创建一个HttpRequest对象,将Web
Client请求的信息封装到这个对象中。 - Servlet容器创建一个HttpResponse对象
- Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。
- HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
- HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
- Servlet容器把HttpServlet的响应结果传给Web
Client。
三、Servlet工作原理:
1、当web客户端发送一个Http请求,Servlet创建HttpRequest对象和HttpResponse对象,将web客户端请求的信息封装到HttpRequest对象中,Servlet将HttpRequest对象和HttpResponse对象作为参数传递给HttpServlet中的service()方法,通过HttpRequest中封装的Http请求信息获取请求方式对请求进行响应的,选择调用doGet,doPost等这些钩子方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet()、doPost()等等这些钩子方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。
如果服务器启动时就创建Servlet,那么还需要在web.xml文件中配置<load-on-startup>1</load-on-startup>。Servlet是在第一次被访问时由服务器创建的,而且一个Servlet类型,服务器只创建一个实例对象,它是单例的。
2、每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。
服务器接收到一次请求,就会调用service() 方法一次。
3、Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。
四、创建Servlet对象
1、Servlet容器启动时:读取web.xml配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,同时将ServletConfig对象作为参数来调用Servlet对象的init方法。
2、在Servlet容器启动后:客户首次向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet 对象的service方法。
3、Servlet Servlet容器在启动时自动创建Servlet,这是由在web.xml文件中为Servlet设置的<load-on-startup>属性决定的。从中我们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。
三、Servlet概述
Servlet是JavaWeb的三大组件之一,它属于动态资源。都会在web.xml中配置,例如如上图
Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
Tomcat服务器会帮助我们将请求的数据封装在request对象
Tomcat同样会创建respose对象给我们使用,让我们响应 HttpServletRequest extends ServletRequest
例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理!
我们需要实现自己的逻辑业务就需要自己来编写Servlet,每个Servlet必须实现javax.servlet.Servlet接口。
实现Servlet有三种方式:
1.实现javax.servlet.Servlet接口;
2.继承javax.servlet.GenericServlet类;
3.继承javax.servlet.http.HttpServlet类;
开发中通常我们会去继承HttpServlet类来完成我们的Servlet,生命周期方法由Tomcat来调用,我们只是完成接受请求,然后响应,完成业务逻辑代码
Tomcat服务器帮助我们完成不变的代码,我们来完成业务需求变化的代码
我们的代码和Tomcat代码合起来构成一个完成的代码
四、补充:
近期发现对:
1、为什么不建议重写service方法?
2、servlet中为什么一定要重写doGet以及doPost方法?
3、servlet的父类;
有了新的认识,进行补充;
1、为什么不建议重写service方法?
因为客户端每一次发送请求,服务端都会调用一次servlet中service方法,而service方法其实是类似调度的功能,
service方法源码:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if(method.equals("GET"))
{
long lastModified = getLastModified(req);
if(lastModified == -1L)
{
doGet(req, resp);
} else
{
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if(ifModifiedSince < (lastModified / 1000L) * 1000L)
{
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else
{
resp.setStatus(304);
}
}
} else
if(method.equals("HEAD"))
{
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else
if(method.equals("POST"))
doPost(req, resp);
else
if(method.equals("PUT"))
doPut(req, resp);
else
if(method.equals("DELETE"))
doDelete(req, resp);
else
if(method.equals("OPTIONS"))
doOptions(req, resp);
else
if(method.equals("TRACE"))
{
doTrace(req, resp);
} else
{
String errMsg = lStrings.getString("http.method_not_implemented");
Object errArgs[] = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
可以看出来,如果我们重写了service方法,没有实现对doGet和doPost等doxxx方法的调用,那么请求就得不到处理。
如果不对service方法重写,那么会执行HttpServlet方法中service方法。
2、servlet中为什么一定要重写doGet以及doPost方法?
因为在service方法对请求的方式进行了匹配,如Get方法就调用doGet方法,所以一定要根据业务逻辑对doGet或者doPost等doxxx方法进行重写
3、servlet的父类
GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet。
GenericServlet还实现了ServletConfig接口,所以可以直接调用getInitParameter()、getServletContext()等ServletConfig的方法。
具体源码可以反编译去查看:
GenericServlet的init()方法
在GenericServlet中,定义了一个ServletConfig config实例变量,并在init(ServletConfig)方法中把参数ServletConfig赋给了实例变量。然后在该类的很多方法中使用了实例变量config。
如果子类覆盖了GenericServlet的init(StringConfig)方法,那么this.config=config这一条语句就会被覆盖了,也就是说GenericServlet的实例变量config的值为null,那么所有依赖config的方法都不能使用了。如果真的希望完成一些初始化操作,那么去覆盖GenericServlet提供的init()方法,它是没有参数的init()方法,它会在init(ServletConfig)方法中被调用。
HttpServlet类是GenericServlet的子类,它提供了对HTTP请求的特殊支持,所以通常我们都会通过继承HttpServlet来完成自定义的Servlet。
HttpServlet覆盖了service()方法
HttpServlet类中提供了service(HttpServletRequest,HttpServletResponse)方法,这个方法是HttpServlet自己的方法,不是从Servlet继承来的。在HttpServlet的service(ServletRequest,ServletResponse)方法中会把ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse,然后调用service(HttpServletRequest,HttpServletResponse)方法,这说明子类可以去覆盖service(HttpServletRequest,HttpServletResponse)方法即可,这就不用自己去强转请求和响应对象了。
就是直接继承HttpServlet,然后无需进行重写,就可以实现ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse,因为在HttpServlet类已经实现了这一操作
借鉴于https://blog.csdn.net/tanyunlong_nice/article/details/42536461
Servlet运行原理以及生命周期的更多相关文章
- HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象
1 HTTP协议特点 1)客户端->服务端(请求request)有三部份 a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...
- jsf的运行原理及生命周期
一.jsf(java server faces)的运行原理(工作方式) 1.jsf应用是事件驱动的,当一个事件发生时(比如用户单击一个按钮),事件通知通过HTTP发往服务器,服务器端使用叫做Faces ...
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- Servlet 运行原理
一:servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. 二:简单servlet实例 //导入所需的包 import javax.servle ...
- JavaWeb之 Servlet执行过程 与 生命周期
Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet.Servlet下有一个实现类叫HttpServle ...
- [转]JavaWeb之 Servlet执行过程 与 生命周期
https://www.cnblogs.com/vmax-tam/p/4122105.html Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类 ...
- PHP的工作原理和生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013778883/article/details/79831035 php是一门适用于web开 ...
- JavaEE Servlet 核心方法及生命周期
做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...
- 【servlet】Servlet的API和生命周期]
创建时间:6.15 一.Servlet的API(生命周期) (1)Servlet接口中的方法 1)init(ServletConfig config) 何时执行:servlet对象创建的时候执行 Se ...
随机推荐
- 解决Office 2016客户端如何同SharePoint Server2016安装在一起
前言 Microsoft Office 2016 客户端默认使用新式验证. 在某些配置中,新式验证不受安装有 SharePoint Server 2016 的 Office 2016 客户端的支持,例 ...
- springmvc中为我们做了什么
这应该是每个使用框架的人应该自问的.这就要从没有使用框架时说.在没用框架开发web应用时,自己是怎么开发的,就是写servlet,jsp. 使用springmvc后,使用Controller注解,其实 ...
- 下载Crypto,CyCrypto,PyCryptodome 报错问题
python下载Crypto,CyCrypto,PyCryptodome,如有site-packages中存在crypto.pycrypto,在pip之前,需要pip3 uninstall crypt ...
- 谷歌浏览器(Chrome)禁止浏览器缓存 设置
在开发项目期间用谷歌浏览器调试,他总是缓存我的css样式这个很气人啊,后经过摸索找到了方法,如下 先F12或者shift+ctrl+j 打开调试者工具,在找Network这个tab按钮,点击进入,勾选 ...
- 推举算法 AdaBoost 哥德尔奖 Godel Prize
推举算法 AdaBoost 2003年理论计算机科学界最高奖 哥德尔奖 Godel Prize
- Web开发——HTML基础
文档资料参考: 参考:MDN官网 参考:http://www.runoob.com,W3School 参考:https://developer.mozilla.org/zh-CN/docs/Learn ...
- 目标检测(七)YOLOv3: An Incremental Improvement
项目地址 Abstract 该技术报告主要介绍了作者对 YOLOv1 的一系列改进措施(注意:不是对YOLOv2,但是借鉴了YOLOv2中的部分改进措施).虽然改进后的网络较YOLOv1大一些,但是检 ...
- 【数据可视化-Echarts】Echart基础
林峰老师Echart基础课程笔记
- 格式化输出&初始编码&运算符
一:格式化输出 % %d %s %为占位符 S替换的内容的类型为字符型 d替换的内容为整型 若在格式化输出的时候需要正常用到% 则表示时用两个%%表示 如: name = input( ...
- 【UML】NO.54.EBook.6.UML.2.002-【Thinking In UML 大象 第二版】- UML 核心元素
1.0.0 Summary Tittle:[UML]NO.54.EBook.6.UML.2.002-[Thinking In UML 大象 第二版]- UML 核心元素 Style:DesignPat ...