Java服务器高级编程(二)Java服务器高级编程(二)_作者.pdf

上传人:asd****56 文档编号:70344442 上传时间:2023-01-19 格式:PDF 页数:18 大小:1.50MB
返回 下载 相关 举报
Java服务器高级编程(二)Java服务器高级编程(二)_作者.pdf_第1页
第1页 / 共18页
Java服务器高级编程(二)Java服务器高级编程(二)_作者.pdf_第2页
第2页 / 共18页
点击查看更多>>
资源描述

《Java服务器高级编程(二)Java服务器高级编程(二)_作者.pdf》由会员分享,可在线阅读,更多相关《Java服务器高级编程(二)Java服务器高级编程(二)_作者.pdf(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、下载第2章s e r v l e t简介在本书中我们要使用的一个关键工具就是 Java Servlet API。s e r v l e t站在了Java We b应用开发的最前沿,它为服务器端代码和基于 We b的客户之间通信提供了一条容易的途径,因此,它成为服务器端编程的核心,我们将在本书的许多例子中使用 s e r v l e t。在接下来的几章中,我们将深入研究s e r v l e t的工作方式以及servlet API提供的不同工具,同时,也包括一些我们自己构造的工具。Servlet API提供了一个执行服务的类的通用模型,这是它最基本的定义。实事上,根据它的名字,s e r v l

2、 e t是简单、小巧、专门化的服务器。为了避免s e r v l e t程序员考虑连接网络、获取请求、产生格式正确的响应等问题的细节,这些任务都由s e r v l e t容器(c o n t a i n e r)完成,也称这种容器为s e r v l e t引擎(e n g i n e)。这种容器把由任何协议使用的请求转换成 s e r v l e t能够理解的对象,并给s e r v l e t一个能用来发送响应的对象;容器也用来管理s e r v l e t的生命周期,这也将会在本章中讨论到。servlet API库和s e r v l e t引擎作为Java Servlet Devel

3、opment Kit(J S D K)的一部分,可从如下地址下载:h t t p:/j a v a.s u n.c o m/p r o d u c t s/s e r v l e t/。对于本书中的代码,我们使用 JSDK 2.1版,但因为一些 s e r v l e t容器仅和版本 2.0兼容,我们将试图解释 2.1版带来的变化。要想得到 J S D K的S e r v l e t R u n n e r的更多信息或其他s e r v l e t引擎的详情,请查看本书附录。我们将在本章后面简单解释如何用S u n公司的S e r v l e t R u n n e r测试s e r v l

4、e t。本章主要内容如下:解释s e r v l e t容器所扮演的角色。讨论组成servlet API的基础类和接口。完整地开发一个简单s e r v l e t。讨论与s e r v l e t性能有关的话题。通过构造一个作为S M T P邮件客户的s e r v l e t,来说明表单处理技术以及H T M L的生成。2.1 servlet容器s e r v l e t容器负责处理客户请求、把请求传给 s e r v l e t并把结果返回给客户。对于不同的程序,容器的实际实现也许会有所变化,但容器与 s e r v l e t之间的接口是由servlet API定义好的,这个接口定义了

5、s e r v l e t容器在s e r v l e t上要调用的方法及传递给s e r v l e t的对象类。s e r v l e t的生命周期一般如下:servlet容器创建s e r v l e t的一个实例。容器调用这个实例的i n i t()方法。如果容器对该s e r v l e t有请求,则调用此实例的s e r v i c e()方法。容器在销毁本实例前调用它的d e s t r o y()方法。销毁并标记该实例以供作为垃圾收集。这就是一个 s e r v l e t的生命周期。接口规定了在调用 s e r v i c e()方法前,应首先完成 s e r v l e t

6、的第2章第s e rv l e t简介第第1 3i n i t()方法。同样,在s e r v l e t被销毁之前要先调用d e s t r o y()。一旦请求了一个s e r v l e t,就没有办法阻止s e r v l e t容器执行一个完整的生命周期,尽管这不是最优的,但却是接口所要求的。实际上,s e r v l e t容器有必要在s e r v l e t启动时创建它的一个实例,或者说当 s e r v l e t首次被调用时,并保持这个s e r v l e t实例在内存中,让它对所有的请求进行处理。容器可决定在任何时间把这个实例从内存中移走。例如,s e r v l e

7、t有一段时间没有被调用过,或者是容器正在关闭时,如果上述假设发生了,容器很容易把实例移走;当然,得先调用 d e s t r o y()方法。因此,在典型的模型中,s e r v l e t容器为每个s e r v l e t创建一个单独的实例(尽管没有理由能解释为什么该引擎不创建多个实例)。然而,我们还没有考虑到服务器端编程的更多问题。如果s e r v l e t的s e r v i c e()方法正在运行,而s e r v l e t容器又收到另一个请求时会发生什么情况呢?s e r v l e t容器会等到正在运行的 s e r v i c e()方法完全运行结束后再调用它,或者(你也

8、许会为猜到),它会创建另一个程序执行线程来调用 s e r v i c e()。由于没有什么规定来约束一个线程在某时只能调用s e r v i c e()一次,因此,在写 s e r v l e t时,我们必须保证我们的代码是线程安全的并改进J a v a的s y n c h r o n i z e d命令。事实上,s e r v l e t容器并不会每接到一个请求就创建一个新线程,而是使用一个线程池来动态地将线程分配给到来的请求,但是从 s e r v l e t的观点来看,其效果是完全相同的。因此,我们可以勾画一幅典型的 s e r v l e t容器的工作示意图。图 2-1说明了一个s

9、e r v l e t的装入,它先后服务于两个紧接在一起的请求,然后在服务器关闭时卸载它。图2-1线程线程servlet执行初始化执行服务执行服务执行清除Servlet容器创建线程池实例化servlet调用的方法将请求分配给线程调用service()方法调用service()方法将请求分配给线程阻塞所有后面的请求直到活动线程结束终止线程池调用destroy()方法终止servlet容器关闭HTTP请求1HTTP请求2关闭初始化HTTP响应1HTTP响应2下载我们有必要在这里注意 s e r v l e t容器的某些特性。既然 s e r v l e t容器直接和s e r v l e t通信,

10、因而它们一般应该由纯粹的 J a v a代码编写而成。不幸的是,大多数的 We b服务器都用其他的像 C和C+这类语言写成。因此,像 S u n的Java Web Server和有J S D K支持的S e r v l e t R u n n e r这类1 0 0%纯J a v a代码的We b服务器,都有它们自己的 s e r v l e t容器;其他的像 A p a c h e和微软的I I S这类的We b服务器需要一个独立的 J a v a程序实际运行 s e r v l e t。在这种情况下,就需要用一个插件或模块来处理We b服务器本身与s e r v l e t容器之间的通信。比

11、如,对于 Apache JServ来说,这个通信实际上是由一个特殊的称为A J P v 1.1的I n t e r n e t协议进行处理;根据该协议,We b服务器向s e r v l e t发出请求,s e r v l e t容器把结果传回服务器。在这种情况下,容器和 We b服务器甚至不需要在同一台机器上运行。由于s e r v l e t和We b服务器联系得这么紧,因此,它就可用来大大扩展 We b服务器的功能。它甚至可用来提供最基本的功能:对一个 s e r v l e t来说,让它完成一个标准We b服务器的工作过程是完成有可能的,它能把一个 U R L请求映射为一个 H T M

12、 L文件的路径并返回相应的 H T M L文件。S u n的Java Web Server使用s e r v l e t来完成包括C G I的处理、J S P的执行、H T M L模板及服务器端导入(Server Side Includes,S S I)在内的所有事情。必须明确指出的是,s e r v l e t几乎可用在We b服务器上执行你想执行的任何任务。2.1.1 servlet API前面我们从s e r v l e t的观点来讨论了s e r v l e t,现在将详细描述 s e r v l e t接口。要开发s e r v l e t,首先要获得一个Java Servlet D

13、evelopment Kit(J S D K)的拷贝,该拷贝包括所有用来开发和运行s e r v l e t的类及接口函数,同时还包括一个叫 S e r v l e t R u n n e r的成熟的s e r v l e t容器。类和接口组成了两个J a v a包:J a v a x.S e r v l e t和J a v a x.s e r v l e t.h t t p,前者提供我们前面讨论过的基本接口,后者则提供从处理H T T P请求的特殊工具的一般s e r v l e t接口中派生出来的类。1.servlet接口public interface Servlet如前面所讨论的那样,

14、S e r v l e t生命周期由j a v a x.s e r v l e t.s e r v l e t接口定义。当你在写s e r v l e t时,必须直接或间接地实现这个接口。你可能会趋向于间接实现:通过扩展j a v a x.s e r v l e t.G e n e r i c S e r v l e t或者j a v a x.s e r v l e t.h t t p.H t t p S e r v l e t类。在实现s e r v l e t接口时,必须实现以下5个方法:(1)init()方法public void init(ServletConfig config)th

15、rows ServletException一旦对s e r v l e t进行实例化后,s e r v l e t容器就调用i n i t()方法。容器会把一个S e r v l e t C o n f i g类型的对象传递给i n i t()方法,这样s e r v l e t的实例就可把与引擎相关的配置数据保存起来供以后使用。如果 i n i t()方法没有正常结束的话,i n i t()方法会抛出一个 S e r v l e t E x c e p t i o n。一旦抛出S e r v l e t E x c e p t i o n,s e r v l e t就不会再执行,而随后对它的

16、调用会导致容器对它重新装入,并再次运行I n i t()方法。接口规定对任何 s e r v l e t的实例,i n i t()方法只能被调用一次,在任何请求传给s e r v l e t之前,i n i t()方法可在不抛出S e r v l e t E x c e p t i o n的情况运行完毕。(2)service()方法14第第J a v a服务器高级编程下载public void service(ServletRequest req,ServletResponse res)throwsS e r v l e t E x c e p t i o n,I O E x c e p t

17、i o n只有在成功地初始化 s e r v l e t以后,才能调用s e r v i c e()方法来处理用户请求。s e r v i c e()方法有两个参数:S e r v l e t R e q u e s t和S e r v l e t R e s p o n s e对象,请求对象S e r v l e t R e q u e s t提供了访问初始请求数据的方法和字段,响应对象S e r v l e t R e s p o n s e提供了s e r v l e t构造响应的方法。(3)destroy()方法public void destroy()在任何时候都必须考虑到,s e

18、r v l e t容器可以决定中止s e r v l e t服务。在内存不够或We b服务器关闭时都会发生这种情况。在 s e r v l e t容器调用此方法之前,必须给 s e r v i c e()线程足够长的时间来结束执行(也许需要很长一段时间),因此,接口规定了当 s e r v i c e()正在运行时d e s t r o y()将不会被执行。(4)getServletConfig()方法public ServletConfig getServletConfig()我们已经知道,在 s e r v l e t初始化时,s e r v l e t引擎传递进来一个 S e r v l

19、 e t C o n f i g对象并保存在s e r v l e t的实例中。S e r v l e t C o n f i g对象允许访问两项内容:初始化参数和 S e r v l e t C o n t e x t对象。初始化参数通常由 s e r v l e t容器在文件中指定,允许在运行时向s e r v l e t传递有关调度信息;S e r v l e t C o n t e x t对象为s e r v l e t提供了关于 s e r v l e t容器的信息,这一点将在第 5章中进行讨论。g e t S e r v l e t C o n f i g()方法可以让s e r

20、v l e t在任何时间获得该对象及其配置信息。(5)getServletInfo()方法public String getServletInfo()本方法会返回一个S t r i n g对象,该对象包含s e r v l e t的信息(如开发者、创建日期、描述信息等等)。该方法也可用于 s e r v l e t容器。例如,s e r v l e t容器可以显示一张具有描述信息的 s e r v l e t列表。2.GenericServlet类public abstract class GenericServlet implements Servlet,ServletConfig,Seri

21、alizableG e n e r i c S e r v l e t类提供了s e r v l e t接口的基本实现部分。你可能注意到这个类被声明为 a b s t r a c t,这是因为 s e r v i c e()方法声明为 a b s t r a c t,也就意味着如果你要扩展这个类,你必须自己实现s e r v i c e()方法;记住如果一个方法被声明为 a b s t r a c t,则类本身也要声明为 a b s t r a c t。其他生存周期的方法实现如下:i n i t(ServletConfig conf)方法把s e r v l e t C o n f i g对象

22、存储在一个private transient(私有临时的)实例变量(叫c o n f i g)中,g e t S e r v l e t C o n f i g()方法返回指向本对象的指针。当然,这意味着如果你不小心重载此方法,你就不能使用 g e t S e r v l e t C o n f i g()来获得S e r v l e t C o n f i g对象。正因如此,如果你确实想重载的话,一定记着包含对 s u p e r.c o n f i g(c o n f)的调用。为解决这个问题,2.1版的A P I为G e n e r i c S e r v l e t类提供了一个重载的没有

23、参数的 i n i t()方法。现在,在i n i t(S e r v l e t C o n f i g)方法结束时,有一个对 i n i t()的调用,它在目前的G e n e r i c S e r v l e t中是空的。通过重载i n i t(),我们就能包含初始化代码而不必担心调用 s u p e r.i n i t(c o n f)。2.1版的A P I里有一些新东西就是G e n e r i c S e r v l e t类实现了S e r v l e t C o n f i g接口,这使得s e r v l e t开第2章第s e rv l e t简介第第1 5下载16第第J

24、 a v a服务器高级编程下载发者在不用获得 S e r v l e t C o n f i g对象情况下直接调用ServletConfig 方法,这些方法是g e t I n i t P a r a m e t e r()、g e t I n i t P a r a m e t e r N a m e s()和g e t S e r v l e t C o n t e x t(),每种方法只需简单地调用和已存储的s e r v l e t C o n f i g对象相关的方法。G e n e r i c S e r v l e t类包含两个写s e r v l e t日志的方法,它们实际上调

25、用的是 s e r v l e t C o n t e x t上对应的方法。第一个方法log(String msg)将s e r v l e t的名称和m s g参数值写到s e r v l e t容器的日志中,另一个方法log(String msg,Throwable cause)除了包含s e r v l e t名字和报文外还包含一个异常。要了解S e r v l e t C o n t e x t的l o g方法更多的信息,请参见第5章。下面的类包含在j a v a x.s e r v l e t.h t t p包里。3.HttpServlet类H t t p S e r v l e t

26、类扩展了G e n e r i c S e r v l e t类并为s e r v l e t接口提供了与H T T P更相关的实现代码。这就像所有s e r v l e t要扩展的类一样,通过实现其他的类,可以扩展 G e n e r i c S e r v l e t类提供了处理其他类型网络服务的框架,但H T T P是s e r v l e t使用的最常用的协议。(1)service()方法s e r v i c e()方法被H t t p S e r v l e t类用来作为H T T P请求的分发器,这个方法在任何时候都不能被重载。当请求到来时,s e r v i c e()方法将决

27、定请求类型(G E T、P O S T、H E A D、O P T I O N S、D E L E T E、P U T和T R A C E。关于H T T P更多的信息,请参见附录A),并把请求分发给相应的处理方法(d o G e t()、d o P o s t()、d o H e a d()、d o O p t i o n s()、d o D e l e t e()、d o P u t()和d o Tr a c e())。每个这种d o X x x()方法具有和上面的第一个s e r v i c e相同的形式,即用H t t p S e r v l e t R e q e u s t和H t

28、 t p S e r v l e t R e s p o n s e作为参数,定义S e r v l e t E x c e p t o n和I O E x c e p t i o n两个异常。为了写出响应特定类型的H T T P请求的s e r v l e t,我们必须重载相应的d o X x x x()方法。如果s e r v l e t收到一个H T T P请求而你并没有重载相应的 d o X x x()方法,它就会返回一个说明此方法对本资源不可用的标准 H T T P错误。(2)getLastModified()方法protected long getLastModified(http

29、ServletRequest req)此方法以毫秒形式返回自 G M T时间1 9 7 0年1月1日0时0分0秒以来最近一次修改 s e r v l e t的时间,缺省值是返回一个负数表示修改时间未知。当处理 G E T请求时,调用此方法可知道 s e r v l e t最近一次修改的时间,服务器就可决定是否把结果从缓存中去掉。4.HttpServletRequest接口public interface HttpServletRequest extends ServletRequest要理解此接口,需知道一点关于H T T P是如何把数据传给We b服务器的。H T T P协议允许你在发请求时

30、发送参数。在 G E T请求中,这些参数就以查询串的形式放在所请求的 U R L的末尾。在P O S T请求中,这些参数包含在请求体内。不管是在哪种情况下,它们都是关键字/值对。然而,H T T P并不要求这些关键字是唯一的对一些关键字,可以是一个值的列表,这是由一般作为H T T P请求参数源的H T M L表单属性所决定的。当你创建H T M L表单时,使用 I N P U T标记符来指定控件。每一个控件都有一个 T Y P E,如C H E C K B O X、T E X T或者S U B M I T,同样还可以有一个N A M E(名称)和/或一个VA L U E(值)。N A M E

31、属性定义了返回给服务器的值所对应的关键字;对不同的控件,VA L U E属性有不同的作用。很明显,如果我们给多个 I N P U T标记符赋予相同的名字,在请求中就会出现同一关键字而有几个关键字/值对。表2-1说明了对于不同类型的表单控件发送给服务器的值以及 VA L U E属性是怎样影响这些值的。表2-1控 制 类 型描述返 回 值T E X T单单行文本输入框,VA L U E属性作为其缺省值单用户输入的文本PA S S W O R D单单行密码输入字段(将输入字符显示为*)单用户输入的文本C H E C K B O X单标准的复选框单如果选中,则返回 VA L U E属性(或如果为指定,

32、则为 o n)如未选中,则不返回关键字/值对R A D I O单标准的单选按钮。具有相同N A M E属性的按钮组单仅返回被选中的单选按钮的成一个按钮,因而只能选中一个VA L U E属性S U B M I T单发送按钮。用VA L U E属性作为按钮的标题单除非给出N A M E属性,否则无返回值。VA L U E的缺省值为S u b m i tH I D D E N单能被用户修改的表单字段。有关怎样将它用于单VA L U E属性We b应用中的详细情况,请参见第4章除表2-1种列出的外,还存在其他的控件,但所列出的控件足以说明问题了。对于多个控件取相同名字最直接的原因是创建单选按键集以及复

33、选框集;单选钮返回被选中的值,复选框返回所有被选中的值。所有实现H t t p S e r v l e t R e q u e s t接口的对象(比如从s e r v l e t引擎传递的H T T P请求对象)都能让s e r v l e t通过自己的方法访问所有请求数据。下面就是一些用来获取表单数据的基本方法,其他方法在以后需要时也会介绍。(1)getParameter()方法public String getParameter(String key)本方法试图将根据查询串中的关键字定位相应的参数并返回其值。如果对于给定的参数有多个值,则会返回列表中的第一个值。(2)getParamete

34、rValues()方法public String getParameterValues(String key)如果一个参数可以返回多个值,比如说复选框集合,你可以用此方法来获得对应参数的所有值。记住,这将返回所有被选中复选框的值,没有什么方法可以查找未被选中的复选框的值。(3)getParameterNames()方法public Enumeration getParameterNames()此方法返回一个E n u m e r a t i o n对象,它包括对应请求的所有参数名字的列表。第2章第s e rv l e t简介第第1 7下载H t t p S e r v l e t R e s

35、p o n s e提供了更多的获取客户信息的方法(比如用 c o o k i e),我们将在后面会讨论它们。5.HttpServletResponse接口public interface HttpServletResponse extends ServletResponses e r v l e t引擎提供了一个实现这个接口的对象并通过 s e r v i c e方法将它传递给 s e r v l e t。通过H t t p S e r v l e t R e s p o n s e对象及其方法,s e r v l e t可以修改响应头并返回结果。下面是当你把结果传给调用者时需要知道的两个基本

36、方法,其他的方法在需要时也会介绍。(1)setContentType()方法public void setContentType(String type)在给调用者发回响应前,必须用此方法来设置 H T T P响应的M I M E类型。它可以是任何有效的M I M E类型,当给浏览器返回 H T M L时,就应是“t e x t/h t m l”类型。我们在第1 3章会见到其他M I M E类型。(2)getWriter()方法public PrintWriter getWriter()throws IOException此方法将返回P r i n t Wr i t e r对象,你可把s e

37、r v l e t的结果作为文本返回给调用者。P r i n t Wr i t e r对象自动把J a v a内部的U n i C o d e编码字符转换成正确的编码以便客户端能够阅读。对于如何改变编码来处理国际字符集,请参见第 1 9章。通过使用P r i n t Wr i t e r对象,你就可以使用 P r i n t l n(S t r i n gt x t)方法把数据写到响应对象里。(3)getOutputStream()方法public ServletOutputStream getOutputStream()throws IOException此方法返回S e r v l e t

38、 O u t p u t S t r e a m对象,它是j a v a.i o.O u t p u t S t r e a m的一个子类。这个对象用来向客户发送二进制数据。我们在第 6章会看到怎样使用这个方法。你只能从H t t p S e r v l e t R e s p o n s e对象获得输出对象。如果其中一个方法被调用时你试图运行这些方法中的一个,你会得到I l l e g a lSt a t e E x c e p t i o n异常。(4)setHeader()方法public void setHeader(String name String value)此方法用来设置送回

39、给客户的H T T P响应头。有一些快捷的方法用来改变某些常用的响应头,但有时你也需要直接调用此方法。2.1.2 servlet的构造到目前为止,我想你一定迫不及待地想知道 s e r v l e t是什么样以及它是如何工作的。在深入讨论之前,现在让我们先来编写一个 s e r v l e t并学习它是如何工作的。为了编译下面的代码,需要从 h t t p:/j a v a.s u n.c o m/p r o d u c t s/s e r v l e t/处获得一份J S D K拷贝。如果你使用的是Java 2,只需简单地把s e r v l e t.j a r从J S D KL I B移到

40、 J D K J R E L I B E X T文件夹下。如果你使用的是JDK 1.1,则需要把J S D K L I B S E RV L E T.J A R加入C L A S S PAT H变量中。你可以用你所喜欢的任何 s e r v l e t引擎去测试下面的代码。在本书末尾,你可以找到同 J S D K18第第J a v a服务器高级编程下载一起发行的关于Java Web Server、Apache Web Server和S e r v l e t R u n n e r的实用程序。在我们的第一个例子中,将编写一个传统的“Hello Wo r l d”程序;它虽然不是原始的,但能够满

41、足我们的需要。首先来看一看完整的源代码。既然我们已经解释了j a v a x.s e r v l e t和j a v a x.s e r v l e t.h t t p包,这里就不应该有什么疑问。下面我们来具体分析代码的每一部分。1.引入s e r v l e t包开发任何 s e r v l e t的第一件事就是包含所有需要的 J a v a类库。这里我们需要的 s e r v l e t包是j a v a x.s e r v l e t和j a v a x.s e r v l e t.h t t p,我们还需包含j a v a.i o包来支持一些可能出现的I O E x c e p t o

42、 n s异常。2.类声明为了实现s e r v l e t的功能,所有的s e r v l e t都要实现s e r v l e t接口。幸运的是,我们不用去实现整个s e r v l e t接口,只需扩展实现s e r v l e t接口的H t t p S e r v l e t类。public class HelloWord extends HttpServlet.第2章第s e rv l e t简介第第1 9下载.3.servlet初始化记住s e r v l e t只在初时装入一次并以多个 s e r v l e t容器线程来处理请求,在处理请求之前,可能需要完成某种类型的初始化。初

43、始化可能包括从文件中装入需长期使用的数据,或者创建数据库连接。但无论s e r v l e t需要什么样的初始化,代码都属于 s e r v l e t的i n i t()方法。对我们这个例子不需要任何初始化。4.用d o G e t()方法处理请求无论何时请求 s e r v l e t,s e r v l e t引擎都会派生一个新的线程并执行 s e r v l e t的s e r v i c e()方法。s e r v i c e方法将判定这是G E T请求并把请求和响应对象传给要执行的 d o G e t()方法。通过请求对象,我们可获得所有表单参数。对于本例,我们不需从请求对象获得什

44、么。public void doGet(HttpServletRequest req,HttpServletResponse res)Throws ServletException,IOException.(1)打开一个输出到浏览器的输出流通过使用响应对象,我们可创建一个 P r i n t Wr i t e r对象来把结果送回浏览器。在本例中,我们首先设置响应的内容类型(content type)为“t e x t/h t m l”,然后使用响应对象的 g e t Wr i t e r()方法获得一个P r i n t Wr i t e r对象。因为我们正在发送已格式化的文本,所以用 P r

45、 i n t Wr i t e r来送回数据。如果我们返回二进制数据,就要用响应对象的 g e t O u p u t S t r e a m()方法打开一个流。r e s.s e t C o n t e n t T y p e(t e x t/h t m l );PrintWriter out=res.getWriter();(2)回送响应我们要做的最后一件事就是通过输出流把响应送回给浏览器,这是通过调用P r i n t Wr i t e r的p r i n t l n()方法来实现的。P r i n t Wr i t e r对我们的输出进行编码,但此时并不立即回送。当我们完成了响应,通过

46、 P r i n t Wr i t e r的c l o s e()方法关闭输出流时,响应才被真正发送出去(见图2-2)。20第第J a v a服务器高级编程下载图2-25.发布H e l l o World servlet为了让H e l l o Wo r l d工作,你需要把它保存在一个叫 H e l l o Wo r l d.j a v a的文件中并编译它,同时要确信J S D K文件在相应的类目录中。如果你使用 J S D K或S e r v l e t R u n n e r提供的s e r v l e t容器,需要把类库文件移到J S D K的安装目录/We b P a g e s/

47、W E B-I N F/s e r v l e t s,并使用s t a r t s e r v e r.b a t来启动S e r v l e t R u n n e r。现在,通过在浏览器的地址框键入 h t t p:/l o c a l h o s t:8 0 8 0/s e r v l e t/H e l l o Wo r l d就可成功调用H e l l o World servlet。如果你的机器连在网络上,你还可以从另一台机器上调用这个 s e r v l e t只需把l o c a l h o s t换成你的机器的主机名即可。如果通过l o c a l h o s t访问s e

48、 r v l e t有问题,你可以换成数字的 I P地址1 2 7.0.0.1,本地址通常就代表本机。在本书最后的附录中,会有更多关于配置 S e r v l e t R u n n e r以及用其他 s e r v l e t容器发布运行s e r v l e t的信息。2.2 简化H T M L的生成过程在开发s e r v l e t时,当然希望能把精力集中到运行的特定服务上而不用去考虑响应的格式。为了有助于格式化响应,最好是预先定义一个对象,通过几个简单方法就能产生标准的 H T M L标志(m a r k u p)。我们要使用的对象包括几个简单的方法来产生 H T M L页面。在后面

49、的第六章中,我们会为此对象增加几个方法来产生一些不同格式的网页。现在,我们需要一个方法来创建头、增加一行H T M L并返回整个H T M L。请注意下面的代码段,看看在使用 H T M L对象时有什么不同。不使用H T M L对象的代码为:第2章第s e rv l e t简介第第2 1下载使用H T M L对象的代码为:HTML h=new HTML(Hello word);h.add(HTML.HEADING,Hello word,false);o u t.p r i n t l n(h.g e t P a g e();很明显,后面的代码比前面简单多了。程序的第一行创建一个 H T M L

50、对象,并把标题设为“Hello Wo r l d”。接下来,使用a d d方法增加一个头。这个方法有三个参数:第一个是样式,可以是N O R M A L、H E A D I N G或者L I N E,这些类型在需要时可加入 H T M L类;第二个参数是要加入的文本;最后第三个参数决定是否在文本后要加分隔线。最后一行代码调用 g e t P a g e()方法返回整个H T M L串。以下代码定义了c o m.w r o x.u t i l.H T M L对象。22第第J a v a服务器高级编程下载2.3 关于性能的几点注释当你考虑一个 s e r v l e t的可能执行次数时,有必要关注

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁