版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章Servlet编程7.1从CGI到Servlet7.2Servlet生命周期7.3Servlet的开发实例
【学习提示】Servlet的本质就是一个Java类,目的是为客户服务。它的任务是获取一个客户的请求,对请求进行相应处理后,再发回一个响应。本章重点讲解Servlet如何获取和使用客户端请求,怎样发送响应或者不发送响应直接进行重定向让浏览器完成工作,以及Servlet的整个开发、配置和使用流程。学习Servlet是掌握JSP的基础和前提,因为JSP在首次运行时都会被Tomcat容器自动转换为Servlet,再次运行时由Tomcat直接调用该Servlet。
7.1.1CGI简介
与浏览器端技术从静态向动态的演进过程类似,Web服务端的技术也是由静态向动态逐渐发展并完善起来的。早期的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,直到通用网关接口(CommonGatewayInterface,CGI)技术的产生才使得Web服务器可根据运行时的具体情况(如数据库的实时数据)动态生成HTML页面。7.1从CGI到ServletCGI是外部应用程序与Web服务器交互的一个标准接口。1993年,CGI1.0的标准草案由美国国家超级计算机应用中心(NationalCenterforSupercomputingApplications,NCSA)提出,并于1995年制定了CGI1.1标准。把遵循CGI标准编写的服务器端的可执行程序称为CGI程序。随着CGI技术的普及,聊天室、论坛、电子商务、搜索引擎等各式各样的Web应用蓬勃兴起,使得互联网真正成为信息检索、信息交换和信息处理的超级工具。
CGI技术允许服务端的应用程序根据客户端的请求,动态生成HTML页面,这使客户端和服务器端的动态信息交换成为了可能。绝大多数的CGI程序被用来解释处理用户在HTML文件的表单中所输入的信息,然后在服务器进行相应的处理并将结果信息动态编写为HTML文件反馈给浏览器。
CGI程序大多是编译后的可执行程序,其编程语言可以是C、C++、Pascal或Perl等程序设计语言。其中,Perl的跨操作系统、易于修改等特性使它成为CGI的主要编程语言。目前几乎所有的Web服务器都支持CGI。CGI程序的工作过程如图7-1所示,具体流程如下:
(1)用户指示浏览器访问一个URL;
(2)浏览器通过HTML表单或超链接请求指向一个CGI程序的URL;
(3)
Web服务器收到请求,并在服务器端执行所指定的CGI程序;
(4)
CGI程序根据参数执行所需要的操作;
(5)
CGI程序把结果格式化为HTML网页;
(6)
Web服务器把结果返回到浏览器中。
图7-1CGI的基本操作
虽然CGI技术为Web服务器端带来了动态生成HTML文档的能力,但CGI的缺点也是较为明显的:CGI的应用程序一般都是一个独立的可执行程序,每一个用户的请求都会激活一个CGI进程。当用户请求数量非常大时,大量的CGI程序就会吞噬系统资源,造成Web服务器运行效率低下。另外,在CGI程序设计过程中,代码编写方式(在语言中不断嵌入HTML文档片段)、调试等环节非常繁琐,开发效率不高。7.1.2ISAPI与NSAPI简介
ISAPI(InternetServerAPI)与NSAPI(NetscapeServerAPI)是分别由Microsoft公司和Netscape公司定义的Web服务器应用程序编程接口。虽然两种技术所支持的Web服务器产品不同,但它们的定位和原理相似,以下主要讨论ISAPI。
ISAPI与CGI的工作原理相似,都是通过交互式网页获取用户输入的信息,然后交服务器后台处理。ISAPI与CGI最大的区别在于:在ISAPI下建立的应用程序都是以动态链接库(DLL)的形式存在的。基于ISAPI进程需要的系统资源也较CGI少,因此ISAPI的运行效率要显著高于CGI程序。可以使用ISAPI筛选器来过滤浏览器端与服务器端之间来回传送的数据,如登录数据或URL请求等。当发生选定事件时相应的筛选器就被调用,通过这种机制,网站可以监视或更改浏览器端与服务器端之间传送的数据。ISAPI筛选器常用来实现网站的权限控制、自定义加密、自定义压缩和用户访问日志等功能。
能够用来开发ISAPI程序的语言有VisualC++、VisualBasic、BorlandC++
和Delphi等,支持ISAPI程序运行的Web服务器主要是Microsoft公司的IIS(InternetInformationServices)服务器。支持NSAPI程序运行的Web服务器主要是Netscape公司的EnterpriseServer和Sun公司的JavaWebServer等产品。7.1.3Servlet简介
与CGI程序类似,Servlet程序也是一种Web服务器端的应用程序,可以根据用户的需求动态生成Web页面。Servlet程序由Java语言开发,由Web服务器进行加载,并在服务器端的Java虚拟机中运行。
在大量用户访问的Web服务器上,Servlet的优点表现在它的执行速度快于CGI程序。每个用户请求被激活成一个线程而非单独的进程,这意味着服务器端处理请求的系统开销将明显降低。这一点非常类似于ISAPI的运行机理。
Servlet的基本结构代码如下:
importjava.io.*;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/*上面是servlet必须引入的类*/
publicclasstestextendsHttpServlet{//Servlet继承父类HttpServlet
publictest(){//该对象的构造方法
super();
}
publicvoiddestroy(){//销毁该Servlet
super.destroy();//继承父类的destroy()方法
}
publicvoiddoDelete(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{/*当收到一个HTTP的delete请求时调用该方法,参变量request表示从客户端到服务器端发送的请求,参变量response表示从服务器端到客户端发送的响应,当发生错误时抛出ServletException和IOException异常*/
}
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
/*当客户端发送请求的方式为get时调用该方法,即通过浏览器直接请求该Servlet或者表单中method的值为get*/
response.setContentType("text/html");
PrintWriterout=response.getWriter();
out.println("<!DOCTYPEHTMLPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\">");
out.println("<HTML>");
out.println("<HEAD><TITLE>AServlet</TITLE></HEAD>");
out.println("<BODY>");
out.print("Thisis");
out.print(this.getClass());
out.println(",usingtheGETmethod");
out.println("</BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
/*当客户端发送请求的方式为post时调用该方法,即表单的method值为post*/
doGet(request,response);//直接调用doGet方法
}
publicvoiddoPut(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//当接收到put请求时调用该方法
//Putyourcodehere
}
publicStringgetServletInfo(){//返回Servlet的相关信息,例如作者等
return"ThisismydefaultservletcreatedbyEclipse";
}
publicvoidinit()throwsServletException{//Servlet的初始化方法
//Putyourcodehere
}
}
在上述Servlet的所有方法中doGet()和doPost()方法体现了Servlet的主要功能,要根据具体的请求方式来确定写doGet()方法还是doPost()方法。
前面章节中介绍了同样是基于Java的网站设计技术Applet。与Servlet比较,两者具有的相似之处包括:
(1)它们都不是独立的应用程序,没有main()方法;
(2)它们都不是由用户或程序员调用,而是由另外一个应用程序(浏览器或服务器)
调用;
(3)它们都包含init()和destroy()方法,用来定义生命周期。但Applet与Servlet又具有很大不同:Applet具有图形界面,在客户端运行;而Servlet则没有图形界面,在服务器端运行。
最早支持Servlet技术的是JavaWebServer。此后,基于Java的稳定性和跨平台性等优点,大量的Web服务器开始支持标准的ServletAPI。
Servlet容器(即Tomcat)会全盘控制Servlet的一生,它会创建请求和响应对象,为Servlet创建一个新线程或分配一个线程,同时调用Servlet的service()方法,传递请求和响应对象的引用作为参数。容器还会对创建的Servlet实例进行适当的管理,服务器内存不够时,要撤销较老的未用实例。因此,每个Servlet都有一个生命期。7.2Servlet生命周期容器创建一个实例时,生命期开始;容器把该实例从服务中删除并撤销时,生命期终止。如图7-2所示的Servlet生命周期说明了初始化和撤销等重要事件何时发生。
图7-2Servlet的生命周期上述生命周期可以概括为以下四个步骤:
(1)第一次访问一个Servlet时,Web容器会加载类并创建它的一个实例。所谓的Web容器就是为Servlet提供运行环境,Servlet的运行必须依赖于Web容器,不能独立于容器运行。前面提到的Tomcat即为Web容器。当容器收到第一个请求时,会创建一个Servlet实例,即运行Servlet类的无参数构造函数。
(2)如果需要,要初始化这个实例。用构造函数创建的实例只是一个普通的对象,而不是一个Servlet。要想成为一个Servlet,必须进行初始化,使其具备一些“Servlet特性”,能为客户请求提供服务。初始化工作由容器即Tomcat完成。对于创建的每个Servlet实例,初始化工作应当只完成一次,而且要通过调用该Servlet的init()方法完成。服务器一旦初始化了一个Servlet,这个Servlet就处于准备状态,可以在任何时刻调用此Servlet来处理到来的请求。
(3)维护这个实例,处理到来的请求。每个客户请求到来时,容器会开启一个新线程,或者从线程池分配一个线程,并调用Servlet的service()方法。该方法根据请求的HTTP方法(GET、POST等)来调用doGet()或doPost()方法。一般在doGet()或doPost()中写客户自己的代码。客户的Web应用想要做什么,就由这个方法负责。
容器可以在Servlet的这个阶段对该Servlet调用多次service()方法,通过运行多个线程来处理对一个Servlet的多个请求,如图7-3所示。对应每个客户请求,会生成一对新的请求和响应对象。
图7-3Servlet线程分配
(4)如果需要为新的Servlet实例让出空间,则删除Servlet实例。Servlet的生命周期中,大多数时间一般都是在为到来的请求提供服务。如果一个服务器负载过重,可能会出现这样一些情况,即需要加载新的Servlet,但是没有足够的内存资源来保证安全的加载。在这些情况下,容器中的资源管理逻辑就可能会从服务中选择删除一个Servlet实例。在所有情况下,这个资源管理逻辑都会选择删除最不可能用到的Servlet实例。在删除Servlet之前,Servlet规范要求容器调用该Servlet的destroy()方法,然后进行垃圾收集。
下面通过一个简单Servlet开发、配置与调用的实例展示Servlet的具体使用方法及其生命周期。7.3Servlet的开发实例7.3.1编写Servlet代码
选择合适的编辑工具,编写类名为HelloWorld的Servlet源文件,具体代码如下:
HelloWorld.java
importjava.io.*;
importjavax.servlet.http.*;
importjavax.servlet.*;
/*上面是Servlet必须引入的3个类*/
publicclassHelloWorldextendsHttpServlet{
publicHelloWorld(){//构造函数
super();
}
/*下面的doGet()方法处理以Get方式提交过来的数据*/
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,ServletException
{
response.setContentType("text/html");
PrintWriterout=response.getWriter();
//下面的代码实现向客户端浏览器输入内容
out.println("<html>");
out.println("<head>");
out.println("<title>HelloWorld</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>HelloWorld!</h1>");
out.println("</body>");
out.println("</html>");
}
//下面的doPost()方法处理以Post方式提交过来的数据
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
publicvoidinit()throwsServletException{//该Servlet装载到容器后将自动执行的初始方法
//放置初始化代码
}
publicvoiddestroy(){//销毁时调用的方法
super.destroy();
}
}在编写Servlet时,重点要根据请求数据的提交方式重写doGet或doPost方法,当需要处理表单提交的数据时,可以依据form属性method的取值来确定是重写doGet还是doPost方法。客户端提交的数据均封装在request对象中,通过调用该对象的相应方法可以获取提交的参数值。对request对象的详细讲解参见9.2节。7.3.2编译和部署Servlet
1.编译Servlet
如果采用MyEclipse编写Servlet代码,点击保存后,会自动生成对应的字节码文件(即
.class文件)。如果没有采用开发工具,则可以直接在命令行窗口中运行javac命令将HelloWorld.java文件编译成字节码文件,如下图7-4所示。
图7-4Servlet的class文件
2.部署Servlet
所谓部署Servlet就是把
.class文件放到其所属Web服务应用文件下的/WEB-INF/
classes/目录下。如果用package语句指明了Servlet类所在的包,则要在classes目录下按照包结构创建子文件夹。
本节创建的HelloWorldServlet用于名为Chapter7的Web应用。它在Tomcat容器中的位置如下图7-5所示。
图7-5HelloWorld.class文件的部署7.3.3配置Servlet
在Web应用的web.xml文件中配置Servlet(HelloWorld.class)的信息,包括Servlet定义逻辑名和访问路径(相对URL地址),具体代码如下:
web.xml
<web-appversion="2.5"xmlns="/xml/ns/javaee"
xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="http:
///xml/ns/javaee/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>MyServlet</servlet-name>
<!--标签servlet-name用于给servlet起一个名字,例如MyServlet,这是一个虚构的名字,只能在Web应用的部署描述文档(即Web.xml)的其他部分使用-->
<servlet-class>HelloWorld</servlet-class>
<!--标签servlet-class用于指定名为MyServlet的Servlet对应的类文件的完全限定名-->
</servlet>
<servlet-mapping>
<!--标签servlet-mapping用于规定前面起好名字的Servlet的访问路径-->
<servlet-name>MyServlet</servlet-name>
<!--直接使用前面创建的Servlet名表示要为哪个Servlet规定访问路径-->
<url-pattern>/Servlet-example</url-pattern>
<!--标签url-pattern的值“/Servlet-example”表示调用MyServlet的URL路径,以Web应用的路径为根目录,譬如在本书中该Servlet绝对调用路径为:http://localhost:8080/Chapter7/Servlet-example-->
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
web.xml的具体结构信息参见6.4.2节。从上述实例可以看出在web.xml文档中必须要为Servlet配置两个信息:一个是给Servlet起名字并指定其对应的class文件,另一个是规定该Servlet的相对访问路径并建立其访问路径之间的映射关系。7.3.4测试Servlet
部署包含该Servlet的Web应用(本书中为Chpater7),启动浏览器,访问http://localhost:
8080/Chapter7/Servlet-example,运行名为MyServlet的Servlet,显示结果如图7-6所示。
图7-6MyServlet的运行结果7.3.5Servlet初始化参数
对于经常发生变化的值不适宜在Servlet类中硬编码写入,而可以将其作为Servlet的初始化参数写到web.xml文档中。例如,在Servlet中要打印输出email地址:
out.println("lianxi@");
如果email有变化怎么办?必须重新编译Servlet,而这样就会大量增加开发人员的工作量,所以可以先将其作为Servlet的初始化参数配置到web.xml中。
Servlet初始化参数的创建和使用步骤如下:
(1)在web.xml中配置Servlet
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地面推广活动执行合同(2篇)
- 地下人行道建设顶管施工合同
- 涂料生产销售合作合同
- 油气管道施工安全合同模板
- 冒险剧编剧招募合同模板
- 市政道路翻新临时施工协议
- 道教宫观瓷砖施工合同
- 体育场馆配套桥梁施工合同
- 临时会计聘用合同模板
- 2024版水利堤防工程施工合同
- GC2级压力管道安装质量保证体系文件编写提纲
- ABB断路器参数调试讲义
- 管廊维护与运营绩效考核评分表
- 预应力混凝土简支小箱梁大作业计算书
- 阳宅形法及峦头
- 燃烧机论文定型机加热论文:天然气直燃热风技术在定型机中的应用
- 尾矿库施工组织设计
- 投标文件封标用封面、密封条11
- 300MW火电厂水汽氢电导率超标的原因及处理方法
- 国际文凭组织IBO简介
- 星巴克营销策划方案(共24页)
评论
0/150
提交评论