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 ...
随机推荐
- rmq区间最值
时间复杂度O(NlogN)+O(Q) int a[N]; int dpmax[N][20],dpmin[N][20]; void first(int n) { mm(dpmax,0); mm(dpmi ...
- JBPM工作流(七)——详解流程图
概念: 流程图的组成: a. 活动 Activity / 节点 Node b. 流转 Transition / 连线(单向箭头) c. 事件 1.流转(Transition) a) 一般情况一个活动中 ...
- 查看oracle数据库是否为归档模式
查看oracle数据库是否为归档模式 [1] 1.select name,log_mode from v$database; NAME LOG_MODE --------------- ...
- Winscp 密钥登录
继前段时间,使用密钥SSH登录系统以后运维用着很爽,但是有一部分开发的同事反应使用Winscp添加私钥的时候,提示添加失败,原来Winscp使用的是putty作为SSH登录工具,而puttygen所生 ...
- PowerPoint使用技巧
1.右键Group两个元素,可以一起移动: 2.Insert 屏幕输入功能: 3.录制旁白: 4.录制完旁白之后可以生成视频: 5.如果不确定所有引用的组件是否可以在别的机器上使用,可以导出只CD,生 ...
- 部署WEB项目到服务器(二)安装tomcat到linux服务器(Ubuntu)详解
突发奇想,想在自己电脑上部署一个web网站. 1,先去tomcat官网下载一个适合linux的版本:tar.gz 2,然后通过FileZIlla传到服务器的/opt目录: 3,然后创建目录 并解压缩 ...
- delphi操作sqlite3
Delphi SQLite 简明无废话上手指南SQLite下载http://www.sqlite.org/download.html SQLite FAQhttp://www.sqlitecn.org ...
- IntelliJ IDEA 下的svn配置及使用
首先,使用的时候,自己得先在电脑上安装个小乌龟.也就是svn啦. 第一步安装小乌龟. 如下: 具体安装好像没什么具体要求,一路next,就好. 如上图箭头所示,在安装 TortoiseSVN 的时候, ...
- ionic1滑动时间选择器
上图: 1.derective代码 .directive('monthPicker', function ($ionicScrollDelegate) { return { restrict: 'E' ...
- vs自定义类模板
.找到VS安装目录,我的目录是:C:Program Files (x86)Microsoft Visual Studio 12.0 .在C:Program Files (x86)Microsoft V ...