JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
【声明】
欢迎转载,但请保留文章原始出处→_→
文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html
一、http协议回顾:
在上一篇文章中:JavaWeb学习之Servlet(一)----MyEclipse及Tomcat的配置,我们通过在浏览器输入url,就能看到在MyEclipse中编写的Servlet资源,效果如下:
上图中,整个过程是这样的:浏览器中输入url后,会通过hosts文件/dns服务器解析为IP地址,进而找到对应ip地址的服务器。
在这期间,浏览器会通过http协议发出请求。服务器端收到请求后,做了下面这些事:
(1)分析出当前请求的是哪台虚拟主机:
- 查看Host请求头分析出访问的是哪台虚拟主机
- 如果没有Host请求头(在浏览器地址栏直接输入ip地址而不是url),则访问缺省虚拟主机
(2)分析当前请求访问的是当前虚拟主机的哪个Web应用:
- 从请求行中请求的资源部分来分析
(3)分析当前请求要访问的是这个Web应用的哪个资源:
- 从请求行的资源部分分析出访问的是哪个资源
(4)查找web.xml文件,查看有没有对应的虚拟路径,如果有则用这个虚拟路径对应的资源做响应
(5)服务器从response对象中获取之前写入的数据(这就是写在Servlet当中的java代码),组织成http响应消息发给浏览器。
注:第(5)句话便是本文要学习的重点。
二、Servet的运行过程及生命周期
Servlet程序是由WEB服务器调用,web服务器收到客户端的ServletWeb服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第(4)步,否则,执行第(2)步。
访问请求后:
(1)装载并创建该Servlet的一个实例对象。
(2)调用Servlet实例对象的init()方法。
(3)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
(4)WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
Servet的生命周期:
Servlet 的生命周期定义了一个Servlet如何被加载、初始化,以及它怎样接收请求、响应请求、提供服务。
生命周期如下:
- (1)通常情况下,服务器会在Servlet第一次被调用时创建该Servlet类的实例对象(servlet出生),创建出对象后立即调用init()方法做初始化操作;
- (2)一旦被创建出来,该Servlet实例就会驻留在内存中,为后续对这个Servlet的请求做服务,每次对这个Servlet的访问都会导致Servlet中Service方法执行;
- (3)当web应用被移除容器或者关闭服务器时,随着web应用的销毁,Servlet也会被销毁(servlet死亡)。在销毁之前服务器会调用Servlet的destroy方法做一些善后的工作。
有3个方法代表了Servlet的生命周期:
- init方法,负责初始化Servlet对象。
- service方法,负责响应客户的请求(调用doGet或doPost等方法)。
- destroy方法,当Servlet对象退出生命周期时,负责释放占用的资源。
注:在Servlet的整个生命周期内,Servlet的init方法只有在servlet被创建时被调用一次,每次对这个Servlet的访问都会导致Servlet中Service方法执行。
例如:现在浏览器连续访问Servlet 10次,内存中只有一个Sevlet对象。Servlet对象由服务器创建(创建一次),request和response由Servlet容器创建(创建10次)
来看一段代码:
package com.vae.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//一般实现一个Servlet,只要继承HttpServlet类即可
public class MyServlet extends HttpServlet {
//Servlet初始化时调用的方法
@Override
public void init() throws ServletException {
super.init();
System.out.println("init....");
} //Servlet被销毁时调用的方法
@Override
public void destroy() {
super.destroy();
System.out.println("destroy...");
}
//-------doGet/doPost 核心的业务处理方法(由service方法来调用)------------
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//super.doGet(req, resp);
doPost(req, resp);
System.out.println("do service...");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//super.doPost(req, resp);
}
}
运行程序,输入url,此时,一按回车,马上就会在后台打出日志:
然后连续刷新三次网页,日志如下:
可以看到,Servelet只会初始化一次,之后的话,我们多次访问的是同一个Sevlet对象。此时,即使关掉网页,Servlet也不会销毁,只有关掉Tomcat服务器才会销毁Servlet。
需要注意的是,前台可能有get和post两种请求,但是在后台做的处理是一样的。例如:前台输入用户名密码,在后台验证的时候是不区分哪一种请求方式的。于是,如果在doGet()方法中写了代码内容,我们可以在doPost()方法中加一句:"doGet(req,resp);"即可,就可以进行重复利用(毕竟执行的都是同一段逻辑)。
三、Servlet的继承结构:
- Servlet接口:定义了Servlet应该具有的基本方法
- GenericServlet:抽象类,实现了Servlet接口。通用基本Servlet实现,对于不常用的方法在这个实现类中进行了基本的实现,将Service设计为了抽象方法,需要子类去实现
- HttpServlet:抽象类,继承了GenericServlet类。在通用Servlet的基础上基于HTTP协议进行了进一步的强化:复写了GenericServlet中的Service方法,Service方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要继承HttpServlet,然后覆写doGet或doPost方法,而不要去覆写service方法。
四、修改Servlet模板:
使用MyEclipse创建Servlet时,根据默认的Servlet模板生成的Servlet代码如下:
import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Servlet2 extends HttpServlet { /**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the GET method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
} /**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the POST method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
} }
在实际开发中,这些生成的代码和注释一般我们都用不到的,每次都要手工删除这些注释和代码,很麻烦,因此可以根据开发的实际情况修改Servlet的模板代码,改成符合实际开发需求的模板代码。
MyEclipse 10修改Servlet模板的步骤如下:
关闭MyEclipse,找到MyEclipse安装目录下的\Common\plugins文件夹,比如:D:\MyEclipse10\Common\plugins,然后找到com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar这个jar文件,如下图所示:
用压缩工具打开,注意是打开而不是解压这个jar包,如下图所示:
上图中,打开Jar包中的Templates文件夹中的Servlet.java文件,可以看到里面的模板代码:
#---------------------------------------------#
# <aw:description>Template for Servlet</aw:description>
# <aw:version>1.1</aw:version>
# <aw:date>04/05/2003</aw:date>
# <aw:author>Ferret Renaud</aw:author>
#---------------------------------------------# <aw:import>java.io.IOException</aw:import>
<aw:import>java.io.PrintWriter</aw:import> <aw:import>javax.servlet.ServletException</aw:import>
<aw:import>javax.servlet.http.HttpServlet</aw:import>
<aw:import>javax.servlet.http.HttpServletRequest</aw:import>
<aw:import>javax.servlet.http.HttpServletResponse</aw:import> <aw:parentClass>javax.servlet.http.HttpServlet</aw:parentClass> <aw:constructor name="c1">
/**
* Constructor of the object.
*/
public <aw:className/>() {
super();
} </aw:constructor> <aw:method name="doGet">
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the GET method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
} </aw:method> <aw:method name="doPost">
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the POST method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
} </aw:method> <aw:method name="doPut">
/**
* The doPut method of the servlet. <br>
*
* This method is called when a HTTP put request is received.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPut(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { // Put your code here } </aw:method> <aw:method name="doDelete">
/**
* The doDelete method of the servlet. <br>
*
* This method is called when a HTTP delete request is received.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doDelete(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { // Put your code here } </aw:method> <aw:method name="init">
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
} </aw:method> <aw:method name="destroy">
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
} </aw:method> <aw:method name="getServletInfo">
/**
* Returns information about the servlet, such as
* author, version, and copyright.
*
* @return String information about this servlet
*/
public String getServletInfo() {
return "This is my default servlet created by Eclipse";
} </aw:method>
代码模板中,删除doGet和doPost上方的注释和方法里面的代码,并在doPost方法里面添加一行doGet(request,response);效果如下:
修改好之后,保存,重启MyEclipse,就可以使用新的模板代码了:
package com.vae.servlet; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Servlet2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { } public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板的更多相关文章
- Maven 学习总结 (二) 之 生命周期与插件
五.生命周期与插件 1.Maven有三套独立的生命周期:clean.default和site. clean生命周期的目的是清理项目,default生命周期的目的是构建项目,site生命周期的目的是建立 ...
- JavaWeb之 Servlet执行过程 与 生命周期
Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet.Servlet下有一个实现类叫HttpServle ...
- [转]JavaWeb之 Servlet执行过程 与 生命周期
https://www.cnblogs.com/vmax-tam/p/4122105.html Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类 ...
- Servlet学习笔记(一):生命周期
一.Servlet 生命周期: Servlet 生命周期可被定义为从创建直到毁灭的整个过程.以下是 Servlet 遵循的过程:初始化——响应请求——终止——回收 Servlet 通过调用 init ...
- HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象
1 HTTP协议特点 1)客户端->服务端(请求request)有三部份 a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...
- JavaEE Servlet 核心方法及生命周期
做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...
- servlet的session的生命周期
谈到javaweb首先想到的就是servlet,说道servlet就会想到servlet的生命周期 说道servlet的生命周期 就绕不过servlet的三个方法init service destro ...
- Servlet执行流程和生命周期【慕课网搬】
Servlet执行流程(GET方式为例) 首先用户客户端浏览器发出Get方式(点击超链接方式)向浏览器发出请求. 服务器接收到客户端点击超链接,接收到GET请求之后,服务器到WEB.xml中<s ...
- Expo大作战(二)--expo的生命周期,expo社区交流方式,expo学习必备资源,开发使用expo时关注的一些问题
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- 【servlet】Servlet的API和生命周期]
创建时间:6.15 一.Servlet的API(生命周期) (1)Servlet接口中的方法 1)init(ServletConfig config) 何时执行:servlet对象创建的时候执行 Se ...
随机推荐
- C#中的接口实现多态
我们都知道虚方法实现多态,抽象方法实现多态等,我们今天来看看如何使用接口实现多态 1.首先我们先要来了解了解什么是接口,它存在的意识 01.接口就是为了约束方法的格式(参数和返回值类型)而存在的 02 ...
- Tomcat一些小事
1.编码问题 1.1.乱码 客户端发请GET请求,如果这个请求地址上有中文,而且也没有进行encode的时候,后端就可能接收到乱码. --解决办法 在tomcat , conf/server.xml ...
- elasticsearch分词插件的安装
IK简介 IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源项目Luen ...
- 简洁侧边wordpress博客模板
模板描述:商务领航,尽现成熟稳重的个人小站风格 响应式Web设计,自适应电脑.平板电脑.移动设备 图标字体库,自适应各种终端设备,保证图形图标清晰无锯齿,支持Retina(视网膜屏幕) ...
- RHEL7管道与重定向
文件描述符 可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作 用户可以自定义文件描述符范围是:3-num,这个最大数字,跟 ...
- Objective-C 代码规范(Code Style)
我们写出来的代码会给很多人看,为了使代码清晰简洁,方便阅读理解,都会统一遵从一定的代码规范,Objective-C同样如此. 主要参考规范: 1.Google Objective-C Style Gu ...
- clang: error: no such file or directory: xxx.pch
今天打开一个下载的例子 报clang: error: no such file or directory: xxx.pch的错 说一下解决方案 1.先在你的工程里找到这.pch文件- 2.把它现在的路 ...
- 使用网站websequencediagrams在线画时序图
在线画时序图的网站:https://www.websequencediagrams.com/ 该网站提供拖拉图形和编写脚本代码2个方式来制作时序图,同时提供多种显示风格. 实例: 1.脚本代码: ti ...
- 每日Scrum--No.5
Yesterday:学习并编写代码 Today:组织小组开一次阶段性的总结会议:讨论需求分析中存在的问题:继续学习和编写代码:总结前阶段代码出现的问题 Problem:编程要注意很多的特殊情况,程序成 ...
- Effetive Java 22 Favor static member classes over nonstatic
Nested class types Usage and remark Advantage Disadvantage static member classes Use for public help ...