﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-花香蝶自来-随笔分类-JSP&amp;SERVLET</title><link>http://www.blogjava.net/ltc603/category/14745.html</link><description>&lt;font size="3"&gt;学无止境&lt;/font&gt;
&lt;br&gt;

&lt;script type="text/javascript" src="http://wujunlove.googlepages.com/bigstaticeyes.js"&gt;&lt;/script&gt;</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 06:23:08 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 06:23:08 GMT</pubDate><ttl>60</ttl><item><title>CSS全攻略－转</title><link>http://www.blogjava.net/ltc603/archive/2006/10/25/77265.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Wed, 25 Oct 2006 11:11:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/10/25/77265.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/77265.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/10/25/77265.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/77265.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/77265.html</trackback:ping><description><![CDATA[
		<div style="MARGIN-TOP: 5px; MARGIN-LEFT: 15px">
				<b>关键字:</b>   转贴     </div>
		<div style="MARGIN-TOP: 10px; MARGIN-LEFT: 15px">
				<table width="100%">
						<tbody>
								<tr>
										<td>
												<p>CSS全称Cascading Style Sheet。层叠式样式表。从三年前就开始使用CSS了，但一直以来都小看了它。CSS的出现其实是一次革命，它试图将网站的内容与表现分开。 <br />一、CSS的四种实现方式： <br />1.内嵌式：</p>
												<p>2.外链式：</p>
												<p>3.导入式</p>
												<p>3.属性式： <br />二.CSS的定义： <br />选择对象{属性1:值1;属性2:值2;属性3:值3;属性n:值n……} <br />如： <br />td{font-size:12px;color:#FFFF00} <br />.myname{font-size:12px;color:#FFFF00} <br />a:hover{font-size:12px;color:#FFFF00;text-decoration: underline;} <br />三.四种选择对象 <br />1.HTML selector (TagName) <br />2.class selector (.NAME) <br />3.ID selector (#IDname) <br />4.特殊对象 (a:hover　a:link　a:visited　a:active) <br />1.HTML selector <br />HTML selector就是HTML的置标符，如：DIV、TD、H1。HTML selector的作用范围是应用了该样式的所有页面中的所有该置标符。 <br />例： <br />td <br />{ color: #FF0000; <br />} <br />--&gt; <br />注意：在中没有应用什么，其中文字自动变红色。 <br />2.class selector <br />定义class selector需要往其名称其加一个点“.”。如“.classname”。class selector的作用范围是所有包含“class="classname"”的置标符。 <br />例： <br />.fontRed <br />{ color: #FF0000; <br />} --&gt; <br />注意：在第二个中没有“class="fontRed"”，所以文字没有变红色。 <br />3.ID selector <br />定义ID selector需要往其名称其加一个点“#”。如“#IDname”。ID selector的作用范围是所有包含“ID="classname"”的置标符。 <br />例：</p>
												<p>#fontRed <br />{ color: #FF0000; <br />} --&gt; <br />注意：在第二个中没有“ID="fontRed"”，所以文字没有变红色。 <br />4.特殊对象 <br />特殊对象包括四种，是针对链接对象设置的: <br />a:hover 鼠标移上时的超链接 <br />a:link 常规，非访问超链接 <br />a:visited 访问过的超链接 <br />a:active 鼠标点击时的超链接 <br />特殊对象的作用范围是所有置标符（这句话有待商榷，因为下面很快就有一种方法可以把“所有”两个字推翻）。 <br />例： <br />a:hover <br />{ color: #0000FF; <br />text-decoration: underline; <br />} --&gt; <br />注意下面，很有用！！！ <br />a.classname:hover <br />a#IDname:hover <br />这两种写法，是分别配合.classname与#IDname使用的。它的作用范围变成了所有包含“class="classname"”或“ID="IDname"”的置标符。这种写法，可以帮助你在同一页面中实现多种a:hover效果，可以看一下艺网的主页上导航栏文字与普通文章标题在鼠标时的区别。 <br />四.应用： <br />1.置标符　自动应用 <br />2.特制类　class="NAME" <br />3.ID ID="IDname" <br />4.特殊对象　自动应用 <br />五.CSS属性 <br />CSS的属性有很多，像上文中用到最多的color，表示文字的颜色。background-color表示背景色。这个是最主要的，但是因为没有什么难度，参考一下相关手册就可以了。</p>
												<p>注明两点 <br />第一点：css的方式现在一般都采用外部连接，这个用起来方便，编译起来也方便 <br />第二点：我用的是frontpage2003，很多css的参数都会自动提示，似乎好像以前我没有用到过~~dw有的</p>
												<p>CSS 标签属性/属性参考 <br />这里列出了目前支持的样式表(CSS)标签属性。标有星号(*)的标签属性可于 Microsoft® Internet Explorer 5 中使用。标有两个星号(**)的标签属性可于 Internet Explorer 5.5 中使用。带有两个加号(++)的标签属性可于 Internet Explorer 6 中使用。如果某个标签属性或属性已经提交给万维网协会(W3C)但尚未作为标准发布，则标有“已提交”。若某个标签属性或属性既未提交给 W3C 也不是标准，将标有“扩展”。</p>
												<p>CSS 标签属性/属性</p>
												<p>行为属性 behavior</p>
												<p>字体和文本属性 direction* </p>
												<p>direction <br />font <br />font-family <br />font-size <br />font-style <br />font-variant <br />font-weight <br />ime-mode <br />layout-grid <br />layout-grid-char <br />layout-grid-line <br />layout-grid-mode <br />layout-grid-type <br />letter-spacing <br />line-break <br />line-height <br />min-height ++ <br />ruby-align <br />ruby-overhang <br />ruby-position <br />text-align <br />text-autospace <br />text-decoration <br />text-indent <br />text-justify <br />text-kashida-space <br />text-overflow ++ <br />text-transform <br />text-underline-position <br />unicode-bidi <br />vertical-align <br />white-space** <br />word-break <br />word-spacing ++(于 Macintosh 版本 4.0 中可用) <br />word-wrap <br />writing-mode</p>
												<p>颜色和背景属性 background-attachment <br />background-color <br />background-image <br />background-position <br />background-position-x <br />background-position-y <br />background-repeat <br />color </p>
												<p>版面属性 border <br />border-bottom <br />border-bottom-color <br />border-bottom-style <br />border-bottom-width <br />border-collapse* <br />border-color <br />border-left <br />border-left-color <br />border-left-style <br />border-left-width <br />border-right <br />border-right-color <br />border-right-style <br />border-right-width <br />border-style <br />border-top <br />border-top-color <br />border-top-style <br />border-top-width <br />border-width <br />clear <br />float <br />layout-flow <br />margin <br />margin-bottom <br />margin-left <br />margin-right <br />margin-top <br />padding <br />padding-bottom <br />padding-left <br />padding-right <br />padding-top <br />scrollbar-3dlight-color <br />scrollbar-arrow-color <br />scrollbar-base-color <br />scrollbar-darkshadow-color <br />scrollbar-face-color <br />scrollbar-highlight-color <br />scrollbar-shadow-color <br />table-layout* <br />zoom</p>
												<p>分类属性 display </p>
												<p>list-style <br />list-style-image <br />list-style-position <br />list-style-type </p>
												<p>定位属性 bottom* </p>
												<p>clip <br />height <br />left <br />overflow <br />overflow-x <br />overflow-y <br />position <br />right* <br />top <br />visibility <br />width <br />z-index </p>
												<p>打印属性 page** </p>
												<p>pageBreakAfter <br />pageBreakBefore</p>
												<p>滤镜属性 filter</p>
												<p>伪类和其它属性 :active </p>
												<p>@charset <br />cursor <br />:first-letter** <br />:first-line** <br />@font-face <br />:hover <br />@import <br />!important <br />:link <br />@media* <br />@page** <br />:visited <br />有关表格边框的css语法整理</p>
												<p>我们知道Dreamweaver在表格制作方面做得非常出色，但是在某些时候还是必须结合css才能达到一些特定效果，下面我们先把有关表格边框的css语法整理出来，然后另外介绍怎样用css美化表格的边框。</p>
												<p>　　有关表格边框的css语法</p>
												<p>　　具体内容包括：上边框宽度、右边框宽度、下边框宽度、左边框宽度、边框宽度、边框颜色、边框样式、上边框、下边框、左边框、右边框、边框、宽度、高度、有关标签等。</p>
												<p>　　 1.上边框宽度</p>
												<p>　　语法: border-top-width: &lt;值&gt;</p>
												<p>　　允许值: thin | medium | thick | &lt;长度&gt;</p>
												<p>　　初始值: medium</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　上边框宽度属性用于指定一个元素上边框的宽度。值可以是三个关键字其中的一个，都不受字体大小或长度的影响，可以用于实现成比例的宽度。不允许使用负值。也可以用在上边框、边框的宽度或边框的属性略写。</p>
												<p>　　2.右边框宽度</p>
												<p>　　语法: border-right-width: &lt;值&gt;</p>
												<p>　　允许值: thin | medium | thick | &lt;长度&gt;</p>
												<p>　　初始值: medium</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　右边框宽度属性用于指定元素的右边框的宽度。值可以是三个关键字其中的一个，都不受字体大小或长度的影响，可以用于实现成比例的宽度。不允许使用负值。也可以用在右边框、边框的宽度或边框的属性略写。</p>
												<p>　　 3.下边框宽度</p>
												<p>　　语法: border-bottom-width: &lt;值&gt;</p>
												<p>　　允许值: thin | medium | thick | &lt;长度&gt;</p>
												<p>　　初始值: medium</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　下边框宽度属性用于指定元素的下边框的宽度。值可以是三个关键字其中的一个，都不受字体大小或长度的影响，可以用于实现成比例的宽度。不允许使用负值。也可以用在下边框、边框的宽度或边框的属性略写。</p>
												<p>　　 4.左边框宽度</p>
												<p>　　语法: border-left-width: &lt;值&gt;</p>
												<p>　　允许值: thin | medium | thick | &lt;长度&gt;</p>
												<p>　　初始值: medium</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　左边框宽度属性用于指定元素的左边框的宽度。值可以是三个关键字其中的一个，都不受字体大小或长度的影响，可以用于实现成比例的宽度。不允许使用负值。也可以用在左边框、边框的宽度或边框的属性略写。</p>
												<p>　　5.边框宽度</p>
												<p>　　语法: border-width: &lt;值&gt;</p>
												<p>　　允许值: [ thin | medium | thick | &lt;长度&gt; ]{1,4}</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　边框宽度属性用一到四个值来设置元素的边界，值是一个关键字或长度。不允许使用负值长度。如果四个值都给出了，它们分别应用于上、右、下和左边框的式样。如果给出一个值，它将被运用到各边上。如果两个或三个值给出了，省略了的值与对边相等。 这个属性是上边框宽度、右边框宽度、下边框宽度和左边框宽度属性的略写。也可以使用略写的边框属性。</p>
												<p>　　6.边框颜色</p>
												<p>　　语法: border-color: &lt;值&gt;</p>
												<p>　　允许值: &lt;颜色&gt;{1,4}</p>
												<p>　　初始值: 颜色属性的值</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　边框颜色属性设置一个元素的边框颜色。可以使用一到四个关键字。如果四个值都给出了，它们分别应用于上、右、下和左边框的式样。如果给出一个值，它将被运用到各边上。如果两个或三个值给出了，省略了的值与对边相等。也可以使用略写的边框属性。</p>
												<p>　　7.边框样式</p>
												<p>　　语法: border-style: &lt;值&gt;</p>
												<p>　　允许值: [ none | dotted | dashed | solid | double | groove | ridge | inset | outset ]{1,4}</p>
												<p>　　初始值: none</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　边框样式属性用于设置一个元素边框的样式。这个属性必须用于指定可见的边框。可以使用一到四个关键字。如果四个值都给出了，它们分别应用于上、右、下和左边框的式样。如果给出一个值，它将被运用到各边上。如果两个或三个值给出了，省略了的值与对边相等。也可以使用略写的边框属性。</p>
												<p>　　none：无样式； <br />　　dotted：点线； <br />　　dashed：虚线； <br />　　solid：实线； <br />　　double：双线； <br />　　groove：槽线； <br />　　ridge：脊线； <br />　　inset：内凹； <br />　　outset：外凸。 <br />8.上边框</p>
												<p>　　语法: border-top: &lt;值&gt;</p>
												<p>　　允许值: &lt;上边框宽度&gt; || &lt;边框式样&gt; || &lt;颜色&gt;</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　上边框属性是一个用于设置一个元素上边框的宽度、式样和颜色的略写。注意只能给出一个边框式样。也可以使用略写的边框属性。</p>
												<p>　　9.右边框</p>
												<p>　　语法: border-right: &lt;值&gt;</p>
												<p>　　允许值: &lt;右边框宽度&gt; || &lt;边框式样&gt; || &lt;颜色&gt;</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　右边框属性是一个用于设置一个元素右边框的宽度、式样、和颜色的略写。注意只能给出一个边框式样。也可以使用略写的边框属性。　　 </p>
												<p>　　10.下边框</p>
												<p>　　语法: border-bottom: &lt;值&gt;</p>
												<p>　　允许值: &lt;下边框宽度&gt; || &lt;边框式样&gt; || &lt;颜色&gt;</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　下边框属性是一个用于设置一个元素的下边框的宽度、式样和颜色的略写。注意只能给出一个边框式样。也可以使用略写的边框属性。</p>
												<p>　　11.左边框</p>
												<p>　　语法: border-left: &lt;值&gt;</p>
												<p>　　允许值: &lt;左边框宽度&gt; || &lt;边框式样&gt; || &lt;颜色&gt;</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　左边框属性是一个用于设置一个元素左边框的宽度、式样和颜色的略写。注意只能给出一个边框式样。也可以使用略写的边框属性。</p>
												<p>　　 12.边框</p>
												<p>　　语法: border: &lt;值&gt;</p>
												<p>　　允许值: &lt;边框宽度&gt; || &lt;边框式样&gt; || &lt;颜色&gt;</p>
												<p>　　初始值: 未定义</p>
												<p>　　适用于: 所有对象</p>
												<p>　　向下兼容: 否</p>
												<p>　　边框属性是一个用于设置一个元素边框的宽度、式样和颜色的略写。</p>
												<p>　　边框声明的例子包括：</p>
												<p>　　H2 { border: groove 3em } <br />　　A:link { border: solid blue } <br />　　A:visited { border: thin dotted #800080 } <br />　　A:active { border: thick double red }</p>
												<p>　　边框属性只能设置四种边框；只能给出一组边框的宽度和式样。为了给出一个元素的四种边框的不同的值，网页制作者必须用一个或更多的属性，如：上边框、右边框、下边框、左边框、边框颜色、边框宽度、边框式样、上边框宽度、右边框宽度、下边框宽度或左边框宽度。 </p>
												<p>　　13.宽度</p>
												<p>　　语法: width: &lt;值&gt;</p>
												<p>　　允许值: &lt;长度&gt; | &lt;百分比&gt; | auto</p>
												<p>　　初始值: auto</p>
												<p>　　适用于: 块级和替换元素</p>
												<p>　　向下兼容: 否</p>
												<p>　　宽度属性的初始值为“auto”，即为该元素的原有宽度(有就是元素自己的宽度)。百分比参考上级元素的宽度。不允许使用负的长度值。</p>
												<p>　　14.高度</p>
												<p>　　语法: height: &lt;值&gt;</p>
												<p>　　允许值: &lt;长度&gt; | auto</p>
												<p>　　初始值: auto</p>
												<p>　　适用于: 块级和替换元素</p>
												<p>　　向下兼容: 否</p>
												<p>　　高度属性的初始值为“auto”，即为该元素的原有高度(有就是元素自己的高度，)。百分比参考上级元素的宽度。不允许使用负的长度值。</p>
												<p>　　15.有关标签</p>
												<p>　　table：表格标签，对整个表格样式的定义要放在table中； <br />　　td：单元格标签，对单元格样式的定义要放在td中。 </p>
												<p>css滤镜</p>
												<p>随着网页设计技术的发展，人们已经不满足于原有的一些HTML标记，而是希望能够为页面添加一些多媒体属性，例如滤镜的和渐变的效果。CSS技术的飞快发展使这些需求成为了现实。从现在开始我要为大家介绍一个新的CSS扩展部分：CSS滤镜属性（Filter Properties)。使用这种技术可以把可视化的滤镜和转换效果添加到一个标准的HTML元素上，例如图片、文本容器、以及其他一些对象。对于滤镜和渐变效果，前者是基础，因为后者就是滤镜效果的不断变化和演示更替。当滤镜和渐变效果结合到一个基本的SCRIPT小程序中后，网页设计者就可以拥有一个建立动态交互文档的强大工具。也就是CSS FILTER+ SCRIPT， 这就说明想要建立动态的文档还要一些SCRIPT （脚本语言）的基础。 <br />可视化滤镜属性只能用在HTML控件元素上。所谓的HTML空间元素就是它们在页面上定义了一个矩形空间，浏览器的窗口可以显示这些空间。下面列出了HTML合法的控件和它们的说明。</p>
												<p>备注：可惜只有IE4.0以上支持，如果是别的浏览器，那就.......</p>
												<p>元素 说明 <br />BODY 网页文档的主体元素，所有的可见范围都在&lt;BODY&gt;元素内 <br />BUTTON 表单域的按钮，可以有“发送(submit)”、“重置(reset)”等形式 <br />DIV 定义了网页上的一个区域，这个区域的高度、宽度或者绝对位置都是以知的 <br />IMG 图片元素，通过指定“src"属性来指定图片的来源 <br />INPUT 输入表单域 <br />MARQUEE 移动字幕效果 <br />SPAN 定义了网页上的一个区域，这个区域的高度、宽度或者绝对位置都是以知的 <br />TABLE 表格 <br />TD 表格数据单元格 <br />TEXTAREA 文本区域 <br />TFOOT 多行输入文本框 <br />TH 表格标题单元格 <br />THEAD 表格标题 <br />TR 表格行 </p>
												<p>　</p>
												<p>IE4.0以上支持的滤镜属性表</p>
												<p>滤镜效果 描述 <br />Alpha 设置透明度 <br />Blru 建立模糊效果 <br />Chroma 把指定的颜色设置为透明 <br />DropShadow 建立一种偏移的影象轮廓，即投射阴影 <br />FlipH 水平反转 <br />FlipV 垂直反转 <br />Glow 为对象的外边界增加光效 <br />Grayscale 降低图片的彩色度 <br />Invert 将色彩、饱和度以及亮度值完全反转建立底片效果 <br />Light 在一个对象上进行灯光投影 <br />Mask 为一个对象建立透明膜 <br />Shadow 建立一个对象的固体轮廓，即阴影效果 <br />Wave 在X轴和Y轴方向利用正弦波纹打乱图片 <br />Xray 只显示对象的轮廓 </p>
												<p>1、Alpha 滤镜 <br /></p>
												<p>语法：{FILTER：ALPHA(opacity=opacity,finishopacity=finishopacity,style=style,startx=startx, <br />starty=starty,finishx=finishx,finishy=finishy)}</p>
												<p>"Alpha"属性是把一个目标元素与背景混合。设计者可以指定数值来控制混合的程度。这种“与背景混合”通俗地说就是一个元素的透明度。通过指定坐标，可以指定点、线、面的透明度。他们的参数含义分别如下： <br />“opacity"代表透明度水准。默认的范围是从0 到 100，他们其实是百分比的形式。也就是说，0代表完全透明，100代表完全不透明。”finishopacity"是一个可选参数，如果想要设置渐变的透明效果，就可以使用他们来指定结束时的透明度。范围也是0 到 100。“style" 参数指定了透明区域的形状特征。其中0代表统一形状、1代表线形、2代表放射状、3代表长方形。”STARTX“和”STARTY“代表渐变透明效果的开始X和Y坐标。”FINISHX“和”FINISHY“代表渐变透明效果结束X和Y 的坐标。</p>
												<p>效果如下：</p>
												<p>2、Blur 滤镜</p>
												<p>语法：对于HTML：{ilter:blur(add=add,direction=direction,strength=strength)} <br />对于Script语言： [oblurfilter=] object.filters.blur <br />用手指在一幅尚未干透的油画上迅速划过时，画面就会变得模糊。”Blur"就是产生同样的模糊效果。 <br />“ADD”参数是一个布尔判断“TRUE（默认）”或者“FALSE”。它指定图片是否被改变成印象派的模糊效果。模糊效果是按顺时针的方向进行的，“DIRECTION”参数用来设置模糊的方向。其中0度代表垂直向上，然后每45度为一个单位。它的默认值是向左的270度。“STRENGTH“值只能使用整数来指定，她代表有多少像素的宽度将受到模糊影响。默认是5个。对于网页上的字体，如果设置他的模糊”ADD=1“，那么这些字体的效果会非常好看的。如下： <br />filter:blur(add=ture,direction=135,strength=10）</p>
												<p>3、FlipH, FlipV 滤镜</p>
												<p>语法：{filter:filph} ,{filter:filpv} 分别是水平反转和垂直反转，具体如下：</p>
												<p>4、Chroma 滤镜</p>
												<p>语法：{filter:chroma(color=color)} <br />使用”Chroma"属性可以设置一个对象中指定的颜色为透明色，参数COLOR即要透明的颜色。下面是兰色文字，然后用Chroma 滤镜过滤掉兰色，就成了下面的样子。 <br />filter:chroma(color=blue)</p>
												<p>滴水檐坊</p>
												<p>5、DropShadow 滤镜</p>
												<p>语法：{filter:dropshadow(color=color,offx=ofx,offy=offy,positive=positive)}</p>
												<p>“DropShaow"顾名思义就是添加对象的阴影效果。其工作原理是建立一个偏移量，加上较深。"Color"代表投射阴影的颜色，"offx"和"offy"分别是X方向和Y方向阴影的饿偏移量。"Positive"参数是一个布尔值，如果为“TRUE（非0）”，那么就为任何的非透明像素建立可见的投影。如果为“FASLE（0）”，那么就为透明的像素部分建立透明效果</p>
												<p>6、Glow 滤镜</p>
												<p>语法：{filter:glow(color=color,strength)} <br />当对一个对象使用"glow"属性后，这个对象的边缘就会产生类似发光的效果。“COLOR”是指定发光的颜色，“STRENGTH”则是强度的表现，可以从1到255之间的任何整数来指定这个力度。 <br />filter:glow(color=red,strength=10) 后的效果 </p>
												<p>7、Gray ,Invert,Xray 滤镜</p>
												<p>语法：{filter:gray} ,{filter:invert},{filter:xray}</p>
												<p>Gray滤镜是把一张图片变成灰度图；Invert滤镜是把对象的可视化属性全部翻转，包括色彩、饱和度、和亮度值；Xray滤镜是让对象反映出它的轮廓并把这些轮廓加亮，也就是所谓的“X”光片。</p>
												<p>效果如下：</p>
												<p>、Light 滤镜</p>
												<p>语法：Filter{light}</p>
												<p>这个属性模拟光源的投射效果。一旦为对象定义了“LIGHT"滤镜属性，那么就可以调用它的“方法(Method)"来设置或者改变属性。“LIGHT"可用的方法有：</p>
												<p>AddAmbient 加入包围的光源 <br />AddCone 加入锥形光源 <br />AddPoint 加入点光源 <br />Changcolor 改变光的颜色 <br />Changstrength 改变光源的强度 <br />Clear 清除所有的光源 <br />MoveLight 移动光源 <br />可以定义光源的虚拟位置，以及通过调整X轴和Y轴的数值来控制光源焦点的位置，还可以调整光源的形式（点光源或者锥形光源）指定光源是否模糊边界、光源的颜色、亮度等属性。如果动态的设置光源，可能回产生一些意想不到的效果。后面几页会有具体范例。</p>
												<p>9、Mask 滤镜</p>
												<p>语法：{filter:mask(color=color)}</p>
												<p>使用"MASK"属性可以为对象建立一个覆盖于表面的膜，其效果就象戴者有色眼镜看物体一样。</p>
												<p>10、Shadow 滤镜</p>
												<p>语法：{filter:shadow(color=color,direction=direction)}</p>
												<p>利用“Shadow”属性可以在指定的方向建立物体的投影，COLOR是投影色，DIRECTION是设置投影的方向。其中0度代表垂直向上，然后每45度为一个单位。它的默认值是向左的270度。</p>
												<p>filter:shadow(color=red,direction=225) <br />filter:shadow(color=blue,direction=225) <br />filter:shadow(color=gray,direction=225) <br />效果分别如下：</p>
												<p>11、Wave 滤镜 语法：{filter:wave(add=add,freq=freq,lightstrength=strength,phase=phase,strength=strength)} <br />"wave" 属性把对象按垂直的波形样式打乱。默认是“TRUE（非0）”， <br />“ADD”表示是否要把对象按照波形样式打乱，</p>
												<p>“FREQ”是波纹的频率，也就是指定在对象上一共需要产生多少个完整的波纹，</p>
												<p>“LIGHTSTRENGTH”参数可以对于波纹增强光影的效果，范围0----100，</p>
												<p>“PHASE”参数用来设置正弦波的偏移量。</p>
												<p>“STRENGTH”代表振幅大小。</p>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
<img src ="http://www.blogjava.net/ltc603/aggbug/77265.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-10-25 19:11 <a href="http://www.blogjava.net/ltc603/archive/2006/10/25/77265.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>contentType 和 pageEncoding</title><link>http://www.blogjava.net/ltc603/archive/2006/09/05/67729.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Tue, 05 Sep 2006 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/05/67729.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67729.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/05/67729.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67729.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67729.html</trackback:ping><description><![CDATA[ContentType<br />ContentType属性指定了MIME类型和JSP页面回应时的字符编码方式。MIME类型的默认值是“text/html”; 字符编码方式的默认值是“ISO-8859-1”. MIME类型和字符编码方式由分号隔开<br /><br />pageEncoding<br />pageEncoding 在JSP标准的语法中，如果pageEncoding属性存在，那么JSP页面的字符编码方式就由pageEncoding决定，否则就由contentType属性中的charset决定，如果charset也不存在，JSP页面的字符编码方式就采用默认的ISO-8859-1。<br /><img src ="http://www.blogjava.net/ltc603/aggbug/67729.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-05 09:37 <a href="http://www.blogjava.net/ltc603/archive/2006/09/05/67729.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对Servlet的初始化的理解 </title><link>http://www.blogjava.net/ltc603/archive/2006/09/04/67640.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Mon, 04 Sep 2006 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/04/67640.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67640.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/04/67640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67640.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67640.html</trackback:ping><description><![CDATA[
		<h1 style="MARGIN: 17pt 0cm 16.5pt; TEXT-ALIGN: center" align="center">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<font size="2">
								<span style="FONT-SIZE: 9pt; COLOR: navy; FONT-FAMILY: 仿宋_GB2312; mso-bidi-font-size: 10.0pt">版权所有，转载请声明出处 </span>
								<b>
										<span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: navy; FONT-FAMILY: Arial; mso-bidi-font-size: 10.0pt; mso-fareast-font-family: 仿宋_GB2312">zhyiwww@163.com</span>
								</b>
						</font>
				</span>
		</h1>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在读我自己的认识之前</span>
				<span lang="EN-US">,</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们先来看一下</span>
				<span lang="EN-US">servet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的结构图</span>
				<span lang="EN-US">:<br /></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /?>
						<v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600">
								<v:stroke joinstyle="miter">
								</v:stroke>
								<v:formulas>
										<v:f eqn="if lineDrawn pixelLineWidth 0">
										</v:f>
										<v:f eqn="sum @0 1 0">
										</v:f>
										<v:f eqn="sum 0 0 @1">
										</v:f>
										<v:f eqn="prod @2 1 2">
										</v:f>
										<v:f eqn="prod @3 21600 pixelWidth">
										</v:f>
										<v:f eqn="prod @3 21600 pixelHeight">
										</v:f>
										<v:f eqn="sum @0 0 1">
										</v:f>
										<v:f eqn="prod @6 1 2">
										</v:f>
										<v:f eqn="prod @7 21600 pixelWidth">
										</v:f>
										<v:f eqn="sum @8 21600 0">
										</v:f>
										<v:f eqn="prod @7 21600 pixelHeight">
										</v:f>
										<v:f eqn="sum @10 21600 0">
										</v:f>
								</v:formulas>
								<v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f">
								</v:path>
								<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
								<o:lock aspectratio="t" v:ext="edit">
								</o:lock>
						</v:shapetype>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
						<img height="455" alt="servlet.png" src="http://www.blogjava.net/images/blogjava_net/zhyiwww/servlet.png" width="628" border="0" />
						<br />以下是我自己的一点浅见：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">①　</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在初始化的时候</span>
				<span lang="EN-US">,</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是通过</span>
				<span lang="EN-US">init(ServletConfig<span style="mso-spacerun: yes">  </span>config)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span>
				<span lang="EN-US">init()</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来执行的。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个接口，它怎样传递给他一格对象来进行初始化呢？其实，是这个对象是由</span>
				<span lang="EN-US">servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器来实例化的，由容器产生一格</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的实现类的对象，然后传递给</span>
				<span lang="EN-US">Servlet</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 16pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">结论：</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 16pt; COLOR: navy; mso-bidi-font-size: 10.0pt">ServletConfig</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 16pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">由容器实例化</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">②　</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们有些时候可能在</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化时给它一些固定的配置参数，那么这些参数是怎样传递到</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">呢？</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实，我们在</span>
				<span lang="EN-US">web.xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中给</span>
				<span lang="EN-US">servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置启动参数，在容器对</span>
				<span lang="EN-US">servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行初始化的时候，会收集你所配置的参数，记录在</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的实现类中，所以你才可以通过</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象的</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>public String getInitParameter(String name);</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>public Enumeration getInitParameterNames();</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法来取得你已经配置好的参数，也就是说，你对</span>
				<span lang="EN-US">servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的配置都已经记录在</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象中了。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">结论：你对</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 15pt; COLOR: navy; mso-bidi-font-size: 10.0pt">Servlet</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">的配置，在</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 15pt; COLOR: navy; mso-bidi-font-size: 10.0pt">Servlet</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">的初始化时都由容器来收集并且记录到</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 15pt; COLOR: navy; mso-bidi-font-size: 10.0pt">ServletConfig</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">的实现类中。</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US"> <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">③　</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们来看一个</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的配置</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>&lt;servlet&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-name&gt;index&lt;/servlet-name&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>&lt;servlet-class&gt;org.zy.pro.sw.servlet.IndexServlet&lt;/servlet-class&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">    </span>&lt;init-param&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">      </span>&lt;param-name&gt;dbconfig&lt;/param-name&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">      </span>&lt;param-value&gt;/WEB-INF/dbconfig.xml&lt;/param-value&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">    </span>&lt;/init-param&gt;</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>&lt;/servlet&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在此，我们实现对数据库的配置文件的加载。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化完成后，我们可以通过</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">String<span style="mso-spacerun: yes">  </span>dbconf=this.getServletConfig().getInitParameter("dbconfig")</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来取得我们的配置的参数的值。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是，我们仅能得到一个配置的字符串。之后我们可以通过配置文件取得我们的数据库的配置参数，然后对数据库进行初始化。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实我们也可以通过传递一个类的名字串，然后再实例化。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">    </span>&lt;init-param&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">      </span>&lt;param-name&gt;dbconfig&lt;/param-name&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">      </span>&lt;param-value&gt;org.zy.util.db.DBUtil&lt;/param-value&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 14pt; COLOR: navy; mso-bidi-font-size: 10.0pt">
								<span style="mso-spacerun: yes">   </span>
								<span style="mso-spacerun: yes"> </span>&lt;/init-param&gt;<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们先取得配置参数：</span>
						<span lang="EN-US" style="COLOR: navy">
								<o:p>
								</o:p>
						</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">String<span style="mso-spacerun: yes">  </span>dbconf=this.getServletConfig().getInitParameter("dbconfig")</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后通过</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">Class.forName(dbconf).getInstance();</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来实例化对象，就可以实现对数据库的调用了。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">结论：在</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 15pt; COLOR: navy; mso-bidi-font-size: 10.0pt">web.xml</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">中对</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span lang="EN-US" style="FONT-SIZE: 15pt; COLOR: navy; mso-bidi-font-size: 10.0pt">Servlet</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 15pt; COLOR: navy; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt">的初始化，只能传递字符串类型的数据</span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 20pt; mso-list: l0 level1 lfo1">
				<span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">④　</span>
				<span lang="EN-US">ServletContext</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">ServletContext</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是负责和</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的上文和下文交互，上面和</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器交互，下面和</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的请求和相应进行交互。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，</span>
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span lang="EN-US">public ServletContext getServletContext();</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法实现取得当前</span>
				<span lang="EN-US">ServletContext</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可能要问，</span>
				<span lang="EN-US">ServletContext</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个接口，那么你如何取得他的对象呢？</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实这个问题和</span>
				<span lang="EN-US">ServletConfig</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相同，都是在</span>
				<span lang="EN-US">Servlet</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行初始化的时候产生的对象，是由容器来初始化的。</span>
		</p>
<img src ="http://www.blogjava.net/ltc603/aggbug/67640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-04 17:25 <a href="http://www.blogjava.net/ltc603/archive/2006/09/04/67640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Jsp和Servlet]servlet简明教程【转载】</title><link>http://www.blogjava.net/ltc603/archive/2006/09/01/67168.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 01 Sep 2006 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/01/67168.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67168.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/01/67168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67168.html</trackback:ping><description><![CDATA[
		<div>一、Servlet和JSP概述 <br />  作 者 : 仙人掌工作室 <br />   <br />   <br />  　　 1.1 Java Servlet及其特点 <br />   <br />  　　 Servlet是Java技术对CGI编程的回答。Servlet程序在服务器端运行，动态地生成Web页面。与传统的CGI和许多其他类似CGI的技术相比，Java Servlet具有更高的效率，更容易使用，功能更强大，具有更好的可移植性，更节省投资（更重要的是， Servlet程序员收入要比Perl程序员高:-）： <br />   <br />  高效。 <br />   <br />  在传统的CGI中，每个请求都要启动一个新的进程，如果CGI程序本身的执行时间较短，启动进程所需要的开销很可能反而超过实际执行时间。而在Servlet中，每个请求由一个轻量级的Java线程处理（而不是重量级的操作系统进程）。 <br />  在传统CGI中，如果有N个并发的对同一CGI程序的请求，则该CGI程序的代码在内存中重复装载了N次；而对于Servlet，处理请求的是N个线程，只需要一份Servlet类代码。在性能优化方面，Servlet也比CGI有着更多的选择，比如缓冲以前的计算结果，保持数据库连接的活动，等等。 <br />   <br />   <br />  方便。 <br />   <br />  Servlet提供了大量的实用工具例程，例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等。 <br />   <br />   <br />  功能强大。 <br />   <br />  在Servlet中，许多使用传统CGI程序很难完成的任务都可以轻松地完成。例如，Servlet能够直接和Web服务器交互，而普通的CGI程序不能。Servlet还能够在各个程序之间共享数据，使得数据库连接池之类的功能很容易实现。 <br />   <br />   <br />  可移植性好。 <br />   <br />  Servlet用Java编写，Servlet API具有完善的标准。因此，为I-Planet Enterprise Server写的Servlet无需任何实质上的改动即可移植到Apache、Microsoft IIS或者WebStar。几乎所有的主流服务器都直接或通过插件支持Servlet。 <br />   <br />   <br />  节省投资。 <br />   <br />  不仅有许多廉价甚至免费的Web服务器可供个人或小规模网站使用，而且对于现有的服务器，如果它不支持Servlet的话，要加上这部分功能也往往是免费的（或只需要极少的投资）。 <br />  　　 1.2 JSP及其特点 <br />   <br />  　　 JavaServer Pages（JSP）是一种实现普通静态HTML和动态HTML混合编码的技术，有关JSP基础概念的说明请参见《JSP技术简介 》。 <br />   <br />  　　 许多由CGI程序生成的页面大部分仍旧是静态HTML，动态内容只在页面中有限的几个部分出现。但是包括Servlet在内的大多数CGI技术及其变种，总是通过程序生成整个页面。JSP使得我们可以分别创建这两个部分。例如，下面就是一个简单的JSP页面： <br />  ＜!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"＞ <br />  ＜HTML＞ <br />  ＜HEAD＞＜TITLE＞欢迎访问网上商店＜/TITLE＞＜/HEAD＞ <br />  ＜BODY＞ <br />  ＜H1＞欢迎＜/H1＞ <br />  ＜SMALL＞欢迎, <br />  ＜!-- 首次访问的用户名字为"New User" --＞ <br />  ＜% out.println(Utils.getUserNameFromCookie(request)); %＞ <br />  要设置帐号信息，请点击 <br />  ＜A HREF="Account-Settings.html"＞这里＜/A＞＜/SMALL＞ <br />  ＜P＞ <br />  页面的其余内容。. <br />  ＜/BODY＞＜/HTML＞ <br />   <br />   <br />   <br />  　　 下面是JSP和其他类似或相关技术的一个简单比较： <br />   <br />  JSP和Active Server Pages（ASP）相比 <br />   <br />  Microsoft的ASP是一种和JSP类似的技术。JSP和ASP相比具有两方面的优点。首先，动态部分用Java编写，而不是VB Script或其他Microsoft语言，不仅功能更强大而且更易于使用。第二，JSP应用可以移植到其他操作系统和非Microsoft的Web服务器上。 <br />   <br />   <br />  JSP和纯Servlet相比 <br />   <br />  JSP并没有增加任何本质上不能用Servlet实现的功能。但是，在JSP中编写静态HTML更加方便，不必再用 println语句来输出每一行HTML代码。更重要的是，借助内容和外观的分离，页面制作中不同性质的任务可以方便地分开：比如，由页面设计专家进行HTML设计，同时留出供Servlet程序员插入动态内容的空间。 <br />   <br />   <br />  JSP和服务器端包含（Server-Side Include，SSI）相比 <br />   <br />  SSI是一种受到广泛支持的在静态HTML中引入外部代码的技术。JSP在这方面的支持更为完善，因为它可以用Servlet而不是独立的程序来生成动态内容。另外，SSI实际上只用于简单的包含，而不是面向那些能够处理表单数据、访问数据库的“真正的”程序。 <br />   <br />   <br />  JSP和JavaScript相比 <br />   <br />  JavaScript能够在客户端动态地生成HTML。虽然JavaScript很有用，但它只能处理以客户端环境为基础的动态信息。除了Cookie之外，HTTP状态和表单提交数据对JavaScript来说都是不可用的。另外，由于是在客户端运行，JavaScript不能访问服务器端资源，比如数据库、目录信息等等。 <br /> 2.1 安装Servlet和JSP开发工具 <br />   <br />  　　 要学习Servlet和JSP开发，首先你必须准备一个符合Java Servlet 2.1/2.2和JavaServer Pages1.0/1.1规范的开发环境。Sun提供免费的JavaServer Web Development Kit（JSWDK），可以从<a href="http://java.sun.com/products/servlet/"><u><font color="#0000ff">http://java.sun.com/products/servlet/</font></u></a> 下载。 <br />   <br />  　　 安装好JSWDK之后，你还要告诉javac，在编译文件的时候到哪里去寻找Servlet和JSP类。JSWDK安装指南对此有详细说明，但主要就是把servlet.jar和jsp.jar加入CLASSPATH。CLASSPATH是一个指示Java如何寻找类文件的环境变量，如果不设置CLASSPATH，Java在当前目录和标准系统库中寻找类；如果你自己设置了CLASSPATH，不要忘记包含当前目录（即在CLASSPATH中包含“.”）。 <br />   <br />  　　 另外，为了避免和其他开发者安装到同一Web服务器上的Servlet产生命名冲突，最好把自己的Servlet放入包里面。此时，把包层次结构中的顶级目录也加入CLASSPATH会带来不少方便。请参见下文具体说明。 <br />   <br />  　　 2.2 安装支持Servlet的Web服务器 <br />   <br />  　　 除了开发工具之外，你还要安装一个支持Java Servlet的Web服务器，或者在现有的Web服务器上安装Servlet软件包。如果你使用的是最新的Web服务器或应用服务器，很可能它已经有了所有必需的软件。请查看Web服务器的文档，或访问<a href="http://java.sun.com/products/servlet/industry.html"><u><font color="#0000ff">http://java.sun.com/products/servlet/industry.html</font></u></a> 查看支持Servlet的服务器软件清单。 <br />   <br />  　　 虽然最终运行Servlet的往往是商业级的服务器，但是开始学习的时候，用一个能够在台式机上运行的免费系统进行开发和测试也足够了。下面是几种当前最受欢迎的产品。 <br />   <br />  Apache Tomcat. <br />   <br />  Tomcat是Servlet 2.2和JSP 1.1规范的官方参考实现。Tomcat既可以单独作为小型Servlet、JSP测试服务器，也可以集成到Apache Web服务器。直到2000年早期，Tomcat还是唯一的支持Servlet 2.2和JSP 1.1规范的服务器，但已经有许多其它服务器宣布提供这方面的支持。 <br />   <br />  Tomcat和Apache一样是免费的。不过，快速、稳定的Apache服务器安装和配置起来有点麻烦，Tomcat也有同样的缺点。和其他商业级Servlet引擎相比，配置Tomcat的工作量显然要多一点。具体请参见<a href="http://jakarta.apache.org/"><u><font color="#800080">http://jakarta.apache.org/</font></u></a> 。 <br />   <br />   <br />  JavaServer Web Development Kit (JSWDK). <br />   <br />  JSWDK是Servlet 2.1和JSP 1.0的官方参考实现。把Servlet和JSP应用部署到正式运行它们的服务器之前，JSWDK可以单独作为小型的Servlet、JSP测试服务器。JSWDK也是免费的，而且具有很好的稳定性，但它的安装和配置也较为复杂。具体请参见<a href="http://java.sun.com/products/servlet/download.html"><u><font color="#0000ff">http://java.sun.com/products/servlet/download.html</font></u></a> 。 <br />   <br />   <br />  Allaire JRun. <br />   <br />  JRun是一个Servlet和JSP引擎，它可以集成到Netscape Enterprise或FastTrack Server、IIS、Microsoft Personal Web Server、版本较低的Apache、O'eilly的WebSite或者StarNine Web STAR。最多支持5个并发连接的限制版本是免费的，商业版本中不存在这个限制，而且增加了远程管理控制台之类的功能。具体请参见<a href="http://www.allaire.com/products/jrun/"><u><font color="#0000ff">http://www.allaire.com/products/jrun/</font></u></a> 。 <br />   <br />   <br />  New Atlanta 的ServletExec <br />   <br />  ServletExec是一个快速的Servlet和JSP引擎，它可以集成到大多数流行的Web服务器，支持平台包括Solaris、Windows、MacOS、HP-UX和Linux。ServletExec可以免费下载和使用，但许多高级功能和管理工具只有在购买了许可之后才可以使用。New Atlanta还提供一个免费的Servlet调试器，该调试器可以在许多流行的Java IDE下工作。具体请参见<a href="http://newatlanta.com/"><u><font color="#0000ff">http://newatlanta.com/</font></u></a> 。 <br />   <br />   <br />  Gefion的LiteWebServer (LWS) <br />   <br />  LWS是一个支持Servlet 2.2和JSP 1.1的免费小型Web服务器。 Gefion还有一个免费的WAICoolRunner插件，利用该插件可以为Netscape FastTrack和Enterprise Server增加Servlet 2.2和JSP 1.1支持。具体请参见<a href="http://www.gefionsoftware.com/"><u><font color="#0000ff">http://www.gefionsoftware.com/</font></u></a> 。 <br />   <br />   <br />  Sun的Java Web Server. <br />   <br />  该服务器全部用Java写成，而且是首先提供Servlet 2.1和JSP 1.0规范完整支持的Web服务器之一。虽然Sun现在已转向Netscape/I-Planet Server，不再发展Java Web Server，但它仍旧是一个广受欢迎的Servlet、JSP学习平台。要得到免费试用版本，请访问<a href="http://www.sun.com/software/jwebserver/try/"><u><font color="#0000ff">http://www.sun.com/software/jwebserver/try/</font></u></a> 。 <br />  <br />3.1 Servlet基本结构 <br />   <br />  　　 下面的代码显示了一个简单Servlet的基本结构。该Servlet处理的是GET请求，所谓的GET请求，如果你不熟悉HTTP，可以把它看成是当用户在浏览器地址栏输入URL、点击Web页面中的链接、提交没有指定METHOD的表单时浏览器所发出的请求。Servlet也可以很方便地处理POST请求。POST请求是提交那些指定了METHOD=“POST”的表单时所发出的请求，具体请参见稍后几节的讨论。 <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />   <br />  public class SomeServlet extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   <br />   // 使用“request”读取和请求有关的信息（比如Cookies） <br />   // 和表单数据 <br />   <br />   // 使用“response”指定HTTP应答状态代码和应答头 <br />   // （比如指定内容类型，设置Cookie） <br />   <br />   PrintWriter out = response.getWriter(); <br />   // 使用 "out"把应答内容发送到浏览器 <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 如果某个类要成为Servlet，则它应该从HttpServlet 继承，根据数据是通过GET还是POST发送，覆盖doGet、doPost方法之一或全部。doGet和doPost方法都有两个参数，分别为HttpServletRequest 类型和HttpServletResponse 类型。HttpServletRequest提供访问有关请求的信息的方法，例如表单数据、HTTP请求头等等。HttpServletResponse除了提供用于指定HTTP应答状态（200，404等）、应答头（Content-Type，Set-Cookie等）的方法之外，最重要的是它提供了一个用于向客户端发送数据的PrintWriter 。对于简单的Servlet来说，它的大部分工作是通过println语句生成向客户端发送的页面。 <br />   <br />  　　 注意doGet和doPost抛出两个异常，因此你必须在声明中包含它们。另外，你还必须导入java.io包（要用到PrintWriter等类）、javax.servlet包（要用到HttpServlet等类）以及javax.servlet.http包（要用到HttpServletRequest类和HttpServletResponse类）。 <br />   <br />  　　 最后，doGet和doPost这两个方法是由service方法调用的，有时你可能需要直接覆盖service方法，比如Servlet要处理GET和POST两种请求时。 <br />   <br />  　　 3.2 输出纯文本的简单Servlet <br />   <br />  　　 下面是一个输出纯文本的简单Servlet。 <br />   <br />  　　 3.2.1 HelloWorld.java <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />   <br />  public class HelloWorld extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   PrintWriter out = response.getWriter(); <br />   out.println("Hello World"); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 3.2.2 Servlet的编译和安装 <br />   <br />  　　 不同的Web服务器上安装Servlet的具体细节可能不同，请参考Web服务器文档了解更权威的说明。假定使用Java Web Server（JWS）2.0，则Servlet应该安装到JWS安装目录的servlets子目录下。在本文中，为了避免同一服务器上不同用户的Servlet命名冲突，我们把所有Servlet都放入一个独立的包hall中；如果你和其他人共用一个服务器，而且该服务器没有“虚拟服务器”机制来避免这种命名冲突，那么最好也使用包。把Servlet放入了包hall之后，HelloWorld.java实际上是放在servlets目录的hall子目录下。 <br />   <br />  　　 大多数其他服务器的配置方法也相似，除了JWS之外，本文的Servlet和JSP示例已经在BEA WebLogic和IBM WebSphere 3.0下经过测试。WebSphere具有优秀的虚拟服务器机制，因此，如果只是为了避免命名冲突的话并非一定要用包。 <br />   <br />  　　 对于没有使用过包的初学者，下面我们介绍编译包里面的类的两种方法。 <br />   <br />  　　 一种方法是设置CLASSPATH，使其指向实际存放Servlet的目录的上一级目录（Servlet主目录），然后在该目录中按正常的方式编译。例如，如果Servlet的主目录是C:＼JavaWebServer＼servlets，包的名字（即主目录下的子目录名字）是hall，在Windows下，编译过程如下： <br />   DOS＞ set CLASSPATH=C:＼JavaWebServer＼servlets;%CLASSPATH% <br />   DOS＞ cd C:＼JavaWebServer＼servlets＼hall <br />   DOS＞ javac YourServlet.java <br />   <br />   <br />   <br />  　　 第二种编译包里面的Servlet的方法是进入Servlet主目录，执行“javac directory＼YourServlet.java”（Windows）或者“javac directory/YourServlet.java”（Unix）。例如，再次假定Servlet主目录是C:＼JavaWebServer＼servlets，包的名字是hall，在Windows中编译过程如下： <br />   DOS＞ cd C:＼JavaWebServer＼servlets <br />   DOS＞ javac hall＼YourServlet.java <br />   <br />   <br />   <br />  　　 注意在Windows下，大多数JDK 1.1版本的javac要求目录名字后面加反斜杠(＼)。JDK1.2已经改正这个问题，然而由于许多Web服务器仍旧使用JDK 1.1，因此大量的Servlet开发者仍旧在使用JDK 1.1。 <br />   <br />  　　 最后，Javac还有一个高级选项用于支持源代码和.class文件的分开放置，即你可以用javac的“-d”选项把.class文件安装到Web服务器所要求的目录。 <br />   <br />  　　 3.2.3 运行Servlet <br />   <br />  　　 在Java Web Server下，Servlet应该放到JWS安装目录的servlets子目录下，而调用Servlet的URL是<a href="http://host/servlet/ServletName"><u><font color="#0000ff">http://host/servlet/ServletName</font></u></a>。注意子目录的名字是servlets（带“s”），而URL使用的是“servlet”。由于HelloWorld Servlet放入包hall，因此调用它的URL应该是<a href="http://host/servlet/hall.HelloWorld"><u><font color="#0000ff">http://host/servlet/hall.HelloWorld</font></u></a>。在其他的服务器上，安装和调用Servlet的方法可能略有不同。 <br />   <br />  　　 大多数Web服务器还允许定义Servlet的别名，因此Servlet也可能用<a href="http://host/any-path/any-file.html"><u><font color="#0000ff">http://host/any-path/any-file.html</font></u></a>形式的URL调用。具体如何进行配置完全依赖于服务器类型，请参考服务器文档了解细节。 <br />   <br />  　　 3.3 输出HTML的Servlet <br />   <br />  　　 大多数Servlet都输出HTML，而不象上例一样输出纯文本。要输出HTML还有两个额外的步骤要做：告诉浏览器接下来发送的是HTML；修改println语句构造出合法的HTML页面。 <br />   <br />  　　 第一步通过设置Content-Type（内容类型）应答头完成。一般地，应答头可以通过HttpServletResponse的setHeader方法设置，但由于设置内容类型是一个很频繁的操作，因此Servlet API提供了一个专用的方法setContentType。注意设置应答头应该在通过PrintWriter发送内容之前进行。下面是一个实例： <br />   <br />  　　 HelloWWW.java <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />   <br />  public class HelloWWW extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   out.println("＜!DOCTYPE HTML PUBLIC ＼"-//W3C//DTD HTML 4.0 " + <br />   "Transitional//EN＼"＞＼n" + <br />   "＜HTML＞＼n" + <br />   "＜HEAD＞＜TITLE＞Hello WWW＜/TITLE＞＜/HEAD＞＼n" + <br />   "＜BODY＞＼n" + <br />   "＜H1＞Hello WWW＜/H1＞＼n" + <br />   "＜/BODY＞＜/HTML＞"); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 3.4 几个HTML工具函数 <br />   <br />  　　 通过println语句输出HTML并不方便，根本的解决方法是使用JavaServer Pages（JSP）。然而，对于标准的Servlet来说，由于Web页面中有两个部分（DOCTYPE和HEAD）一般不会改变，因此可以用工具函数来封装生成这些内容的代码。 <br />   <br />  　　 虽然大多数主流浏览器都会忽略DOCTYPE行，但严格地说HTML规范是要求有DOCTYPE行的，它有助于HTML语法检查器根据所声明的HTML版本检查HTML文档合法性。在许多Web页面中，HEAD部分只包含＜TITLE＞。虽然许多有经验的编写者都会在HEAD中包含许多META标记和样式声明，但这里只考虑最简单的情况。 <br />   <br />  　　 下面的Java方法只接受页面标题为参数，然后输出页面的DOCTYPE、HEAD、TITLE部分。清单如下： <br />   <br />  　　 ServletUtilities.java <br />  package hall; <br />   <br />  public class ServletUtilities { <br />   public static final String DOCTYPE = <br />   "＜!DOCTYPE HTML PUBLIC ＼"-//W3C//DTD HTML 4.0 Transitional//EN＼"＞"; <br />   <br />   public static String headWithTitle(String title) { <br />   return(DOCTYPE + "＼n" + <br />   "＜HTML＞＼n" + <br />   "＜HEAD＞＜TITLE＞" + title + "＜/TITLE＞＜/HEAD＞＼n"); <br />   } <br />   <br />   // 其他工具函数的代码在本文后面介绍 <br />  } <br />   <br />   <br />   <br />   <br />  　　 HelloWWW2.java <br />   <br />  　　 下面是应用了ServletUtilities之后重写HelloWWW类得到的HelloWWW2： <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />   <br />  public class HelloWWW2 extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   out.println(ServletUtilities.headWithTitle("Hello WWW") + <br />   "＜BODY＞＼n" + <br />   "＜H1＞Hello WWW＜/H1＞＼n" + <br />   "＜/BODY＞＜/HTML＞"); <br />   } <br />  } <br />4.1 表单数据概述 <br />   <br />  　　 如果你曾经使用过Web搜索引擎，或者浏览过在线书店、股票价格、机票信息，或许会留意到一些古怪的URL，比如“http://host/path?user=Marty+Hall&amp;origin=bwi&amp;dest=lax”。这个URL中位于问号后面的部分，即“user=Marty+Hall&amp;origin=bwi&amp;dest=lax”，就是表单数据，这是将Web页面数据发送给服务器程序的最常用方法。对于GET请求，表单数据附加到URL的问号后面（如上例所示）；对于POST请求，表单数据用一个单独的行发送给服务器。 <br />   <br />  　　 以前，从这种形式的数据提取出所需要的表单变量是CGI编程中最麻烦的事情之一。首先，GET请求和POST请求的数据提取方法不同：对于GET请求，通常要通过QUERY_STRING环境变量提取数据；对于POST请求，则一般通过标准输入提取数据。第二，程序员必须负责在“&amp;”符号处截断变量名字-变量值对，再分离出变量名字（等号左边）和变量值（等号右边）。第三，必须对变量值进行URL反编码操作。因为发送数据的时候，字母和数字以原来的形式发送，但空格被转换成加号，其他字符被转换成“%XX”形式，其中XX是十六进制表示的字符ASCII（或者ISO Latin-1）编码值。例如，如果HTML表单中名为“users”的域值为“~hall, ~gates, and ~mcnealy”，则实际向服务器发送的数据为“users=%7Ehall%2C+%7Egates%2C+and+%7Emcnealy”。最后，即第四个导致解析表单数据非常困难的原因在于，变量值既可能被省略（如“param1=val1＆param2=＆param3=val3”），也有可能一个变量拥有一个以上的值，即同一个变量可能出现一次以上（如“param1=val1＆param2=val2＆param1=val3”）。 <br />   <br />  　　 Java Servlet的好处之一就在于所有上述解析操作都能够自动完成。只需要简单地调用一下HttpServletRequest的getParameter方法、在调用参数中提供表单变量的名字（大小写敏感）即可，而且GET请求和POST请求的处理方法完全相同。 <br />   <br />  　　 getParameter方法的返回值是一个字符串，它是参数中指定的变量名字第一次出现所对应的值经反编码得到得字符串（可以直接使用）。如果指定的表单变量存在，但没有值，getParameter返回空字符串；如果指定的表单变量不存在，则返回null。如果表单变量可能对应多个值，可以用getParameterValues来取代getParameter。getParameterValues能够返回一个字符串数组。 <br />   <br />  　　 最后，虽然在实际应用中Servlet很可能只会用到那些已知名字的表单变量，但在调试环境中，获得完整的表单变量名字列表往往是很有用的，利用getParamerterNames方法可以方便地实现这一点。getParamerterNames返回的是一个Enumeration，其中的每一项都可以转换为调用getParameter的字符串。 <br />   <br />  　　 4.2 实例：读取三个表单变量 <br />   <br />  　　 下面是一个简单的例子，它读取三个表单变量param1、param2和param3，并以HTML列表的形式列出它们的值。请注意，虽然在发送应答内容之前必须指定应答类型（包括内容类型、状态以及其他HTTP头信息），但Servlet对何时读取请求内容却没有什么要求。 <br />   <br />  　　 另外，我们也可以很容易地把Servlet做成既能处理GET请求，也能够处理POST请求，这只需要在doPost方法中调用doGet方法，或者覆盖service方法（service方法调用doGet、doPost、doHead等方法）。在实际编程中这是一种标准的方法，因为它只需要很少的额外工作，却能够增加客户端编码的灵活性。 <br />   <br />  　　 如果你习惯用传统的CGI方法，通过标准输入读取POST数据，那么在Servlet中也有类似的方法，即在HttpServletRequest上调用getReader或者getInputStream，但这种方法对普通的表单变量来说太麻烦。然而，如果是要上载文件，或者POST数据是通过专门的客户程序而不是HTML表单发送，那么就要用到这种方法。 <br />   <br />  　　 注意用第二种方法读取POST数据时，不能再用getParameter来读取这些数据。 <br />   <br />  　　 ThreeParams.java <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.util.*; <br />   <br />  public class ThreeParams extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   String title = "读取三个请求参数"; <br />   out.println(ServletUtilities.headWithTitle(title) + <br />   "＜BODY＞＼n" + <br />   "＜H1 ALIGN=CENTER＞" + title + "＜/H1＞＼n" + <br />   "＜UL＞＼n" + <br />   " ＜LI＞param1: " <br />   + request.getParameter("param1") + "＼n" + <br />   " ＜LI＞param2: " <br />   + request.getParameter("param2") + "＼n" + <br />   " ＜LI＞param3: " <br />   + request.getParameter("param3") + "＼n" + <br />   "＜/UL＞＼n" + <br />   "＜/BODY＞＜/HTML＞"); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 4.3 实例：输出所有的表单数据 <br />   <br />  　　 下面这个例子寻找表单所发送的所有变量名字，并把它们放入表格中，没有值或者有多个值的变量都突出显示。 <br />   <br />  　　 首先，程序通过HttpServletRequest的getParameterNames方法得到所有的变量名字，getParameterNames返回的是一个Enumeration。接下来，程序用循环遍历这个Enumeration，通过hasMoreElements确定何时结束循环，利用nextElement得到Enumeration中的各个项。由于nextElement返回的是一个Object，程序把它转换成字符串后再用这个字符串来调用getParameterValues。 <br />   <br />  　　 getParameterValues返回一个字符串数组，如果这个数组只有一个元素且等于空字符串，说明这个表单变量没有值，Servlet以斜体形式输出“No Value”；如果数组元素个数大于1，说明这个表单变量有多个值，Servlet以HTML列表形式输出这些值；其他情况下Servlet直接把变量值放入表格。 <br />   <br />  　　 ShowParameters.java <br />   <br />  　　 注意，ShowParameters.java用到了前面介绍过的ServletUtilities.java。 <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.util.*; <br />   <br />  public class ShowParameters extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   String title = "读取所有请求参数"; <br />   out.println(ServletUtilities.headWithTitle(title) + <br />   "＜BODY BGCOLOR=＼"#FDF5E6＼"＞＼n" + <br />   "＜H1 ALIGN=CENTER＞" + title + "＜/H1＞＼n" + <br />   "＜TABLE BORDER=1 ALIGN=CENTER＞＼n" + <br />   "＜TR BGCOLOR=＼"#FFAD00＼"＞＼n" + <br />   "＜TH＞参数名字＜TH＞参数值"); <br />   Enumeration paramNames = request.getParameterNames(); <br />   while(paramNames.hasMoreElements()) { <br />   String paramName = (String)paramNames.nextElement(); <br />   out.println("＜TR＞＜TD＞" + paramName + "＼n＜TD＞"); <br />   String[] paramValues = request.getParameterValues(paramName); <br />   if (paramValues.length == 1) { <br />   String paramValue = paramValues[0]; <br />   if (paramValue.length() == 0) <br />   out.print("＜I＞No Value＜/I＞"); <br />   else <br />   out.print(paramValue); <br />   } else { <br />   out.println("＜UL＞"); <br />   for(int i=0; i＜paramValues.length; i++) { <br />   out.println("＜LI＞" + paramValues[i]); <br />   } <br />   out.println("＜/UL＞"); <br />   } <br />   } <br />   out.println("＜/TABLE＞＼n＜/BODY＞＜/HTML＞"); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 测试表单 <br />   <br />  　　 下面是向上述Servlet发送数据的表单PostForm.html。就像所有包含密码输入域的表单一样，该表单用POST方法发送数据。我们可以看到，在Servlet中同时实现doGet和doPost这两种方法为表单制作带来了方便。 <br />  ＜!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"＞ <br />  ＜HTML＞ <br />  ＜HEAD＞ <br />   ＜TITLE＞示例表单＜/TITLE＞ <br />  ＜/HEAD＞ <br />   <br />  ＜BODY BGCOLOR="#FDF5E6"＞ <br />  ＜H1 ALIGN="CENTER"＞用POST方法发送数据的表单＜/H1＞ <br />   <br />  ＜FORM ACTION="/servlet/hall.ShowParameters" <br />   METHOD="POST"＞ <br />   Item Number: <br />   ＜INPUT TYPE="TEXT" NAME="itemNum"＞＜BR＞ <br />   Quantity: <br />   ＜INPUT TYPE="TEXT" NAME="quantity"＞＜BR＞ <br />   Price Each: <br />   ＜INPUT TYPE="TEXT" NAME="price" VALUE="$"＞＜BR＞ <br />   ＜HR＞ <br />   First Name: <br />   ＜INPUT TYPE="TEXT" NAME="firstName"＞＜BR＞ <br />   Last Name: <br />   ＜INPUT TYPE="TEXT" NAME="lastName"＞＜BR＞ <br />   Middle Initial: <br />   ＜INPUT TYPE="TEXT" NAME="initial"＞＜BR＞ <br />   Shipping Address: <br />   ＜TEXTAREA NAME="address" ROWS=3 COLS=40＞＜/TEXTAREA＞＜BR＞ <br />   Credit Card:＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="cardType" <br />   VALUE="Visa"＞Visa＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="cardType" <br />   VALUE="Master Card"＞Master Card＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="cardType" <br />   VALUE="Amex"＞American Express＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="cardType" <br />   VALUE="Discover"＞Discover＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="cardType" <br />   VALUE="Java SmartCard"＞Java SmartCard＜BR＞ <br />   Credit Card Number: <br />   ＜INPUT TYPE="PASSWORD" NAME="cardNum"＞＜BR＞ <br />   Repeat Credit Card Number: <br />   ＜INPUT TYPE="PASSWORD" NAME="cardNum"＞＜BR＞＜BR＞ <br />   ＜CENTER＞ <br />   ＜INPUT TYPE="SUBMIT" VALUE="Submit Order"＞ <br />   ＜/CENTER＞ <br />  ＜/FORM＞ <br />   <br />  ＜/BODY＞ <br />  ＜/HTML＞ <br />5.1 HTTP请求头概述 <br />   <br />  　　 HTTP客户程序（例如浏览器），向服务器发送请求的时候必须指明请求类型（一般是GET或者POST）。如有必要，客户程序还可以选择发送其他的请求头。大多数请求头并不是必需的，但Content-Length除外。对于POST请求来说Content-Length必须出现。 <br />   <br />  　　 下面是一些最常见的请求头： <br />   <br />  Accept：浏览器可接受的MIME类型。 <br />  Accept-Charset：浏览器可接受的字符集。 <br />  Accept-Encoding：浏览器能够进行解码的数据编码方式，比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。 <br />  Accept-Language：浏览器所希望的语言种类，当服务器能够提供一种以上的语言版本时要用到。 <br />  Authorization：授权信息，通常出现在对服务器发送的WWW-Authenticate头的应答中。 <br />  Connection：表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”，或者看到请求使用的是HTTP 1.1（HTTP 1.1默认进行持久连接），它就可以利用持久连接的优点，当页面包含多个元素时（例如Applet，图片），显著地减少下载所需要的时间。要实现这一点，Servlet需要在应答中发送一个Content-Length头，最简单的实现方法是：先把内容写入ByteArrayOutputStream，然后在正式写出内容之前计算它的大小。 <br />  Content-Length：表示请求消息正文的长度。 <br />  Cookie：这是最重要的请求头信息之一，参见后面《Cookie处理》一章中的讨论。 <br />  From：请求发送者的email地址，由一些特殊的Web客户程序使用，浏览器不会用到它。 <br />  Host：初始URL中的主机和端口。 <br />  If-Modified-Since：只有当所请求的内容在指定的日期之后又经过修改才返回它，否则返回304“Not Modified”应答。 <br />  Pragma：指定“no-cache”值表示服务器必须返回一个刷新后的文档，即使它是代理服务器而且已经有了页面的本地拷贝。 <br />  Referer：包含一个URL，用户从该URL代表的页面出发访问当前请求的页面。 <br />  User-Agent：浏览器类型，如果Servlet返回的内容与浏览器类型有关则该值非常有用。 <br />  UA-Pixels，UA-Color，UA-OS，UA-CPU：由某些版本的IE浏览器所发送的非标准的请求头，表示屏幕大小、颜色深度、操作系统和CPU类型。 <br />  　　 有关HTTP头完整、详细的说明，请参见<a href="http://www.w3.org/Protocols/"><u><font color="#0000ff">http://www.w3.org/Protocols/</font></u></a> 的HTTP规范。 <br />   <br />  　　 5.2 在Servlet中读取请求头 <br />   <br />  　　 在Servlet中读取HTTP头是非常方便的，只需要调用一下HttpServletRequest的getHeader方法即可。如果客户请求中提供了指定的头信息，getHeader返回对应的字符串；否则，返回null。部分头信息经常要用到，它们有专用的访问方法：getCookies方法返回Cookie头的内容，经解析后存放在Cookie对象的数组中，请参见后面有关Cookie章节的讨论；getAuthType和getRemoteUser方法分别读取Authorization头中的一部分内容；getDateHeader和getIntHeader方法读取指定的头，然后返回日期值或整数值。 <br />   <br />  　　 除了读取指定的头之外，利用getHeaderNames还可以得到请求中所有头名字的一个Enumeration对象。 <br />   <br />  　　 最后，除了查看请求头信息之外，我们还可以从请求主命令行获得一些信息。getMethod方法返回请求方法，请求方法通常是GET或者POST，但也有可能是HEAD、PUT或者DELETE。getRequestURI方法返回URI（URI是URL的从主机和端口之后到表单数据之前的那一部分）。getRequestProtocol返回请求命令的第三部分，一般是“HTTP/1.0”或者“HTTP/1.1”。 <br />   <br />  　　 5.3 实例：输出所有的请求头 <br />   <br />  　　 下面的Servlet实例把所有接收到的请求头和它的值以表格的形式输出。另外，该Servlet还会输出主请求命令的三个部分：请求方法，URI，协议/版本。 <br />   <br />  　　 ShowRequestHeaders.java <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.util.*; <br />   <br />  public class ShowRequestHeaders extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   String title = "显示所有请求头"; <br />   out.println(ServletUtilities.headWithTitle(title) + <br />   "＜BODY BGCOLOR=＼"#FDF5E6＼"＞＼n" + <br />   "＜H1 ALIGN=CENTER＞" + title + "＜/H1＞＼n" + <br />   "＜B＞Request Method: ＜/B＞" + <br />   request.getMethod() + "＜BR＞＼n" + <br />   "＜B＞Request URI: ＜/B＞" + <br />   request.getRequestURI() + "＜BR＞＼n" + <br />   "＜B＞Request Protocol: ＜/B＞" + <br />   request.getProtocol() + "＜BR＞＜BR＞＼n" + <br />   "＜TABLE BORDER=1 ALIGN=CENTER＞＼n" + <br />   "＜TR BGCOLOR=＼"#FFAD00＼"＞＼n" + <br />   "＜TH＞Header Name＜TH＞Header Value"); <br />   Enumeration headerNames = request.getHeaderNames(); <br />   while(headerNames.hasMoreElements()) { <br />   String headerName = (String)headerNames.nextElement(); <br />   out.println("＜TR＞＜TD＞" + headerName); <br />   out.println(" ＜TD＞" + request.getHeader(headerName)); <br />   } <br />   out.println("＜/TABLE＞＼n＜/BODY＞＜/HTML＞"); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />  } <br />6.1 CGI变量概述 <br />   <br />  　　 如果你是从传统的CGI编程转而学习Java Servlet，或许已经习惯了“CGI变量”这一概念。CGI变量汇集了各种有关请求的信息： <br />   <br />  部分来自HTTP请求命令和请求头，例如Content-Length头； <br />  部分来自Socket本身，例如主机的名字和IP地址； <br />  也有部分与服务器安装配置有关，例如URL到实际路径的映射。 <br />  　　 6.2 标准CGI变量的Servlet等价表示 <br />   <br />  　　 下表假定request对象是提供给doGet和doPost方法的HttpServletRequest类型对象。 CGI变量 含义 从doGet或doPost访问 <br />  AUTH_TYPE 如果提供了Authorization头，这里指定了具体的模式（basic或者digest）。 request.getAuthType() <br />  CONTENT_LENGTH 只用于POST请求，表示所发送数据的字节数。 严格地讲，等价的表达方式应该是String.valueOf(request.getContentLength())（返回一个字符串）。但更常见的是用request.getContentLength()返回含义相同的整数。 <br />  CONTENT_TYPE 如果指定的话，表示后面所跟数据的类型。 request.getContentType() <br />  DOCUMENT_ROOT 与<a href="http://host/"><u><font color="#0000ff">http://host/</font></u></a>对应的路径。 getServletContext().getRealPath("/") <br />  注意低版本Servlet规范中的等价表达方式是request.getRealPath("/")。 <br />   <br />  HTTP_XXX_YYY 访问任意HTTP头。 request.getHeader("Xxx-Yyy") <br />  PATH_INFO URL中的附加路径信息，即URL中Servlet路径之后、查询字符串之前的那部分。 request.getPathInfo() <br />  PATH_TRANSLATED 映射到服务器实际路径之后的路径信息。 request.getPathTranslated() <br />  QUERY_STRING 这是字符串形式的附加到URL后面的查询字符串，数据仍旧是URL编码的。在Servlet中很少需要用到未经解码的数据，一般使用getParameter访问各个参数。 request.getQueryString() <br />  REMOTE_ADDR 发出请求的客户机的IP地址。 request.getRemoteAddr() <br />  REMOTE_HOST 发出请求的客户机的完整的域名，如java.sun.com。如果不能确定该域名，则返回IP地址。 request.getRemoteHost() <br />  REMOTE_USER 如果提供了Authorization头，则代表其用户部分。它代表发出请求的用户的名字。 request.getRemoteUser() <br />  REQUEST_METHOD 请求类型。通常是GET或者POST。但偶尔也会出现HEAD，PUT， DELETE，OPTIONS，或者 TRACE. request.getMethod() <br />  SCRIPT_NAME URL中调用Servlet的那一部分，不包含附加路径信息和查询字符串。 request.getServletPath() <br />  SERVER_NAME Web服务器名字。 request.getServerName() <br />  SERVER_PORT 服务器监听的端口。 严格地说，等价表达应该是返回字符串的String.valueOf(request.getServerPort())。但经常使用返回整数值的request.getServerPort()。 <br />  SERVER_PROTOCOL 请求命令中的协议名字和版本（即HTTP/1.0或HTTP/1.1）。 request.getProtocol() <br />  SERVER_SOFTWARE Servlet引擎的名字和版本。 getServletContext().getServerInfo() <br />   <br />   <br />  　　 6.3 实例：读取CGI变量 <br />   <br />  　　 下面这个Servlet创建一个表格，显示除了HTTP_XXX_YYY之外的所有CGI变量。HTTP_XXX_YYY是HTTP请求头信息，请参见上一节介绍。 <br />   <br />  　　 ShowCGIVariables.java <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.util.*; <br />   <br />  public class ShowCGIVariables extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   String[][] variables = <br />   { { "AUTH_TYPE", request.getAuthType() }, <br />   { "CONTENT_LENGTH", String.valueOf(request.getContentLength()) }, <br />   { "CONTENT_TYPE", request.getContentType() }, <br />   { "DOCUMENT_ROOT", getServletContext().getRealPath("/") }, <br />   { "PATH_INFO", request.getPathInfo() }, <br />   { "PATH_TRANSLATED", request.getPathTranslated() }, <br />   { "QUERY_STRING", request.getQueryString() }, <br />   { "REMOTE_ADDR", request.getRemoteAddr() }, <br />   { "REMOTE_HOST", request.getRemoteHost() }, <br />   { "REMOTE_USER", request.getRemoteUser() }, <br />   { "REQUEST_METHOD", request.getMethod() }, <br />   { "SCRIPT_NAME", request.getServletPath() }, <br />   { "SERVER_NAME", request.getServerName() }, <br />   { "SERVER_PORT", String.valueOf(request.getServerPort()) }, <br />   { "SERVER_PROTOCOL", request.getProtocol() }, <br />   { "SERVER_SOFTWARE", getServletContext().getServerInfo() } <br />   }; <br />   String title = "显示CGI变量"; <br />   out.println(ServletUtilities.headWithTitle(title) + <br />   "＜BODY BGCOLOR=＼"#FDF5E6＼"＞＼n" + <br />   "＜H1 ALIGN=CENTER＞" + title + "＜/H1＞＼n" + <br />   "＜TABLE BORDER=1 ALIGN=CENTER＞＼n" + <br />   "＜TR BGCOLOR=＼"#FFAD00＼"＞＼n" + <br />   "＜TH＞CGI Variable Name＜TH＞Value"); <br />   for(int i=0; i＜variables.length; i++) { <br />   String varName = variables[i][0]; <br />   String varValue = variables[i][1]; <br />   if (varValue == null) <br />   varValue = "＜I＞Not specified＜/I＞"; <br />   out.println("＜TR＞＜TD＞" + varName + "＜TD＞" + varValue); <br />   } <br />   out.println("＜/TABLE＞＜/BODY＞＜/HTML＞"); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />  } <br />7.1 状态代码概述 <br />   <br />  　　 Web服务器响应浏览器或其他客户程序的请求时，其应答一般由以下几个部分组成：一个状态行，几个应答头，一个空行，内容文档。下面是一个最简单的应答： <br />  HTTP/1.1 200 OK <br />  Content-Type: text/plain <br />   <br />  Hello World <br />   <br />   <br />   <br />   <br />  　　 状态行包含HTTP版本、状态代码、与状态代码对应的简短说明信息。在大多数情况下，除了Content-Type之外的所有应答头都是可选的。但Content-Type是必需的，它描述的是后面文档的MIME类型。虽然大多数应答都包含一个文档，但也有一些不包含，例如对HEAD请求的应答永远不会附带文档。有许多状态代码实际上用来标识一次失败的请求，这些应答也不包含文档（或只包含一个简短的错误信息说明）。 <br />   <br />  　　 Servlet可以利用状态代码来实现许多功能。例如，可以把用户重定向到另一个网站；可以指示出后面的文档是图片、PDF文件或HTML文件；可以告诉用户必须提供密码才能访问文档；等等。这一部分我们将具体讨论各种状态代码的含义以及利用这些代码可以做些什么。 <br />   <br />  　　 7.2 设置状态代码 <br />   <br />  　　 如前所述，HTTP应答状态行包含HTTP版本、状态代码和对应的状态信息。由于状态信息直接和状态代码相关，而HTTP版本又由服务器确定，因此需要Servlet设置的只有一个状态代码。 <br />   <br />  　　 Servlet设置状态代码一般使用HttpServletResponse的setStatus方法。setStatus方法的参数是一个整数（即状态代码），不过为了使得代码具有更好的可读性，可以用HttpServletResponse中定义的常量来避免直接使用整数。这些常量根据HTTP 1.1中的标准状态信息命名，所有的名字都加上了SC前缀（Status Code的缩写）并大写，同时把空格转换成了下划线。也就是说，与状态代码404对应的状态信息是“Not Found”，则HttpServletResponse中的对应常量名字为SC_NOT_FOUND。但有两个例外：和状态代码302对应的常量根据HTTP 1.0命名，而307没有对应的常量。 <br />   <br />  　　 设置状态代码并非总是意味着不要再返回文档。例如，虽然大多数服务器返回404应答时会输出简单的“File Not Found”信息，但Servlet也可以定制这个应答。不过，定制应答时应当在通过PrintWriter发送任何内容之前先调用response.setStatus。 <br />   <br />  　　 虽然设置状态代码一般使用的是response.setStauts(int)方法，但为了简单起见，HttpServletResponse为两种常见的情形提供了专用方法：sendError方法生成一个404应答，同时生成一个简短的HTML错误信息文档；sendRedirect方法生成一个302应答，同时在Location头中指示新文档的URL。 <br />   <br />  　　 7.3 HTTP 1.1状态代码及其含义 <br />   <br />  　　 下表显示了常见的HTTP 1.1状态代码以及它们对应的状态信息和含义。 <br />   <br />  　　 应当谨慎地使用那些只有HTTP 1.1支持的状态代码，因为许多浏览器还只能够支持HTTP 1.0。如果你使用了HTTP 1.1特有的状态代码，最好能够检查一下请求的HTTP版本号（通过HttpServletRequest的getProtocol方法）。 状态代码 状态信息 含义 <br />  100 Continue 初始的请求已经接受，客户应当继续发送请求的其余部分。（HTTP 1.1新） <br />  101 Switching Protocols 服务器将遵从客户的请求转换到另外一种协议（HTTP 1.1新） <br />  200 OK 一切正常，对GET和POST请求的应答文档跟在后面。如果不用setStatus设置状态代码，Servlet默认使用202状态代码。 <br />  201 Created 服务器已经创建了文档，Location头给出了它的URL。 <br />  202 Accepted 已经接受请求，但处理尚未完成。 <br />  203 Non-Authoritative Information 文档已经正常地返回，但一些应答头可能不正确，因为使用的是文档的拷贝（HTTP 1.1新）。 <br />  204 No Content 没有新文档，浏览器应该继续显示原来的文档。如果用户定期地刷新页面，而Servlet可以确定用户文档足够新，这个状态代码是很有用的。 <br />  205 Reset Content 没有新的内容，但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容（HTTP 1.1新）。 <br />  206 Partial Content 客户发送了一个带有Range头的GET请求，服务器完成了它（HTTP 1.1新）。 <br />  300 Multiple Choices 客户请求的文档可以在多个位置找到，这些位置已经在返回的文档内列出。如果服务器要提出优先选择，则应该在Location应答头指明。 <br />  301 Moved Permanently 客户请求的文档在其他地方，新的URL在Location头中给出，浏览器应该自动地访问新的URL。 <br />  302 Found 类似于301，但新的URL应该被视为临时性的替代，而不是永久性的。注意，在HTTP1.0中对应的状态信息是“Moved Temporatily”，而HttpServletResponse中相应的常量是SC_MOVED_TEMPORARILY，而不是SC_FOUND。 <br />  出现该状态代码时，浏览器能够自动访问新的URL，因此它是一个很有用的状态代码。为此，Servlet提供了一个专用的方法，即sendRedirect。使用response.sendRedirect(url)比使用response.setStatus(response.SC_MOVED_TEMPORARILY)和response.setHeader("Location",url)更好。这是因为： <br />   <br />  首先，代码更加简洁。 <br />  第二，使用sendRedirect，Servlet会自动构造一个包含新链接的页面（用于那些不能自动重定向的老式浏览器）。 <br />  最后，sendRedirect能够处理相对URL，自动把它们转换成绝对URL。 <br />  注意这个状态代码有时候可以和301替换使用。例如，如果浏览器错误地请求<a href="http://host/~user"><u><font color="#0000ff">http://host/~user</font></u></a>（缺少了后面的斜杠），有的服务器返回301，有的则返回302。 <br />   <br />  严格地说，我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 <br />   <br />  303 See Other 类似于301/302，不同之处在于，如果原来的请求是POST，Location头指定的重定向目标文档应该通过GET提取（HTTP 1.1新）。 <br />  304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求（一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档）。服务器告诉客户，原来缓冲的文档还可以继续使用。 <br />  305 Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取（HTTP 1.1新）。 <br />  307 Temporary Redirect 和302（Found）相同。许多浏览器会错误地响应302应答进行重定向，即使原来的请求是POST，即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因，HTTP 1.1新增了307，以便更加清除地区分几个状态代码：当出现303应答时，浏览器可以跟随重定向的GET和POST请求；如果是307应答，则浏览器只能跟随对GET请求的重定向。 <br />  注意，HttpServletResponse中没有为该状态代码提供相应的常量。（HTTP 1.1新） <br />   <br />  400 Bad Request 请求出现语法错误。 <br />  401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头，浏览器据此显示用户名字/密码对话框，然后在填写合适的Authorization头后再次发出请求。 <br />  403 Forbidden 资源不可用。服务器理解客户的请求，但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。 <br />  404 Not Found 无法找到指定位置的资源。这也是一个常用的应答，HttpServletResponse专门提供了相应的方法：sendError(message)。 <br />  405 Method Not Allowed 请求方法（GET、POST、HEAD、DELETE、PUT、TRACE等）对指定的资源不适用。（HTTP 1.1新） <br />  406 Not Acceptable 指定的资源已经找到，但它的MIME类型和客户在Accpet头中所指定的不兼容（HTTP 1.1新）。 <br />  407 Proxy Authentication Required 类似于401，表示客户必须先经过代理服务器的授权。（HTTP 1.1新） <br />  408 Request Timeout 在服务器许可的等待时间内，客户一直没有发出任何请求。客户可以在以后重复同一请求。（HTTP 1.1新） <br />  409 Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突，因此请求不能成功。（HTTP 1.1新） <br />  410 Gone 所请求的文档已经不再可用，而且服务器不知道应该重定向到哪一个地址。它和404的不同在于，返回407表示文档永久地离开了指定的位置，而404表示由于未知的原因文档不可用。（HTTP 1.1新） <br />  411 Length Required 服务器不能处理请求，除非客户发送一个Content-Length头。（HTTP 1.1新） <br />  412 Precondition Failed 请求头中指定的一些前提条件失败（HTTP 1.1新）。 <br />  413 Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求，则应该提供一个Retry-After头（HTTP 1.1新）。 <br />  414 Request URI Too Long URI太长（HTTP 1.1新）。 <br />  416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。（HTTP 1.1新） <br />  500 Internal Server Error 服务器遇到了意料不到的情况，不能完成客户的请求。 <br />  501 Not Implemented 服务器不支持实现请求所需要的功能。例如，客户发出了一个服务器不支持的PUT请求。 <br />  502 Bad Gateway 服务器作为网关或者代理时，为了完成请求访问下一个服务器，但该服务器返回了非法的应答。 <br />  503 Service Unavailable 服务器由于维护或者负载过重未能应答。例如，Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。 <br />  504 Gateway Timeout 由作为代理或网关的服务器使用，表示不能及时地从远程服务器获得应答。（HTTP 1.1新） <br />  505 HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本。（HTTP 1.1新） <br />   <br />   <br />  　　 7.4 实例：访问多个搜索引擎 <br />   <br />  　　 下面这个例子用到了除200之外的另外两个常见状态代码：302和404。302通过sendRedirect方法设置，404通过sendError方法设置。 <br />   <br />  　　 在这个例子中，首先出现的HTML表单用来选择搜索引擎、搜索字符串、每页显示的搜索结果数量。表单提交后，Servlet提取这三个变量，按照所选择的搜索引擎的要求构造出包含这些变量的URL，然后把用户重定向到这个URL。如果用户不能正确地选择搜索引擎，或者利用其他表单发送了一个不认识的搜索引擎名字，则返回一个提示搜索引擎找不到的404页面。 <br />   <br />  　　 SearchEngines.java <br />   <br />  　　 注意：这个Servlet要用到后面给出的SearchSpec类，SearchSpec的功能是构造适合不同搜索引擎的URL。 <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.net.*; <br />   <br />  public class SearchEngines extends HttpServlet { <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   // getParameter自动解码URL编码的查询字符串。由于我们 <br />   // 要把查询字符串发送给另一个服务器，因此再次使用 <br />   // URLEncoder进行URL编码 <br />   String searchString = <br />   URLEncoder.encode(request.getParameter("searchString")); <br />   String numResults = <br />   request.getParameter("numResults"); <br />   String searchEngine = <br />   request.getParameter("searchEngine"); <br />   SearchSpec[] commonSpecs = SearchSpec.getCommonSpecs(); <br />   for(int i=0; i＜commonSpecs.length; i++) { <br />   SearchSpec searchSpec = commonSpecs[i]; <br />   if (searchSpec.getName().equals(searchEngine)) { <br />   String url = <br />   response.encodeURL(searchSpec.makeURL(searchString, <br />   numResults)); <br />   response.sendRedirect(url); <br />   return; <br />   } <br />   } <br />   response.sendError(response.SC_NOT_FOUND, <br />   "No recognized search engine specified."); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 SearchSpec.java <br />  package hall; <br />   <br />  class SearchSpec { <br />   private String name, baseURL, numResultsSuffix; <br />   <br />   private static SearchSpec[] commonSpecs = <br />   { new SearchSpec("google", <br />   "<a href="http://www.google.com/search?q"><u><font color="#0000ff">http://www.google.com/search?q</font></u></a>=", <br />   "&amp;num="), <br />   new SearchSpec("infoseek", <br />   "<a href="http://infoseek.go.com/Titles?qt"><u><font color="#0000ff">http://infoseek.go.com/Titles?qt</font></u></a>=", <br />   "&amp;nh="), <br />   new SearchSpec("lycos", <br />   "<a href="http://lycospro.lycos.com/cgi-bin/pursuit?query"><u><font color="#0000ff">http://lycospro.lycos.com/cgi-bin/pursuit?query</font></u></a>=", <br />   "&amp;maxhits="), <br />   new SearchSpec("hotbot", <br />   "<a href="http://www.hotbot.com/?MT"><u><font color="#0000ff">http://www.hotbot.com/?MT</font></u></a>=", <br />   "&amp;DC=") <br />   }; <br />   <br />   public SearchSpec(String name, <br />   String baseURL, <br />   String numResultsSuffix) { <br />   this.name = name; <br />   this.baseURL = baseURL; <br />   this.numResultsSuffix = numResultsSuffix; <br />   } <br />   <br />   public String makeURL(String searchString, String numResults) { <br />   return(baseURL + searchString + numResultsSuffix + numResults); <br />   } <br />   <br />   public String getName() { <br />   return(name); <br />   } <br />   <br />   public static SearchSpec[] getCommonSpecs() { <br />   return(commonSpecs); <br />   } <br />  } <br />   <br />   <br />   <br />   <br />  　　 SearchEngines.html <br />   <br />  　　 下面是调用上述Servlet的HTML表单。 <br />  ＜!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"＞ <br />  ＜HTML＞ <br />  ＜HEAD＞ <br />   ＜TITLE＞访问多个搜索引擎＜/TITLE＞ <br />  ＜/HEAD＞ <br />   <br />  ＜BODY BGCOLOR="#FDF5E6"＞ <br />   <br />  ＜FORM ACTION="/servlet/hall.SearchEngines"＞ <br />   ＜CENTER＞ <br />   搜索关键字: <br />   ＜INPUT TYPE="TEXT" NAME="searchString"＞＜BR＞ <br />   每页显示几个查询结果: <br />   ＜INPUT TYPE="TEXT" NAME="numResults" <br />   VALUE=10 SIZE=3＞＜BR＞ <br />   ＜INPUT TYPE="RADIO" NAME="searchEngine" <br />   VALUE="google"＞ <br />   Google | <br />   ＜INPUT TYPE="RADIO" NAME="searchEngine" <br />   VALUE="infoseek"＞ <br />   Infoseek | <br />   ＜INPUT TYPE="RADIO" NAME="searchEngine" <br />   VALUE="lycos"＞ <br />   Lycos | <br />   ＜INPUT TYPE="RADIO" NAME="searchEngine" <br />   VALUE="hotbot"＞ <br />   HotBot <br />   ＜BR＞ <br />   ＜INPUT TYPE="SUBMIT" VALUE="Search"＞ <br />   ＜/CENTER＞ <br />  ＜/FORM＞ <br />   <br />  ＜/BODY＞ <br />  ＜/HTML＞ <br />8.1 HTTP应答头概述 <br />   <br />  　　 Web服务器的HTTP应答一般由以下几项构成：一个状态行，一个或多个应答头，一个空行，内容文档。设置HTTP应答头往往和设置状态行中的状态代码结合起来。例如，有好几个表示“文档位置已经改变”的状态代码都伴随着一个Location头，而401（Unauthorized）状态代码则必须伴随一个WWW-Authenticate头。 <br />   <br />  　　 然而，即使在没有设置特殊含义的状态代码时，指定应答头也是很有用的。应答头可以用来完成：设置Cookie，指定修改日期，指示浏览器按照指定的间隔刷新页面，声明文档的长度以便利用持久HTTP连接，……等等许多其他任务。 <br />   <br />  　　 设置应答头最常用的方法是HttpServletResponse的setHeader，该方法有两个参数，分别表示应答头的名字和值。和设置状态代码相似，设置应答头应该在发送任何文档内容之前进行。 <br />   <br />  　　 setDateHeader方法和setIntHeadr方法专门用来设置包含日期和整数值的应答头，前者避免了把Java时间转换为GMT时间字符串的麻烦，后者则避免了把整数转换为字符串的麻烦。 <br />   <br />  　　 HttpServletResponse还提供了许多设置常见应答头的简便方法，如下所示： <br />   <br />  setContentType：设置Content-Type头。大多数Servlet都要用到这个方法。 <br />  setContentLength：设置Content-Length头。对于支持持久HTTP连接的浏览器来说，这个函数是很有用的。 <br />  addCookie：设置一个Cookie（Servlet API中没有setCookie方法，因为应答往往包含多个Set-Cookie头）。 <br />  另外，如上节介绍，sendRedirect方法设置状态代码302时也会设置Location头。 <br />  　　 8.2 常见应答头及其含义 <br />   <br />  　　 有关HTTP头详细和完整的说明，请参见<a href="http://www.w3.org/Protocols/"><u><font color="#0000ff">http://www.w3.org/Protocols/</font></u></a> 规范。 <br />   <br />  应答头 说明 <br />  Allow 服务器支持哪些请求方法（如GET、POST等）。 <br />  Content-Encoding 文档的编码（Encode）方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩，但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此，Servlet应该通过查看Accept-Encoding头（即request.getHeader("Accept-Encoding")）检查浏览器是否支持gzip，为支持gzip的浏览器返回经gzip压缩的HTML页面，为其他浏览器返回普通页面。 <br />  Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势，可以把输出文档写入ByteArrayOutputStram，完成后查看其大小，然后把该值放入Content-Length头，最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。 <br />  Content-Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain，但通常需要显式地指定为text/html。由于经常要设置Content-Type，因此HttpServletResponse提供了一个专用的方法setContentTyep。 <br />  Date 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 <br />  Expires 应该在什么时候认为文档已经过期，从而不再缓存它？ <br />  Last-Modified 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期，该请求将被视为一个条件GET，只有改动时间迟于指定时间的文档才会返回，否则返回一个304（Not Modified）状态。Last-Modified也可用setDateHeader方法来设置。 <br />  Location 表示客户应当到哪里去提取文档。Location通常不是直接设置的，而是通过HttpServletResponse的sendRedirect方法，该方法同时设置状态代码为302。 <br />  Refresh 表示浏览器应该在多少时间之后刷新文档，以秒计。除了刷新当前文档之外，你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。 <br />  注意这种功能通常是通过设置HTML页面HEAD区的＜META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path"＞实现，这是因为，自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是，对于Servlet来说，直接设置Refresh头更加方便。 <br />   <br />  注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”，而不是“每隔N秒刷新本页面或访问指定页面”。因此，连续刷新要求每次都发送一个Refresh头，而发送204状态代码则可以阻止浏览器继续刷新，不管是使用Refresh头还是＜META HTTP-EQUIV="Refresh" ...＞。 <br />   <br />  注意Refresh头不属于HTTP 1.1正式规范的一部分，而是一个扩展，但Netscape和IE都支持它。 <br />   <br />  Server 服务器名字。Servlet一般不设置这个值，而是由Web服务器自己设置。 <br />  Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader("Set-Cookie", ...)，而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。 <br />  WWW-Authenticate 客户应该在Authorization头中提供什么类型的授权信息？在包含401（Unauthorized）状态行的应答中这个头是必需的。例如，response.setHeader("WWW-Authenticate", "BASIC realm=＼"executives＼"")。 <br />  注意Servlet一般不进行这方面的处理，而是让Web服务器的专门机制来控制受密码保护页面的访问（例如.htaccess）。 <br />   <br />   <br />   <br />  　　 8.3 实例：内容改变时自动刷新页面 <br />   <br />  　　 下面这个Servlet用来计算大素数。因为计算非常大的数字（例如500位）可能要花不少时间，所以Servlet将立即返回已经找到的结果，同时在后台继续计算。后台计算使用一个优先级较低的线程以避免过多地影响Web服务器的性能。如果计算还没有完成，Servlet通过发送Refresh头指示浏览器在几秒之后继续请求新的内容。 <br />   <br />  　　 注意，本例除了说明HTTP应答头的用处之外，还显示了Servlet的另外两个很有价值的功能。首先，它表明Servlet能够处理多个并发的连接，每个都有自己的线程。Servlet维护了一份已有素数计算请求的Vector表，通过查找素数个数（素数列表的长度）和数字个数（每个素数的长度）将当前请求和已有请求相匹配，把所有这些请求同步到这个列表上。第二，本例证明，在Servlet中维持请求之间的状态信息是非常容易的。维持状态信息在传统的CGI编程中是一件很麻烦的事情。由于维持了状态信息，浏览器能够在刷新页面时访问到正在进行的计算过程，同时也使得Servlet能够保存一个有关最近请求结果的列表，当一个新的请求指定了和最近请求相同的参数时可以立即返回结果。 <br />   <br />  　　 PrimeNumbers.java <br />   <br />  　　 注意，该Servlet要用到前面给出的ServletUtilities.java。另外还要用到：PrimeList.java，用于在后台线程中创建一个素数的Vector；Primes.java，用于随机生成BigInteger类型的大数字，检查它们是否是素数。（此处略去PrimeList.java和Primes.java的代码。） <br />  package hall; <br />   <br />  import java.io.*; <br />  import javax.servlet.*; <br />  import javax.servlet.http.*; <br />  import java.util.*; <br />   <br />  public class PrimeNumbers extends HttpServlet { <br />   private static Vector primeListVector = new Vector(); <br />   private static int maxPrimeLists = 30; <br />   <br />   public void doGet(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   int numPrimes = ServletUtilities.getIntParameter(request, "numPrimes", 50); <br />   int numDigits = ServletUtilities.getIntParameter(request, "numDigits", 120); <br />   PrimeList primeList = findPrimeList(primeListVector, numPrimes, numDigits); <br />   if (primeList == null) { <br />   primeList = new PrimeList(numPrimes, numDigits, true); <br />   synchronized(primeListVector) { <br />   if (primeListVector.size() ＞= maxPrimeLists) <br />   primeListVector.removeElementAt(0); <br />   primeListVector.addElement(primeList); <br />   } <br />   } <br />   Vector currentPrimes = primeList.getPrimes(); <br />   int numCurrentPrimes = currentPrimes.size(); <br />   int numPrimesRemaining = (numPrimes - numCurrentPrimes); <br />   boolean isLastResult = (numPrimesRemaining == 0); <br />   if (!isLastResult) { <br />   response.setHeader("Refresh", "5"); <br />   } <br />   response.setContentType("text/html"); <br />   PrintWriter out = response.getWriter(); <br />   String title = "Some " + numDigits + "-Digit Prime Numbers"; <br />   out.println(ServletUtilities.headWithTitle(title) + <br />   "＜BODY BGCOLOR=＼"#FDF5E6＼"＞＼n" + <br />   "＜H2 ALIGN=CENTER＞" + title + "＜/H2＞＼n" + <br />   "＜H3＞Primes found with " + numDigits + <br />   " or more digits: " + numCurrentPrimes + ".＜/H3＞"); <br />   if (isLastResult) <br />   out.println("＜B＞Done searching.＜/B＞"); <br />   else <br />   out.println("＜B＞Still looking for " + numPrimesRemaining + <br />   " more＜BLINK＞...＜/BLINK＞＜/B＞"); <br />   out.println("＜OL＞"); <br />   for(int i=0; i＜numCurrentPrimes; i++) { <br />   out.println(" ＜LI＞" + currentPrimes.elementAt(i)); <br />   } <br />   out.println("＜/OL＞"); <br />   out.println("＜/BODY＞＜/HTML＞"); <br />   } <br />   <br />   public void doPost(HttpServletRequest request, <br />   HttpServletResponse response) <br />   throws ServletException, IOException { <br />   doGet(request, response); <br />   } <br />   <br />   // 检查是否存在同类型请求（已经完成，或者正在计算）。 <br />   // 如存在，则返回现有结果而不是启动新的后台线程。 <br />   private PrimeList findPrimeList(Vector primeListVector, <br />   int numPrimes, <br />   int numDigits) { <br />   synchronized(primeListVector) { <br />   for(int i=0; i＜primeListVector.size(); i++) { <br />   PrimeList primes = (PrimeList)primeListVector.elementAt(i); <br />   if ((numPrimes == primes.numPrimes()) &amp;&amp; <br />   (numDigits == primes.numDigits())) <br />   return(primes); <br />   } <br />   return(null); <br />   } <br />   } <br />  } <br /></div>
<img src ="http://www.blogjava.net/ltc603/aggbug/67168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-01 17:20 <a href="http://www.blogjava.net/ltc603/archive/2006/09/01/67168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Servlet API说明文档【转载】</title><link>http://www.blogjava.net/ltc603/archive/2006/09/01/67157.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 01 Sep 2006 09:06:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/01/67157.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67157.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/01/67157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67157.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67157.html</trackback:ping><description><![CDATA[
		<div>Java Servlet API说明文档（2.1a版）<br />译者前言：<br />近来在整理有关Servlet资料时发现，在网上竟然找不到一份中文的Java Servlet API的说明文档，而在有一本有关JSP的书后面附的Java Servlet API说明竟然不全，而这份文档的2.1a版在1998年的11月份就已定稿。所以我决定翻译一份中文的文档（其中一些与技术关系不大的部分已被略去），有兴趣的读者可以从http: //java.sun.com/products/servlet/2.1/servletspec-2.1.zip下载原文阅读。<br /><br /><br />Java Servlet API说明文档（2.1a版）<br />1998年11月<br /><br /><br />绪言<br />这是一份关于2.1版Java Servlet API的说明文档，作为对这本文档的补充，你可以到<a href="http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。"><font color="#000000">http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。</font></a><br /><br />谁需要读这份文档<br />这份文档描述了Java Servlet API的最新版本2.1版。所以，这本书对于Servlet的开发者及servlet引擎的开发者同样适用。<br /><br />Java Servlet API的组成<br />Java Servlet API由两个软件包组成：一个是对应HTTP的软件包，另一个是不对应HTTP的通用的软件包。这两个软件包的同时存在使得Java Servlet API能够适应将来的其他请求-响应的协议。<br />这份文档以及刚才提及的Javadoc格式的文档都描述了这两个软件包，Javadoc格式的文档还描述了你应该如何使用这两个软件包中的所有方法。<br /><br />有关规范<br />你也许对下面的这些Internet规范感兴趣，这些规范将直接影响到Servlet API的发展和执行。你可以从http: //info.internet.isi.edu/7c/in-notes/rfc/.cache 找到下面提到的所有这些RFC规范。<br />RFC 1738 统一资源定位器(URL) <br />RFC 1808 相关统一资源定位器 <br />RFC 1945 超文本传输协议--HTTP/1.0 <br />RFC 2045 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第一部分:Internet信息体格式 <br />RFC 2046 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第二部分:媒体类型 <br />RFC 2047 多用途网际邮件扩充协议(MIME)(多用途Internet邮件扩展)第三部分:信息标题扩展用于非ASCII文本 <br />RFC 2048 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第四部分: 注册步骤 <br />RFC 2049 多用途Internet邮件扩展(多用途网际邮件扩充协议(MIME))第五部分:一致性标准和例子 <br />RFC 2068 超文本传输协议 -- HTTP/1.1 <br />RFC 2069 一个扩展HTTP:摘要访问鉴定 <br />RFC 2109 HTTP状态管理机制 <br />RFC 2145 HTTP 版本号的使用和解释 <br />RFC 2324 超文本Coffee Pot控制协议 (HTCPCP/1.0)<br />万维网协会（<a href="http://www.w3.org）管理着这些协议的规范和执行。/"><font color="#000000">http://www.w3.org）管理着这些协议的规范和执行。/</font></a><br /><br /><br />有关Java Servlets<br />JavaTM servlets 是一个不受平台约束的Java小程序，它可以被用来通过多种方法扩充一个Web服务器的功能。你可以把Servlet理解成Server上的 applets，它被编译成字节码，这样它就可以被动态地载入并用效地扩展主机的处理能力。<br />Servlet与applets不同的地方是，它不运行在Web浏览器或其他图形化的用户界面上。Servlet通过servlet引擎运行在Web服务器中，以执行请求和响应，请求、响应的典型范例是HTTP协议。<br />一个客户端程序，可以是一个Web浏览器，或者是非其他的可以连接上Internet的程序，它会访问Web服务器并发出请求。这个请求被运行在Web服务器上的Servlet引擎处理，并返回响应到Servlet。Servlet通过HTTP将这个响应转发到客户端。<br />在功能上，Servlet与CGI、NSAPI有点类似，但是，与他们不同的是：Servlet具有平台无关性。<br /><br />Java Servlet概论<br />Servlet与其他普通的server扩展机制有以下进步：<br />因为它采用了不同的进程处理模式，所以它比CGI更快。<br />它使用了许多Web服务器都支持的标准的API。<br />它继承了Java的所有优势，包括易升级以及平台无关性。<br />它可以调用Java所提供的大量的API的功能模块。<br />这份文档说明了Java Servlet API的类和接口的方法。有关更多的信息，请参看下面的API说明。<br /><br />Servlet的生命周期<br />一个Java servlet具有一个生命周期，这个生命周期定义了一个Servlet如何被载入并被初始化，如何接收请求并作出对请求的响应，如何被从服务中清除。Servlet的生命周期被javax.servlet.Servlet这个接口所定义。<br />所有的Java Servlet都会直接地或间接地执行javax.servlet.Servlet接口，这样它才能在一个Servlet引擎中运行。 Servlet引擎是Web 服务器按照Java Servlet API定制的扩展。Servlet引擎提供网络服务，能够理解MIME请求，并提供一个运行Servlet的容器。<br />javax.servlet.Servlet接口定义了在Servlet的生命周期中特定时间以及特定顺序被调用的方法。<br /><br />Servlet的解析和载入<br />Servlet引擎解析并载入一个Servlet，这个过程可以发生在引擎启动时，需要一个Servlet去响应请求时，以及在此之间的任何时候。<br />Servlet引擎利用Java类载入工具载入一个Servlet，Servlet引擎可以从一个本地的文件系统、一个远程的文件系统以及网络载入Servlet。<br /><br />Servlet的初始化<br />Servlet引擎载入Servlet后，Servlet引擎必须对Servlet进行初始化，在这一过程中，你可以读取一些固定存储的数据、初始化JDBC的连接以及建立与其他资源的连接。<br />在初始化过程中，javax.servlet.Servlet接口的init()方法提供了Servlet的初始化信息。这样，Servlet可以对自己进行配置。<br />init()方法获得了一个Servlet配置对象（ServletConfig）。这个对象在Servlet引擎中执行，并允许Servlet通过它获处相关参数。这个对象使得Servlet能够访问ServletContext对象。<br /><br />Servlet处理请求<br />Servlet被初始化之后，它已经可以处理来自客户端的请求，每一个来自客户端的请求都被描述成一个ServletRequest对象，Servlet的响应被描述成一个ServletResponse对象。<br />当客户端发出请求时，Servlet引擎传递给Servlet一个ServletRequest对象和一个ServletResponse对象，这两个对象作为参数传递到service()方法中。<br />Servlet 也可以执行ServletRequest接口和ServletResponse接口。ServletRequest接口使得Servlet有权使用客户端发出的请求。Servlet可以通过ServletInputStream对象读取请求信息。<br />ServletResponse接口允许Servlet建立响应头和状态代码。通过执行这个接口，Servlet有权使用ServletOutputStream类来向客户端返回数据。<br /><br />多线程和映射<br />在多线程的环境下，Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口，如果是那样的话，Servlet只能同时处理一个请求。<br />Servlet依照Servlet引擎的映射来响应客户端的请求。一个映射对包括一个Servlet实例以及一个Servlet返回数据的URL，例如：HelloServlet with /hello/index.html。<br />然而，一个映射可能是由一个URL和许多Servlet实例组成，例如：一个分布式的Servlet引擎可能运行在不止一个的服务器中，这样的话，每一个服务器中都可能有一个Servlet实例，以平衡进程的载入。作为一个Servlet的开发者，你不能假定一个Servlet只有一个实例。<br /><br />Servlet的卸载<br />Servlet引擎并不必需保证一个Servlet在任何时候或在服务开启的任何时候都被载入。Servlet引擎可以自由的在任何时候使用或清除一个Servlet。因此，我们不能依赖一个类或实例来存储重要的信息。<br />当Servlet引擎决定卸载一个Servlet时（例如，如果这个引擎被关闭或者需要让资源），这个引擎必须允许Servlet释放正在使用的资源并存储有关资料。为了完成以上工作，引擎会调用Servlet的destroy()方法。 <br />在卸载一个Servlet之前，Servlet引擎必须等待所有的service()方法完成或超时结束（Servlet引擎会对超时作出定义）。当一个 Servlet被卸载时，引擎将不能给Servlet发送任何请求。引擎必须释放Servlet并完成无用存储单元的收集<br /><br />Servlet映射技术<br />作为一个Servlet引擎的开发者，你必须对于如何映射客户端的请求到Servlet有大量的适应性。这份说明文档不规定映射如何发生。但是，你必须能够自由地运用下面的所有技术：<br /><br />映射一个Servlet到一个URL<br />例如，你可以指定一个特殊的Servlet它仅被来自/feedback/index.html的请求调用。<br /><br />映射一个Servlet到以一个指定的目录名开始的所有URL<br />例如，你可以映射一个Servlet到/catalog，这样来自/catalog/、 /catalog/garden和 /catalog/housewares/index.html的请求都会被映射到这个Servlet。但是来自/catalogtwo 或 /catalog.html的请求没被映射。<br /><br />映射一个Servlet到所有以一个特定的字段结尾的所有URL<br />例如，你可以映射一个来自于所有以in.thtml结尾的请求到一个特定的Servlet。<br /><br />映射一个Servlet到一个特殊的URL /servlet/servlet_name。<br />例如，如果你建立了一个名叫listattributes的Servlet，你可以通过使用/servlet/listattributes来访问这个Servlet。<br /><br />通过类名调用Servlet<br />例如，如果Servlet引擎接收了来自/servlet/com.foo.servlet.MailServlet的请求，Servlet引擎会载入这个com.foo.servlet.MailServlet类，建立实例，并通过这个Servlet来处理请求。<br /><br />Servlet环境<br />ServletContext 接口定义了一个Servlet环境对象，这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用这个对象，Servlet可以记录事件、得到资源并得到来自Servlet引擎的类（例如RequestDispatcher对象）。一个Servlet只能运行在一个Servlet环境中，但是不同的Servlet可以在Servlet引擎上有不同的视图。<br />如果Servlet引擎支持虚拟主机，每个虚拟主机有一个Servlet环境。一个Servlet环境不能在虚拟主机之间共享。<br />Servlet引擎能够允许一个Servlet环境有它自己的活动范围。<br />例如，一个Servlet环境是属于bank应用的，它将被映射到/bank目录下。在这种情况下，一个对getContext方法的调用会返回/bank的Servlet环境。<br /><br />HTTP会话<br />HTTP是一个没有状态的协议。要建立一个有效的Web服务应用，你必须能够识别一个连续的来自远端的客户机的唯一的请求。随着时间的过去，发展了许多会话跟踪的技术，但是使用起来都比较麻烦。<br />Java Servlet API提供了一个简单的接口，通过这个接口，Servlet引擎可以有效地跟踪用户的会话。<br /><br />建立Session<br />因为HTTP是一个请求-响应协议，一个会话在客户机加入之前会被认为是一个新的会话。加入的意思是返回会话跟踪信息到服务器中，指出会话已被建立。在客户端加入之前，我们不能判断下一个客户端请求是目前会话的一部分。<br />在下面的情况下，Session会被认为是新的Session。<br />客户端的Session在此之前还不知道<br />客户端选择不加入Session，例如，如果客户端拒绝接收来自服务器的cookie<br />作为一个Servlet的开发者，你必须决定你的Web应用是否处理客户机不加入或不能加入Session。服务器会在Web服务器或Servlet规定的时间内维持一个Session对象。当Session终止时，服务器会释放Session对象以及所有绑定在Session上的对象。<br />绑定对象到Session中<br />如果有助于你处理应用的数据需求，你也许需要绑定对象到Session中，你可以通过一个唯一的名字绑定任何的对象到Session中，这时，你需要使用 HttpSession对象。任何绑定到Session上的对象都可以被处理同一会话的Servlet调用。<br />有些对象可能需要你知道什么时候会被放置到Session中或从Session中移开。你可以通过使用HttpSessionBindingListener接口获得这些信息。当你的应用存储数据到Session中，或从Session中清除数据，Servlet都会通过HttpSessionBindingListener检杳什么类被绑定或被取消绑定。这个接口的方法会通报被绑定或被取消绑定的对象。<br /><br />API对象的说明<br />这一部分包含了对Java Servlet API的全部类和接口的详细说明。这个说明与Javadoc API差不多，但是这份文档提供了更多的信息。<br />API包含了两个软件包，十二个接口和九个类。<br />软件包：javax.servlet <br />所包含的接口：RequestDispatcher；Servlet；ServletConfig；ServletContext；ServletRequest；ServletResponse；SingleThreadModel。<br />所包含的类：GenericServlet；ServletInputStream；ServletOutputStream；ServletException；UnavailableException。<br /><br />一、RequestDispatcher接口：<br />定义：<br />public interface RequestDispatcher;<br />定义一个对象，从客户端接收请求，然后将它发给服务器的可用资源（例如Servlet、CGI、HTML文件、JSP文件）。Servlet引擎创建request dispatcher对象，用于封装由一个特定的URL定义的服务器资源。<br />这个接口是专用于封装Servlet的，但是一个Servlet引擎可以创建request dispatcher对象用于封装任何类型的资源。<br />request dispatcher对象是由Servlet引擎建立的，而不是由Servlet开发者建立的。<br />方法<br />1、forward<br />public void forward(ServletRequest request, ServletReponse response)<br />throws ServletException, IOException;<br />被用来从这个Servlet向其它服务器资源传递请求。当一个Servlet对响应作了初步的处理，并要求其它的对象对此作出响应时，可以使用这个方法。<br />当request对象被传递到目标对象时，请求的URL路径和其他路径参数会被调整为反映目标对象的目标URL路径。<br />如果已经通过响应返回了一个ServletOutputStream对象或PrintWriter对象，这个方法将不能使用，否则，这个方法会抛出一个IllegalStateException。<br />2、include<br />public void include(ServletRequest request, ServletResponse response)<br />throws ServletException, IOException<br />用来包括发送给其他服务器资源的响应的内容。本质上来说，这个方法反映了服务器端的内容。<br />请求对象传到目标对象后会反映调用请求的请求URL路径和路径信息。这个响应对象只能调用这个Servlet的ServletOutputStream对象和PrintWriter对象。<br />一个调用include的Servlet不能设置头域，如果这个Servlet调用了必须设置头域的方法（例如cookie），这个方法将不能保证正常使用。作为一个Servlet开发者，你必须妥善地解决那些可能直接存储头域的方法。例如，即使你使用会话跟踪，为了保证session的正常工作，你必须在一个调用include的Servlet之外开始你的session<br /><br />二、Servlet接口。<br />定义<br />public interface Servlet<br />这个接口定义了一个Servlet：一个在Web服务器上继承了这个功能的Java类。<br />方法<br />1、init<br />public void init(ServletConfig config) throws ServletException;<br />Servlet引擎会在Servlet实例化之后，置入服务之前精确地调用init方法。在调用service方法之前，init方法必须成功退出。<br />如果init方法抛出一个ServletException，你不能将这个Servlet置入服务中，如果init方法在超时范围内没完成，我们也可以假定这个Servlet是不具备功能的，也不能置入服务中。<br />2、service<br />public void service(ServletRequest request, ServletResponse response)<br />throws ServletException, IOException;<br />Servlet引擎调用这个方法以允许Servlet响应请求。这个方法在Servlet未成功初始化之前无法调用。在Servlet被初始化之前，Servlet引擎能够封锁未决的请求。<br />在一个Servlet对象被卸载后，直到一个新的Servelt被初始化，Servlet引擎不能调用这个方法<br />3、destroy<br />public void destroy();<br />当一个Servlet被从服务中去除时，Servlet引擎调用这个方法。在这个对象的service方法所有线程未全部退出或者没被引擎认为发生超时操作时，destroy方法不能被调用。<br />4、getServletConfig<br />public ServletConfig getServletConfig();<br />返回一个ServletConfig对象，作为一个Servlet的开发者，你应该通过init方法存储ServletConfig对象以便这个方法能返回这个对象。为了你的便利，GenericServlet在执行这个接口时，已经这样做了。<br />5、getServletInfo<br />public String getServletInfo();<br />允许Servlet向主机的Servlet运行者提供有关它本身的信息。返回的字符串应该是纯文本格式而不应有任何标志（例如HTML，XML等）。<br /><br />三、ServletConfig接口<br />定义<br />public interface ServletConfig<br />这个接口定义了一个对象，通过这个对象，Servlet引擎配置一个Servlet并且允许Servlet获得一个有关它的ServletContext接口的说明。每一个ServletConfig对象对应着一个唯一的Servlet。<br />方法<br />1、getInitParameter<br />public String getInitParameter(String name);<br />这个方法返回一个包含Servlet指定的初始化参数的String。如果这个参数不存在，返加空值。<br />2、getInitParameterNames<br />public Enumeration getInitParameterNames();<br />这个方法返回一个列表String对象，该对象包括Servlet的所有初始化参数名。如果Servlet没有初始化参数，getInitParameterNames返回一个空的列表。<br />3、getServletContext<br />public ServletContext getServletContext();<br />返回这个Servlet的ServletContext对象。<br /><br />四、ServletContext接口<br />定义<br />public interface ServletContext<br />定义了一个Servlet的环境对象，通过这个对象，Servlet引擎向Servlet提供环境信息。<br />一个Servlet的环境对象必须至少与它所驻留的主机是一一对应的。在一个处理多个虚拟主机的Servlet引擎中（例如，使用了HTTP1.1的主机头域），每一个虚拟主机必须被视为一个单独的环境。此外，Servlet引擎还可以创建对应于一组Servlet的环境对象。<br />方法 <br />1、getAttribute<br />public Object getAttribute(String name); <br />返回Servlet环境对象中指定的属性对象。如果该属性对象不存在，返回空值。这个方法允许访问有关这个Servlet引擎的在该接口的其他方法中尚未提供的附加信息。<br />2、getAttributeNames<br />public Enumeration getAttributeNames();<br />返回一个Servlet环境对象中可用的属性名的列表。<br />3、getContext<br />public ServletContext getContext(String uripath);<br />返回一个Servlet环境对象，这个对象包括了特定URI路径的Servlets和资源，如果该路径不存在，则返回一个空值。URI路径格式是/dir/dir/filename.ext。<br />为了安全，如果通过这个方法访问一个受限制的Servlet的环境对象，会返回一个空值。<br />4、getMajorVersion<br />public int getMajorVersion();<br />返回Servlet引擎支持的Servlet API的主版本号。例如对于2.1版，这个方法会返回一个整数2。<br />5、getMinorVersion<br />public int getMinorVersion();<br />返回Servlet引擎支持的Servlet API的次版本号。例如对于2.1版，这个方法会返回一个整数2。<br />6、getMimeType<br />public String getMimeType(String file);<br />返回指定文件的MIME类型，如果这种MIME类型未知，则返回一个空值。MIME类型是由Servlet引擎的配置决定的。<br />7、getRealPath<br />public String getRealPath(String path);<br />一个符合URL路径格式的指定的虚拟路径的格式是：/dir/dir/filename.ext。用这个方法，可以返回与一个符合该格式的虚拟路径相对应的真实路径的String。这个真实路径的格式应该适合于运行这个Servlet引擎的计算机（包括其相应的路径解析器）。<br />不管是什么原因，如果这一从虚拟路径转换成实际路径的过程不能执行，该方法将会返回一个空值。<br />8、getResource<br />public URL getResource(String uripath);<br />返回一个URL对象，该对象反映位于给定的URL地址（格式：/dir/dir/filename.ext）的Servlet环境对象已知的资源。无论 URLStreamHandlers对于访问给定的环境是不是必须的，Servlet引擎都必须执行。如果给定的路径的Servlet环境没有已知的资源，该方法会返回一个空值。<br />这个方法和java.lang.Class的getResource方法不完全相同。 java.lang.Class的getResource方法通过装载类来寻找资源。而这个方法允许服务器产生环境变量给任何资源的任何Servlet，而不必依赖于装载类、特定区域等等。<br />9、getResourceAsStream<br />public InputStream getResourceAsStream(String uripath);<br />返回一个InputStream对象，该对象引用指定的URL的Servlet环境对象的内容。如果没找到Servlet环境变量，就会返回空值，URL路径应该具有这种格式：/dir/dir/filename.ext。<br />这个方法是一个通过getResource方法获得URL对象的方便的途径。请注意，当你使用这个方法时，meta-information（例如内容长度、内容类型）会丢失。<br />10、getRequestDispatcher<br />public RequestDispatcher getRequestDispatcher(String uripath);<br />如果这个指定的路径下能够找到活动的资源(例如一个Servlet，JSP页面，CGI等等)就返回一个特定URL的RequestDispatcher 对象，否则，就返回一个空值，Servlet引擎负责用一个request dispatcher对象封装目标路径。这个 request dispatcher对象可以用来完全请求的传送。<br />11、getServerInfo<br />public String getServerInfo();<br />返回一个String对象，该对象至少包括Servlet引擎的名字和版本号。<br />12、log<br />public void log(String msg);<br />public void log(String msg, Throwable t);<br />public void log(Exception exception, String msg); // 这种用法将被取消<br />写指定的信息到一个Servlet环境对象的log文件中。被写入的log文件由Servlet引擎指定，但是通常这是一个事件log。当这个方法被一个异常调用时，log中将包括堆栈跟踪。<br />13、setAttribute<br />public void setAttribute(String name, Object o);<br />给予Servlet环境对象中你所指定的对象一个名称。<br />14、removeAttribute<br />public void removeAttribute(String name);<br />从指定的Servlet环境对象中删除一个属性。<br />注：以下几个方法将被取消<br />15、getServlet<br />public Servlet getServlet(String name) throws ServletException;<br />最初用来返回一个指定名称的Servlet，如果没找到就返回一个空值。如果这个Servlet能够返回，这就意味着它已经被初始化，而且已经可以接受 service请求。这是一个危险的方法。当调用这个方法时，可能并不知道Servlet的状态，这就可能导致有关服务器状态的问题。而允许一个 Servlet访问其他Servlet的这个方法也同样的危险。<br />现在这个方法返回一个空值，为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。<br />16、getServletNames<br />public Enumeration getServletNames();<br />最初用来返回一个String对象的列表，该列表表示了在这个Servlet环境下所有已知的Servlet对象名。这个列表总是包含这个Servlet自身。<br />基于与上一个方法同样的理由，这也是一个危险的方法。<br />现在这个方法返回一个空的列表。为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。<br />17、getServlets<br />public Enumeration getServlets();<br />最初用来返回在这个Servelet环境下所有已知的Servlet对象的列表。这个列表总是包含这个Servlet自身。<br />基于与getServlet方法同样的理由，这也是一个危险的方法。<br />现在这个方法返回一个空的列表。为了保持和以前版本的兼容性，现在这个方法还没有被取消。在以后的API版本中，该方法将被取消。<br /><br />五、ServletRequest接口<br />定义<br />public interface ServletRequest<br />定义一个Servlet引擎产生的对象，通过这个对象，Servlet可以获得客户端请求的数据。这个对象通过读取请求体的数据提供包括参数的名称、值和属性以及输入流的所有数据。<br />方法<br />1、getAttribute<br />public Object getAttribute(String name);<br />返回请求中指定属性的值，如果这个属性不存在，就返回一个空值。这个方法允许访问一些不提供给这个接口中其他方法的请求信息以及其他Servlet放置在这个请求对象内的数据。<br />2、getAttributeNames<br />public Enumeration getAttributeNames();<br />返回包含在这个请求中的所有属性名的列表。<br />3、getCharacterEncoding<br />public String getCharacterEncoding();<br />返回请求中输入内容的字符编码类型，如果没有定义字符编码类型就返回空值。<br />4、getContentLength<br />public int getContentLength();<br />请求内容的长度，如果长度未知就返回-1。<br />5、getContentType<br />public String getContentType();<br />返回请求数据体的MIME类型，如果类型未知返回空值。<br />6、getInputStream<br />public ServletInputStream getInputStream() throws IOException;<br />返回一个输入流用来从请求体读取二进制数据。如果在此之前已经通过getReader方法获得了要读取的结果，这个方法会抛出一个IllegalStateException。<br />7、getParameter<br />public String getParameter(String name);<br />以一个String返回指定的参数的值，如果这个参数不存在返回空值。例如，在一个HTTP Servlet中，这个方法会返回一个指定的查询语句产生的参数的值或一个被提交的表单中的参数值。如果一个参数名对应着几个参数值，这个方法只能返回通过getParameterValues方法返回的数组中的第一个值。因此，如果这个参数有（或者可能有）多个值，你只能使用getParameterValues方法。<br />8、getParameterNames<br />public Enumeration getParameterNames();<br />返回所有参数名的String对象列表，如果没有输入参数，该方法返回一个空值。<br />9、getParameterValues<br />public String[] getParameterValues(String name);<br />通过一个String对象的数组返回指定参数的值，如果这个参数不存在，该方法返回一个空值。<br />10、getProtocol<br />public String getProtocol();<br />返回这个请求所用的协议，其形式是协议/主版本号.次版本号。例如对于一个HTTP1.0的请求，该方法返回HTTP/1.0。<br />11、getReader<br />public BufferedReader getReader() throws IOException;<br />这个方法返回一个buffered reader用来读取请求体的实体，其编码方式依照请求数据的编码方式。如果这个请求的输入流已经被getInputStream调用获得，这个方法会抛出一个IllegalStateException。<br />12、getRemoteAddr<br />public String getRemoteAddr();<br />返回发送请求者的IP地址。<br />13、getRemoteHost<br />public String getRemoteHost();<br />返回发送请求者的主机名称。如果引擎不能或者选择不解析主机名（为了改善性能），这个方法会直接返回IP地址。<br />14、getScheme<br />public String getScheme();<br />返回请求所使用的URL的模式。例如，对于一个HTTP请求，这个模式就是http。<br />15、getServerName<br />public String getServerName();<br />返回接收请求的服务器的主机名。<br />16、getServerPort<br />public int getServerPort();<br />返回接收请求的端口号。<br />17、setAttribute<br />public void setAttribute(String name, Object object);<br />这个方法在请求中添加一个属性，这个属性可以被其他可以访问这个请求对象的对象（例如一个嵌套的Servlet）使用。<br />注：以下方法将被取消<br />getRealPath<br />public String getRealPath(String path);<br />返回与虚拟路径相对应的真实路径，如果因为某种原因，这一过程不能进行，该方法将返回一个空值。<br />这个方法和ServletContext接口中的getRealPath方法重复。在2.1版中，ServletContext接口将阐明一个 Servlet所能用的所有的路径的映射。该方法执行的结果将会与ServletContext中getRealPath方法的结果完全一样。<br /><br />六、ServletResponse接口<br />定义<br />public interface ServletResponse<br />定义一个Servlet引擎产生的对象，通过这个对象，Servlet对客户端的请求作出响应。这个响应应该是一个MIME实体，可能是一个HTML页、图象数据或其他MIME的格式。<br />方法<br />1、getCharacterEncoding<br />public String getCharacterEncoding();<br />返回MIME实体的字符编码。这个字符编码可以是指定的类型，也可以是与请求头域所反映的客户端所能接受的字符编码最匹配的类型。在HTTP协议中，这个信息被通过Accept-Charset传送到Servlet引擎。<br />有关字符编码和MIME的更多信息请参看RFC 2047。<br />2、getOutputStream<br />public ServletOutputStream getOutputStream() throws IOException;<br />返回一个记录二进制的响应数据的输出流。<br />如果这个响应对象已经调用getWriter，将会抛出IllegalStateException。<br />3、getWriter<br />public PrintWriter getWriter throws IOException;<br />这个方法返回一个PringWriter对象用来记录格式化的响应实体。如果要反映使用的字符编码，必须修改响应的MIME类型。在调用这个方法之前，必须设定响应的content类型。<br />如果没有提供这样的编码类型，会抛出一个UnsupportedEncodingException，如果这个响应对象已调用getOutputStream，会抛出一个getOutputStream。<br />4、setContentLength<br />public void setContentLength(int length);<br />设置响应的内容的长度，这个方法会覆盖以前对内容长度的设定。<br />为了保证成功地设定响应头的内容长度，在响应被提交到输出流之前必须调用这个方法。<br />5、setContentType<br />public void setContentType(String type);<br />这个方法用来设定响应的content类型。这个类型以后可能会在另外的一些情况下被隐式地修改，这里所说的另外的情况可能当服务器发现有必要的情况下对MIME的字符设置。<br />为了保证成功地设定响应头的content类型，在响应被提交到输出流之前必须调用这个方法。<br /><br />七、SingleThreadModel接口<br />定义<br />public interface SingleThreadModel;<br />这是一个空接口，它指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定，那么在这个Servlet中的service方法中将不会有两个线程被同时执行。<br />Servlet可以通过维持一个各自独立的Servlet实例池，或者通过只让Servlet的service中只有一个线程的方法来实现这个保证。<br /><br />八、GenericServlet类<br />public abstract class GenericServlet implements Servlet,<br />ServletConfig, Serializable;<br />这个类的存在使得编写Servlet更加方便。它提供了一个简单的方案，这个方案用来执行有关Servlet生命周期的方法以及在初始化时对ServletConfig对象和ServletContext对象进行说明。<br />方法<br />1、destroy<br />public void destroy();<br />在这里destroy方法不做任何其他的工作。<br />2、getInitParameter<br />public String getInitParameter(String name);<br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。<br />3、getInitParameterNames<br />public Enumeration getInitParameterNames();<br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。<br />4、getServletConfig<br />public ServletConfig getServletConfig();<br />返回一个通过这个类的init方法产生的ServletConfig对象的说明。<br />5、getServletContext<br />public ServletContext getServletContext();<br />这是一个简便的途径，它将会调用ServletConfig对象的同名的方法。<br />6、getServletInfo<br />public String getServletInfo();<br />返回一个反映Servlet版本的String。<br />7、init<br />public void init() throws ServletException;<br />public void init(ServletConfig config) throws ServletException;<br />init(ServletConfig config)方法是一个对这个Servlet的生命周期进行初始化的简便的途径。<br />init()方法是用来让你对GenericServlet类进行扩充的，使用这个方法时，你不需要存储config对象，也不需要调用super.init(config)。<br />init(ServletConfig config)方法会存储config对象然后调用init()。如果你重载了这个方法，你必须调用super.init(config)，这样GenericServlet类的其他方法才能正常工作。<br />8、log<br />public void log(String msg);<br />public void log(String msg, Throwable cause);<br />通过Servlet content对象将Servlet的类名和给定的信息写入log文件中。<br />9、service<br />public abstract void service(ServletRequest request, ServletResponse<br />response) throws ServletException, IOException;<br />这是一个抽象的方法，当你扩展这个类时，为了执行网络请求，你必须执行它。<br /><br />九、ServletInputStream类<br />定义<br />public abstract class ServletInputStream extends InputStream<br />这个类定义了一个用来读取客户端的请求信息的输入流。这是一个Servlet引擎提供的抽象类。一个Servlet通过使用ServletRequest接口获得了对一个ServletInputStream对象的说明。<br />这个类的子类必须提供一个从InputStream接口读取有关信息的方法。<br />方法<br />1、readLine<br />public int readLine(byte[] b, int off, int len) throws IOException;<br />从输入流的指定的偏移量开始将指定长度的字节读入到指定的数组中。如果该行所有请求的内容都已被读取，这个读取的过程将结束。如果是遇到了新的一行，新的一行的首个字符也将被读入到数组中。<br /><br />十、ServletOutputStream类<br />定义<br />public abstract class ServletOutputStream extends OutputStream<br />这是一个由Servlet引擎使用的抽象类。Servlet通过使用ServletResponse接口的使用获得了对一个这种类型的对象的说明。利用这个输出流可以将数据返回到客户端。<br />这个类的子类必须提供一个向OutputStream接口写入有关信息的方法。<br />在这个接口中，当一个刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端，也就是说响应被提交了。请注意，关闭这种类型的对象时不一定要关闭隐含的socket流。<br />方法<br />1、print<br />public void print(String s) throws IOException;<br />public void print(boolean b) throws IOException;<br />public void print(char c) throws IOException;<br />public void print(int i) throws IOException;<br />public void print(long l) throws IOException;<br />public void print(float f) throws IOException;<br />public void print(double d) throws IOException;<br />输出变量到输出流中<br />2、println<br />public void println() throws IOException;<br />public void println(String s) throws IOException;<br />public void println(boolean b) throws IOException;<br />public void println(char c) throws IOException;<br />public void println(int i) throws IOException;<br />public void println(long l) throws IOException;<br />public void println(float f) throws IOException;<br />public void println(double d) throws IOException;<br />输出变量到输出流中，并增加一个回车换行符<br /><br />十一、ServletException类<br />定义<br />public class ServletException extends Exception<br />当Servlet遇到问题时抛出的一个异常。<br />构造函数<br />public ServletException();<br />public ServletException(String message);<br />public ServletException(String message, Throwable cause);<br />public ServletException(Throwable cause);<br />构造一个新的ServletException，如果这个构造函数包括一个Throwable参数，这个Throwable对象将被作为可能抛出这个异常的原因。<br />方法<br />1、getRootCause<br />public Throwable getRootCause();<br />如果配置了抛出这个异常的原因，这个方法将返回这个原因，否则返回一个空值。<br /><br />十二、UnavailableException类<br />定义<br />public class UnavailableException extends ServletException<br />不论一个Servlet是永久地还是临时地无效，都会抛出这个异常。Servlet会记录这个异常以及Servlet引擎所要采取的相应措施。<br />临时的无效是指Servlet在某一时间由于一个临时的问题而不能处理请求。例如，在另一个不同的应用层的服务（可能是数据库）无法使用。这个问题可能会自行纠正或者需要采取其他的纠正措施。<br />永久的无效是指除非管理员采取措施，这个Servlet将不能处理客户端的请求。例如，这个Servlet配置信息丢失或Servlet的状态被破坏。<br />Servlet 引擎可以安全地处理包括永久无效在内的这两种异常，但是对临时无效的正常处理可以使得Servlet引擎更健壮。特别的，这时对Servlet的请求只是被阻止（或者是被延期）一段时间，这显然要比在service自己重新启动前完全拒绝请求更为科学。<br />构造函数<br />public UnavailableException(Servlet servlet, String message);<br />public UnavailableException(int seconds, Servlet servlet, <br />String message);<br />构造一个包含指定的描述信息的新的异常。如果这个构造函数有一个关于秒数的参数，这将给出Servlet发生临时无效后，能够重新处理请求的估计时间。如果不包含这个参数，这意味着这个Servlet永久无效。<br />方法<br />1、getServlet<br />public Servlet getServlet();<br />返回报告无效的Servlet。这被Servlet引擎用来识别受到影响的Servlet。<br />2、getUnavailableSeconds<br />public int getUnavailableSeconds();<br />返回Servlet预期的无效时间，如果这个Servlet是永久无效，返回-1。<br />3、isPermanent<br />public boolean isPermanent();<br />如果这个Servlet永久无效，返回布尔值true，指示必须采取一些管理行动以使得这个Servlet可用。<br /><br />软件包：javax.servlet.http <br />所包含的接口：HttpServletRequest；HttpServletResponse；HttpSession；HttpSessionBindingListener；HttpSessionContext。<br />所包含的类：Cookie；HttpServlet；HttpSessionBindingEvent；HttpUtils。<br /><br />一、HttpServletRequest接口<br />定义\<br />public interface HttpServletRequest extends ServletRequest;<br />用来处理一个对Servlet的HTTP格式的请求信息。<br />方法<br />1、getAuthType<br />public String getAuthType();<br />返回这个请求的身份验证模式。<br />2、getCookies<br />public Cookie[] getCookies();<br />返回一个数组，该数组包含这个请求中当前的所有cookie。如果这个请求中没有cookie，返回一个空数组。<br />3、getDateHeader<br />public long getDateHeader(String name);<br />返回指定的请求头域的值，这个值被转换成一个反映自1970-1-1日（GMT）以来的精确到毫秒的长整数。<br />如果头域不能转换，抛出一个IllegalArgumentException。如果这个请求头域不存在，这个方法返回-1。<br />4、getHeader<br />public String getHeader(String name);<br />返回一个请求头域的值。（译者注：与上一个方法不同的是，该方法返回一个字符串）<br />如果这个请求头域不存在，这个方法返回-1。<br />5、getHeaderNames<br />public Enumeration getHeaderNames();<br />该方法返回一个String对象的列表，该列表反映请求的所有头域名。<br />有的引擎可能不允许通过这种方法访问头域，在这种情况下，这个方法返回一个空的列表。<br />6、getIntHeader<br />public int getIntHeader(String name);<br />返回指定的请求头域的值，这个值被转换成一个整数。<br />如果头域不能转换，抛出一个IllegalArgumentException。如果这个请求头域不存在，这个方法返回-1。<br />7、getMethod<br />public String getMethod();<br />返回这个请求使用的HTTP方法（例如：GET、POST、PUT）<br />8、getPathInfo<br />public String getPathInfo();<br />这个方法返回在这个请求的URL的Servlet路径之后的请求URL的额外的路径信息。如果这个请求URL包括一个查询字符串，在返回值内将不包括这个查询字符串。这个路径在返回之前必须经过URL解码。如果在这个请求的URL的Servlet路径之后没有路径信息。这个方法返回空值。<br />9、getPathTranslated<br />public String getPathTranslated();<br />这个方法获得这个请求的URL的Servlet路径之后的额外的路径信息，并将它转换成一个真实的路径。在进行转换前，这个请求的URL必须经过URL解码。如果在这个URL的Servlet路径之后没有附加路径信息。这个方法返回空值。<br />10、getQueryString<br />public String getQueryString();<br />返回这个请求URL所包含的查询字符串。一个查询字串符在一个URL中由一个“？”引出。如果没有查询字符串，这个方法返回空值。<br />11、getRemoteUser<br />public String getRemoteUser<br />返回作了请求的用户名，这个信息用来作HTTP用户论证。<br />如果在请求中没有用户名信息，这个方法返回空值。<br />12、getRequestedSessionId<br />public String getRequestedSessionId();<br />返回这个请求相应的session id。如果由于某种原因客户端提供的session id是无效的，这个session id将与在当前session中的session id不同，与此同时，将建立一个新的session。<br />如果这个请求没与一个session关联，这个方法返回空值。<br />13、getRequestURI<br />public String getRequestURI();<br />从HTTP请求的第一行返回请求的URL中定义被请求的资源的部分。如果有一个查询字符串存在，这个查询字符串将不包括在返回值当中。例如，一个请求通过 /catalog/books?id=1这样的URL路径访问，这个方法将返回/catalog/books。这个方法的返回值包括了Servlet路径和路径信息。<br />如果这个URL路径中的的一部分经过了URL编码，这个方法的返回值在返回之前必须经过解码。<br />14、getServletPath<br />public String getServletPath();<br />这个方法返回请求URL反映调用Servlet的部分。例如，一个Servlet被映射到/catalog/summer这个URL路径，而一个请求使用了/catalog/summer/casual这样的路径。所谓的反映调用Servlet的部分就是指/catalog/summer。<br />如果这个Servlet不是通过路径匹配来调用。这个方法将返回一个空值。<br />15、getSession<br />public HttpSession getSession();<br />public HttpSession getSession(boolean create);<br />返回与这个请求关联的当前的有效的session。如果调用这个方法时没带参数，那么在没有session与这个请求关联的情况下，将会新建一个session。如果调用这个方法时带入了一个布尔型的参数，只有当这个参数为真时，session才会被建立。<br />为了确保session能够被完全维持。Servlet开发者必须在响应被提交之前调用该方法。<br />如果带入的参数为假，而且没有session与这个请求关联。这个方法会返回空值。<br />16、isRequestedSessionIdValid<br />public boolean isRequestedSessionIdValid();<br />这个方法检查与此请求关联的session当前是不是有效。如果当前请求中使用的session无效，它将不能通过getSession方法返回。<br />17、isRequestedSessionIdFromCookie<br />public boolean isRequestedSessionIdFromCookie();<br />如果这个请求的session id是通过客户端的一个cookie提供的，该方法返回真，否则返回假。<br />18、isRequestedSessionIdFromURL<br />public boolean isRequestedSessionIdFromURL();<br />如果这个请求的session id是通过客户端的URL的一部分提供的，该方法返回真，否则返回假。请注意此方法与isRequestedSessionIdFromUrl在URL的拼写上不同。<br />以下方法将被取消\<br /><br />19、isRequestedSessionIdFromUrl<br />public boolean isRequestedSessionIdFromUrl();<br />该方法被isRequestedSessionIdFromURL代替。<br /><br />二、HttpServletResponse接口<br />定义\<br /><br />public interface HttpServletResponse extends ServletResponse<br />描述一个返回到客户端的HTTP回应。这个接口允许Servlet程序员利用HTTP协议规定的头信息。<br />成员变量<br />public static final int SC_CONTINUE = 100;<br />public static final int SC_SWITCHING_PROTOCOLS = 101;<br />public static final int SC_OK = 200;<br />public static final int SC_CREATED = 201;<br />public static final int SC_ACCEPTED = 202;<br />public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;<br />public static final int SC_NO_CONTENT = 204;<br />public static final int SC_RESET_CONTENT = 205;<br />public static final int SC_PARTIAL_CONTENT = 206;<br />public static final int SC_MULTIPLE_CHOICES = 300;<br />public static final int SC_MOVED_PERMANENTLY = 301;<br />public static final int SC_MOVED_TEMPORARILY = 302;<br />public static final int SC_SEE_OTHER = 303;<br />public static final int SC_NOT_MODIFIED = 304;<br />public static final int SC_USE_PROXY = 305;<br />public static final int SC_BAD_REQUEST = 400;<br />public static final int SC_UNAUTHORIZED = 401;<br />public static final int SC_PAYMENT_REQUIRED = 402;<br />public static final int SC_FORBIDDEN = 403;<br />public static final int SC_NOT_FOUND = 404;<br />public static final int SC_METHOD_NOT_ALLOWED = 405;<br />public static final int SC_NOT_ACCEPTABLE = 406;<br />public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;<br />public static final int SC_REQUEST_TIMEOUT = 408;<br />public static final int SC_CONFLICT = 409;<br />public static final int SC_GONE = 410;<br />public static final int SC_LENGTH_REQUIRED = 411;<br />public static final int SC_PRECONDITION_FAILED = 412;<br />public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;<br />public static final int SC_REQUEST_URI_TOO_LONG = 414;<br />public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;<br />public static final int SC_INTERNAL_SERVER_ERROR = 500;<br />public static final int SC_NOT_IMPLEMENTED = 501;<br />public static final int SC_BAD_GATEWAY = 502;<br />public static final int SC_SERVICE_UNAVAILABLE = 503;<br />public static final int SC_GATEWAY_TIMEOUT = 504;<br />public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;<br />以上HTTP产状态码是由HTTP/1.1定义的。<br />方法<br />1、addCookie<br />public void addCookie(Cookie cookie);<br />在响应中增加一个指定的cookie。可多次调用该方法以定义多个cookie。为了设置适当的头域，该方法应该在响应被提交之前调用。<br />2、containsHeader<br />public boolean containsHeader(String name);<br />检查是否设置了指定的响应头。<br />3、encodeRedirectURL<br />public String encodeRedirectURL(String url);<br />对sendRedirect方法使用的指定URL进行编码。如果不需要编码，就直接返回这个URL。之所以提供这个附加的编码方法，是因为在 redirect的情况下，决定是否对URL进行编码的规则和一般情况有所不同。所给的URL必须是一个绝对URL。相对URL不能被接收，会抛出一个 IllegalArgumentException。<br />所有提供给sendRedirect方法的URL都应通过这个方法运行，这样才能确保会话跟踪能够在所有浏览器中正常运行。<br />4、encodeURL<br />public String encodeURL(String url);<br />对包含session ID的URL进行编码。如果不需要编码，就直接返回这个URL。Servlet引擎必须提供URL编码方法，因为在有些情况下，我们将不得不重写URL，例如，在响应对应的请求中包含一个有效的session，但是这个session不能被非URL的（例如cookie）的手段来维持。<br />所有提供给Servlet的URL都应通过这个方法运行，这样才能确保会话跟踪能够在所有浏览器中正常运行。<br />5、sendError<br />public void sendError(int statusCode) throws IOException;<br />public void sendError(int statusCode, String message) throws<br />IOException;<br />用给定的状态码发给客户端一个错误响应。如果提供了一个message参数，这将作为响应体的一部分被发出，否则，服务器会返回错误代码所对应的标准信息。<br />调用这个方法后，响应立即被提交。在调用这个方法后，Servlet不会再有更多的输出。<br />6、sendRedirect<br />public void sendRedirect(String location) throws IOException;<br />使用给定的路径，给客户端发出一个临时转向的响应（SC_MOVED_TEMPORARILY）。给定的路径必须是绝对URL。相对URL将不能被接收，会抛出一个IllegalArgumentException。<br />这个方法必须在响应被提交之前调用。调用这个方法后，响应立即被提交。在调用这个方法后，Servlet不会再有更多的输出。<br />7、setDateHeader<br />public void setDateHeader(String name, long date);<br />用一个给定的名称和日期值设置响应头，这里的日期值应该是反映自1970-1-1日（GMT）以来的精确到毫秒的长整数。如果响应头已经被设置，新的值将覆盖当前的值。<br />8、setHeader<br />public void setHeader(String name, String value);<br />用一个给定的名称和域设置响应头。如果响应头已经被设置，新的值将覆盖当前的值。<br />9、setIntHeader<br />public void setIntHeader(String name, int value);<br />用一个给定的名称和整形值设置响应头。如果响应头已经被设置，新的值将覆盖当前的值。<br />10、setStatus<br />public void setStatus(int statusCode);<br />这个方法设置了响应的状态码，如果状态码已经被设置，新的值将覆盖当前的值。<br />以下的几个方法将被取消\<br />11、encodeRedirectUrl<br />public String encodeRedirectUrl(String url);<br />该方法被encodeRedirectURL取代。 <br />12、encodeUrl<br />public String encodeUrl(String url);<br />该方法被encodeURL取代。 <br />13、setStatus<br />public void setStatus(int statusCode, String message);<br />这个方法设置了响应的状态码，如果状态码已经被设置，新的值将覆盖当前的值。如果提供了一个message，它也将会被作为响应体的一部分被发送。<br /><br />三、HttpSession接口<br />定义\<br />public interface HttpSession<br />这个接口被Servlet引擎用来实现在HTTP客户端和HTTP会话两者的关联。这种关联可能在多外连接和请求中持续一段给定的时间。session用来在无状态的HTTP协议下越过多个请求页面来维持状态和识别用户。<br />一个session可以通过cookie或重写URL来维持。<br />方法<br />1、getCreationTime<br />public long getCreationTime();<br />返回建立session的时间，这个时间表示为自1970-1-1日（GMT）以来的毫秒数。 <br />2、getId<br />public String getId();<br />返回分配给这个session的标识符。一个HTTP session的标识符是一个由服务器来建立和维持的唯一的字符串。<br />3、getLastAccessedTime<br />public long getLastAccessedTime();<br />返回客户端最后一次发出与这个session有关的请求的时间，如果这个session是新建立的，返回-1。这个时间表示为自1970-1-1日（GMT）以来的毫秒数。 <br />4、getMaxInactiveInterval<br />public int getMaxInactiveInterval();<br />返加一个秒数，这个秒数表示客户端在不发出请求时，session被Servlet引擎维持的最长时间。在这个时间之后，Servlet引擎可能被Servlet引擎终止。如果这个session不会被终止，这个方法返回-1。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />5、getValue<br />public Object getValue(String name);<br />返回一个以给定的名字绑定到session上的对象。如果不存在这样的绑定，返回空值。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />6、getValueNames<br />public String[] getValueNames();<br />以一个数组返回绑定到session上的所有数据的名称。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />7、invalidate<br />public void invalidate();<br />这个方法会终止这个session。所有绑定在这个session上的数据都会被清除。并通过HttpSessionBindingListener接口的valueUnbound方法发出通告。<br />8、isNew<br />public boolean isNew();<br />返回一个布尔值以判断这个session是不是新的。如果一个session已经被服务器建立但是还没有收到相应的客户端的请求，这个session将被认为是新的。这意味着，这个客户端还没有加入会话或没有被会话公认。在他发出下一个请求时还不能返回适当的session认证信息。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />9、putValue<br />public void putValue(String name, Object value);<br />以给定的名字，绑定给定的对象到session中。已存在的同名的绑定会被重置。这时会调用HttpSessionBindingListener接口的valueBound方法。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />10、removeValue<br />public void removeValue(String name);<br />取消给定名字的对象在session上的绑定。如果未找到给定名字的绑定的对象，这个方法什么出不做。 这时会调用HttpSessionBindingListener接口的valueUnbound方法。<br />当session无效后再调用这个方法会抛出一个IllegalStateException。<br />11、setMaxInactiveInterval<br />public int setMaxInactiveInterval(int interval);<br />设置一个秒数，这个秒数表示客户端在不发出请求时，session被Servlet引擎维持的最长时间。<br />以下这个方法将被取消\<br />12、getSessionContext<br />public HttpSessionContext getSessionContext();<br />返回session在其中得以保持的环境变量。这个方法和其他所有HttpSessionContext的方法一样被取消了。<br /><br />四、HttpSessionBindingListener接口<br />定义\<br />public interface HttpSessionBindingListener<br />这个对象被加入到HTTP的session中，执行这个接口会通告有没有什么对象被绑定到这个HTTP session中或被从这个HTTP session中取消绑定。<br />方法<br />1、valueBound<br />public void valueBound(HttpSessionBindingEvent event);<br />当一个对象被绑定到session中，调用此方法。HttpSession.putValue方法被调用时，Servlet引擎应该调用此方法。<br />2、valueUnbound<br />public void valueUnbound(HttpSessionBindingEvent event);<br />当一个对象被从session中取消绑定，调用此方法。HttpSession.removeValue方法被调用时，Servlet引擎应该调用此方法。<br /><br />五、HttpSessionContext接口<br />定义\<br />此接口将被取消\<br />public interface HttpSessionContext<br />这个对象是与一组HTTP session关联的单一的实体。<br />这个接口由于安全的原因被取消，它出现在目前的版本中仅仅是为了兼容性的原因。这个接口的方法将模拟以前的版本的定义返回相应的值。<br />方法<br />1、getSession<br />public HttpSession getSession(String sessionId);<br />当初用来返回与这个session id相关的session。现在返回空值。<br />2、getIds<br />public Enumeration getIds();<br />当初用来返回这个环境下所有session id的列表。现在返回空的列表。<br /><br />六、Cookie类\<br />定义\<br />public class Cookie implements Cloneable<br />这个类描述了一个cookie，有关cookie的定义你可以参照Netscape Communications Corporation的说明，也可以参照RFC 2109。<br />构造函数<br />public Cookie(String name, String value);<br />用一个name-value对定义一个cookie。这个name必须能被HTTP/1.1所接受。<br />以字符$开头的name被RFC 2109保留。<br />给定的name如果不能被HTTP/1.1所接受，该方法抛出一个IllegalArgumentException。<br />方法<br />1、getComment<br />public String getComment();<br />返回描述这个cookie目的的说明，如果未定义这个说明，返回空值。<br />2、getDomain<br />public String getDomain();<br />返回这个cookie可以出现的区域，如果未定义区域，返回空值。<br />3、getMaxAge<br />public int getMaxAge();<br />这个方法返回这个cookie指定的最长存活时期。如果未定义这个最长存活时期，该方法返回-1。<br />4、getName<br />public String getName();<br />该方法返回cookie名。<br />5、getPath<br />public String getPath();<br />返回这个cookie有效的所有URL路径的前缀，如果未定义，返回空值。<br />6、getSecure<br />public boolean getSecure();<br />如果这个cookie只通过安全通道传输返回真，否则返回假。<br />7、getValue<br />public String getValue();<br />该方法返回cookie的值。<br />8、getVersion<br />public int getVersion();<br />返回cookie的版本。版本1由RFC 2109解释。版本0由Netscape Communications Corporation的说明解释。新构造的cookie默认使用版本0。<br />9、setComment<br />public void setComment(String purpose);<br />如果一个用户将这个cookie提交给另一个用户，必须通过这个说明描述这个cookie的目的。版本0不支持这个属性。<br />10、setDomain<br />public void setDomain(String pattern);<br />这个方法设置cookie的有效域的属性。这个属性指定了cookie可以出现的区域。一个有效域以一个点开头（.foo.com），这意味着在指定的域名解析系统的区域中（可能是<a href="http://www.foo.com但不是a.b.foo.com）的主机可以看到这个cookie。默认情况是，cookie只能返回保存它的主机。/"><font color="#000000">http://www.foo.com但不是a.b.foo.com...乇４嫠闹骰?/a&gt;<br />11、setMaxAge<br />public void setMaxAge(int expiry);<br />这个方法设定这个cookie的最长存活时期。在该存活时期之后，cookie会被终目。负数表示这个cookie不会生效，0将从客户端删除这个cookie。<br />12、setPath<br />public void setPath(String uri);<br />这个方法设置cookie的路径属性。客户端只能向以这个给定的路径String开头的路径返回cookie。<br />13、setSecure<br />public void setSecure(boolean flag);<br />指出这个cookie只能通过安全通道（例如HTTPS）发送。只有当产生这个cookie的服务器使用安全协议发送这个cookie值时才能这样设置。<br />14、setValue<br />public void setValue(String newValue);<br />设置这个cookie的值，对于二进制数据采用BASE64编码。<br />版本0不能使用空格、{}、()、=、，、“”、/、?、@、：以及；。<br />15、setVersion<br />public void setVersion(int v);<br />设置cookie的版本号<br /><br />七、HttpServlet类\<br />定义\<br />public class HttpServlet extends GenericServlet implements <br />Serializable<br />这是一个抽象类，用来简化HTTP Servlet写作的过程。它是GenericServlet类的扩充，提供了一个处理HTTP协议的框架。<br />在这个类中的service方法支持例如GET、POST这样的标准的HTTP方法。这一支持过程是通过分配他们到适当的方法（例如doGet、doPost）来实现的。<br />方法<br />1、doDelete<br />protected void doDelete(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP DELETE操作。这个操作允许客户端请求从服务器上删除URL。这一操作可能有负面影响，对此用户就负起责任。<br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理DELETE请求时，你必须重载这一方法。<br />2、doGet<br />protected void doGet(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP GET操作。这个操作允许客户端简单地从一个HTTP服务器“获得”资源。对这个方法的重载将自动地支持HEAD方法。<br />GET操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。<br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。<br />3、doHead<br />protected void doHead(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP HEAD操作。默认的情况是，这个操作会按照一个无条件的GET方法来执行，该操作不向客户端返回任何数据，而仅仅是返回包含内容长度的头信息。<br />与GET操作一样，这个操作应该是安全而且没有负面影响的。这个操作也应该可以安全地重复。<br />这个方法的默认执行结果是自动处理HTTP HEAD操作，这个方法不需要被一个子类执行。 <br />4、doOptions<br />protected void doOptions(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP OPTION操作。这个操作自动地决定支持哪一种HTTP方法。例如，一个Servlet写了一个HttpServlet的子类并重载了doGet方法，doOption会返回下面的头：<br />Allow: GET,HEAD,TRACE,OPTIONS<br />你一般不需要重载这个方法。<br />5、doPost<br />protected void doPost(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP POST操作。这个操作包含请求体的数据，Servlet应该按照他行事。<br />这个操作可能有负面影响。例如更新存储的数据或在线购物。<br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理POST操作时，你必须在HttpServlet的子类中重载这一方法。<br />6、doPut<br />protected void doPut(HttpServletRequest request, <br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP PUT操作。这个操作类似于通过FTP发送文件。<br />这个操作可能有负面影响。例如更新存储的数据或在线购物。<br />这一方法的默认执行结果是返回一个HTTP BAD_REQUEST错误。当你要处理PUT操作时，你必须在HttpServlet的子类中重载这一方法。<br />7、doTrace<br />protected void doTrace(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />被这个类的service方法调用，用来处理一个HTTP TRACE操作。这个操作的默认执行结果是产生一个响应，这个响应包含一个反映trace请求中发送的所有头域的信息。<br />当你开发Servlet时，在多数情况下你需要重载这个方法。<br />8、getLastModified<br />protected long getLastModified(HttpServletRequest request);<br />返回这个请求实体的最后修改时间。为了支持GET操作，你必须重载这一方法，以精确地反映最后修改的时间。这将有助于浏览器和代理服务器减少装载服务器和网络资源，从而更加有效地工作。返回的数值是自1970-1-1日（GMT）以来的毫秒数。 <br />默认的执行结果是返回一个负数，这标志着最后修改时间未知，它也不能被一个有条件的GET操作使用。<br />9、service<br />protected void service(HttpServletRequest request,<br />HttpServletResponse response) throws ServletException,<br />IOException;<br />public void service(ServletRequest request, ServletResponse response)<br />throws ServletException, IOException;<br />这是一个Servlet的HTTP-specific方案，它分配请求到这个类的支持这个请求的其他方法。<br />当你开发Servlet时，在多数情况下你不必重载这个方法。<br /><br />八、HttpSessionBindingEvent类\<br />定义\<br />public class HttpSessionBindingEvent extends EventObject<br />这个事件是在监听到HttpSession发生绑定和取消绑定的情况时连通HttpSessionBindingListener的。这可能是一个session被终止或被认定无效的结果。<br />事件源是HttpSession.putValue或HttpSession.removeValue。<br />构造函数<br />public HttpSessionBindingEvent(HttpSession session, String name);<br />通过引起这个事件的Session和发生绑定或取消绑定的对象名构造一个新的HttpSessionBindingEvent。<br />方法<br />1、getName<br />public String getName();<br />返回发生绑定和取消绑定的对象的名字。<br />2、getSession<br />public HttpSession getSession();<br />返回发生绑定和取消绑定的session的名字。<br /><br />九、HttpUtils类\<br />定义\<br />public class HttpUtils<br />收集HTTP Servlet使用的静态的有效的方法。<br />方法<br />1、getRequestURL<br />public static StringBuffer getRequestURL(HttpServletRequest<br />request);<br />在服务器上重建客户端用来建立请求的URL。这个方法反映了不同的协议（例如http和https）和端口，但不包含查询字符串。<br />这个方法返回一个StringBuffer而不是一个String，这样URL可以被Servlet开发者有效地修改。<br />2、parsePostData<br />public static Hashtable parsePostData(int len, <br />ServletInputstream in);<br />解析一个包含MIME类型application/x-www-form-urlencoded的数据的流，并创建一个具有关键值-数据对的 hash table。这里的关键值是字符串，数据是该字符串所对应的值的列表。一个关键值可以在POST的数据中出现一次或多次。这个关键值每出现一次，它的相应的值就被加入到hash table中的字符串所对应的值的列表中。<br />从POST数据读出的数据将经过URL解码，+将被转换为空格以十六进制传送的数据（例如%xx）将被转换成字符。<br />当POST数据无效时，该方法抛出一个IllegalArgumentException。<br />3、parseQueryString<br />public static Hashtable parseQueryString(String s);<br />解析一个查询字符串，并创建一个具有关键值-数据对的hash table。这里的数据是该字符串所对应的值的列表。一个关键值可以出现一次或多次。这个关键值每出现一次，它的相应的值就被加入到hash table中的字符串所对应的值的列表中。<br />从查询字符串读出的数据将经过URL解码，+将被转换为空格以十六进制传送的数据（例如%xx）将被转换成字符。<br />当查询字符串无效时，该方法抛出一个IllegalArgumentException。<br /><br />术语表<br />bytecode <br />字节码：由Java编译器和Java解释程序生成的机器代码。<br />cookie <br />由Web服务器建立的数据，该数据存储在用户的计算机上，提供了一个Web站点跟踪用户的参数并存储在用户自己硬盘上的方法。<br />HTTP <br />超文本传输协议。一个请求响应协议用来连接WWW服务器向客户端浏览器传输HTML页面。<br />输入流对象<br />一个对象，由ServletInputStream类定义，被Servlet用来从客户端读取请求。<br />映射<br />由Servlet实例和Servlet返回数据的URL组成的一对，例如，HelloServlet和/hello/index.html。<br />输出流对象<br />一个对象，由ServletOutputStream class类定义，被Servlet用来向客户端返回数据。<br />request dispatcher object <br />由RequestDispatcher接口定义的一个对象，用来从客户端接收请求，并将其发送到Web服务器上可用的其他资源（例如Servlet、CGI、HTML文件或JSP文件）。<br />sandboxed servlet <br />在一个安全性约束下运行的Servlet。<br />servlet <br />一个小的，具有平台无关性的，没有图形用户界面的Java程序。它可以在许多方面扩充Web服务的功能。<br />servlet configuration object <br />ServletConfig接口定义的一个对象，用来配置一个Servlet。<br />servlet context object <br />ServletContext接口定义的一个对象。给予Servlet有关Servlet引擎的信息。<br />servlet引擎<br />由Web服务器提供商制作的一个环境，可以允许Servlet在具体的Web服务器上运行。<br />servlet请求对象 <br />由ServletRequest接口定义的一个对象，允许Servlet获得用关客户端请求的数据。<br />servlet response object <br />由ServletResponse接口定义的一个对象，允许Servlet作出响应。<br />servlet runner <br />Java Servlet Developer’s Kit (JSDK)中的sun.servlet.http.HttpServer过程，它使得Servlet得以运行。<br />会话跟踪 <br />在一个Web应用程序中，识别一个从同一个客户端发出的连续的唯一的请求的能力。<br />SSL <br />加密套接字协议层。一个安全协议，用来在Iternet上的客户端浏览器和服务器交换密钥和加密数据。<br />URI <br />统一资源标识。定义一个Internet地址，它是一个URL的超集。<br />URL <br />统一资源路径。这个地址定义了到达一个WWW上的文件的路线，通常由协议前缀、域名、目录名和文件名组成。</font></a></div>
<img src ="http://www.blogjava.net/ltc603/aggbug/67157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-01 17:06 <a href="http://www.blogjava.net/ltc603/archive/2006/09/01/67157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>servlet 相关的Listener应用 作者： colin_ch （抄自javaeye）</title><link>http://www.blogjava.net/ltc603/archive/2006/09/01/67152.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 01 Sep 2006 08:55:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/01/67152.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67152.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/01/67152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67152.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67152.html</trackback:ping><description><![CDATA[
		<div>
				<span>从作用域范围来说,Servlet的作用域有ServletContext,HttpSession,ServletRequest. <br /><br />Context范围: <br /><br />ServletContextListener: <br />对一个应用进行全局监听.随应用启动而启动,随应用消失而消失主要有两个方法: <br />contextDestroyed(ServletContextEvent event) <br />在应用关闭的时候调用 <br />contextInitialized(ServletContextEvent event) <br />在应用启动的时候调用 <br /><br />这个监听器主要用于一些随着应用启动而要完成的工作,也就是很多人说的我想在容器 <br />启动的时候干.......... <br />一般来说对"全局变量"初始化,如 <br />public void contextInitialized(ServletContextEvent event){ <br />ServletContex sc = event.getServletContext(); <br />sc.setAttribute(name,value); <br />} <br />以后你就可以在任何servlet中getServletContext().getAttribute(name); <br />我最喜欢用它来做守护性工作,就是在contextInitialized(ServletContextEvent event) <br />方法中实现一个Timer,然后就让应用在每次启动的时候让这个Timer工作: <br />public void contextInitialized(ServletContextEvent event){ <br />timer = new Timer(); <br />timer.schedule(new TimerTask(){ <br />public void run(){ <br />//do any things <br />} <br />},0,时间间隔); <br />} <br /><br />有人说Timer只能规定从现在开始的多长时间后,每隔多久做一次事或在什么时间做 <br />一次事,那我想在每月1号或每天12点做一项工作如何做呢? <br />你只要设一个间隔,然后每次判断一下当时是不是那个时间段就行了啊,比如每月一号做,那你 <br />时间间隔设为天,即24小时一个循环,然后在run方法中判断当时日期new Date().getDate()==1 <br />就行了啊.如果是每天的12点,那你时间间隔设为小时,然后在run中判断new Date().getHour() <br />==12,再做某事就行了. <br /><br />ServletContextAttributeListener: <br /><br />这个监听器主要监听ServletContex对象在setAttribute()和removeAttribute()的事件,注意 <br />也就是一个"全局变量"在被Add(第一次set),replace(对已有的变量重新赋值)和remove的时候. <br />分别调用下面三个方法: <br />public void attributeAdded(ServletContextAttributeEvent scab)这个方法不仅可以知道 <br />哪些全局变量被加进来,而且可获取容器在启动时自动设置了哪些context变量: <br /><br />public void attributeAdded(ServletContextAttributeEvent scab){ <br />System.out.println(scab.getName()); <br />} <br />public void attributeRemoved(ServletContextAttributeEvent scab) <br /><br />public void attributeReplaced(ServletContextAttributeEvent scab) <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />Session范围: <br />HttpSessionListener: <br />这个监听器主要监听一个Session对象被生成和销毁时发生的事件.对应有两个方法: <br />public void sessionCreated(HttpSessionEvent se) <br /><br />public void sessionDestroyed(HttpSessionEvent se) <br /><br />一般来说,一个session对象被create时,可以说明有一个新客端进入.可以用来粗略统计在线人 <br />数,注意这不是精确的,因为这个客户端可能立即就关闭了,但sessionDestroyed方法却会按一定 <br />的策略很久以后才会发生. <br /><br />HttpSessionAttributeListener: <br />和ServletContextAttributeListener一样,它监听一个session对象的Attribut被Add(一个特定 <br />名称的Attribute每一次被设置),replace(已有名称的Attribute的值被重设)和remove时的事件. <br />对就的有三个方法. <br />public void attributeAdded(HttpSessionBindingEvent se) <br /><br />public void attributeRemoved(HttpSessionBindingEvent se) <br /><br />public void attributeReplaced(HttpSessionBindingEvent se) <br /><br />上面的几个监听器的方法,都是在监听应用逻辑中servlet逻辑中发生了什么事,一般的来说. <br />我们只要完成逻辑功能,比如session.setAttribute("aaa","111");我只要把一个名为aaa的变量 <br />放在session中以便以后我能获取它,我并不关心当session.setAttribute("aaa","111");发生时 <br />我还要干什么.(当然有些时候要利用的),但对于下面这个监听器,你应该好好发解一下: <br /><br />HttpSessionBindingListener: <br />上面的监听器都是作为一个独立的Listener在容器中控制事件的.而HttpSessionBindingListener <br />对在一对象中监听该对象的状态,实现了该接口的对象如果被作为value被add到一个session中或从 <br />session中remove,它就会知道自己已经作为一个session对象或已经从session删除,这对于一些非 <br />纯JAVA对象,生命周期长于session的对象,以及其它需要释放资源或改变状态的对象非常重要. <br />比如: <br />session.setAttribute("abcd","1111"); <br />以后session.removeAttribute("abcd");因为abcd是一个字符中,你从session中remove后,它就会 <br />自动被垃圾回收器回收,而如果是一个connection:(只是举例,你千万不要加connection往session <br />中加入) <br />session.setAttribute("abcd",conn); <br />以后session.removeAttribute("abcd");这时这个conn被从session中remove了,你已经无法获取它 <br />的句柄,所以你根本没法关闭它.而在没有remove之前你根本不知道什么时候要被remove,你又无法 <br />close(),那么这个connection对象就死了.另外还有一些对象可以在被加入一个session时要锁定 <br />还要被remove时要解锁,应因你在程序中无法判断什么时候被remove(),add还好操作,我可以先加锁 <br />再add,但remove就后你就找不到它的句柄了,根本没法解锁,所以这些操作只能在对象自身中实现. <br />也就是在对象被add时或remove时通知对象自己回调相应的方法: <br /><br />MyConn extends Connection implements HttpSessionBindingListener{ <br />public void valueBound(HttpSessionBindingEvent se){ <br />this.initXXX(); <br />} <br />public void valueUnbound(HttpSessionBindingEvent se){ <br /><br />this.close(); <br />} <br />} <br /><br />session.setAttribute("aaa",new MyConn()); <br />这时如果调用session.removeAttribute("aaa"),则触发valueUnbound方法,就会自动关闭自己. <br />而其它的需要改变状态的对象了是一样.</span>
		</div>
<img src ="http://www.blogjava.net/ltc603/aggbug/67152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-01 16:55 <a href="http://www.blogjava.net/ltc603/archive/2006/09/01/67152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP学习经验总结【转载】</title><link>http://www.blogjava.net/ltc603/archive/2006/09/01/67151.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 01 Sep 2006 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/ltc603/archive/2006/09/01/67151.html</guid><wfw:comment>http://www.blogjava.net/ltc603/comments/67151.html</wfw:comment><comments>http://www.blogjava.net/ltc603/archive/2006/09/01/67151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ltc603/comments/commentRss/67151.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ltc603/services/trackbacks/67151.html</trackback:ping><description><![CDATA[
		<div id="msgcns!6ACF9041B1D020E2!113">一、JSP工作原理 <br /><br />在一个JSP文件第一次被请求时，JSP引擎把该JSP文件转换成为一个servlet。而这个引擎本身也是一个servlet，在JSWDK或WEBLOGIC中，它就是JspServlet。 JSP引擎先把该JSP文件转换成一个Java源文件，在转换时如果发现jsp文件有任何语法错误，转换过程将中断，并向服务端和客户端输出出错信息；如果转换成功， JSP引擎用javac把该Java源文件编译成相应的class文件。然后创建一个该SERVLET的实例，该SERVLET的jspInit()方法被执行，jspInit()方法在servlet的生命周期中只被执行一次。然后jspService()方法被调用来处理客户端的请求。对每一个请求，JSP引擎创建一个新的线程来处理该请求。如果有多个客户端同时请求该JSP文件，则JSP引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间.但应该注意多线程的编程限制，由于该servlet始终驻于内存，所以响应是非常快的。 如果.jsp文件被修改了，服务器将根据设置决定是否对该文件重新编译，如果需要重新编译，则将编译结果取代内存中的servlet，并继续上述处理过程。 虽然JSP效率很高，但在第一次调用时由于需要转换和编译而有一些轻微的延迟。 此外，如果在任何时候如果由于系统资源不足的原因，JSP引擎将以某种不确定的方式将servlet从内存中移去。当这种情况发生时jspDestroy()方法首先被调用, 然后servlet实例便被标记加入"垃圾收集"处理。 jspInit()及jspDestory()格式如下：可在jspInit()中进行一些初始化工作,如建立与数据库的连接，或建立网络连接，从配置文件中取一些参数等，在jspDestory()中释放相应的资源。  <br /><br />&lt;%! <br />public void jspInit() <br />{ <br />       System.out.println("jspinit");  <br />} <br />  <br />%&gt; <br />  <br />&lt;%! <br />public void jspDestory() <br />{ <br />       System.out.println("jspDestory");  <br />} <br />%&gt; <br /><br />二、服务端的输出缓冲区 <br /><br />缺省情况下:服务端要输出到客户端的内容,不直接写到客户端,而是先写到一个输出缓冲区中.只有在下面三中情况下，才会把该缓冲区的内容输出到客户端上： <br /><br /><br />该JSP网页已完成信息的输出  <br />输出缓冲区已满  <br />JSP中调用了out.flush()或response.flushbuffer()  <br />输出缓冲区的大小可以用:或response.setBufferSize()设置,如下：  <br />设置输出缓冲区的大小为1KB。或response.setBufferSize(1);  <br />设置输出缓冲区的大小为0，即不缓冲。或response.setBufferSize(0);  <br />用response.getBufferSize()或out.getBufferSize()可取的输出缓冲区的大小,单位为字节. 用response.isCommitted()可检查看服务端是否已将数据输出到客户端. 如果返回值是TRUE则已将数据输出到客户端,是FALSE则还没有.  <br /><br />三、服务端输出重定向 <br /><br />有以下3种方法可以做到输出重定向:  <br /><br />RESPONSE.SETREDERECT("URL") 该方法通过修改HTTP协议的HEADER部分,对浏览器下达重定向指令的,使浏览器显示重定向网页的内容. response.sendRedirect("http://localhost:7001/index.html");  <br />下面的方法也能改变HTTP HEADER属性，它的原理和 1 是一样的.  <br />&lt;%  <br />response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);  <br />String newLocn="/index.html";  <br />response.setHeader("Location",newLocn);  <br />% &gt;  <br />采用&lt;JSP:FORWORD&gt; 该方法是利用服务器端先将数据输出到缓冲区的机制,在把缓冲区的内容发送到客户端之前,原来的不发送,改为发送该页面的内容,如果在&lt;JSP:FORWORD&gt;之前有很多输出,前面的输出已使缓冲区满,将自动输出到客户端,那么该语句将不起作用,这一点应该特别注意. 如下面的例子中(1)会输出index.html的内容，2 不会输出index.html的内容，而是输出out.println("@@@@@@@@@@@@@@@@@"); 中的内容,并且在服务端会抛出:java.lang.IllegalStateException: Response already committed 异常，但客户端没有任何错误输出。  <br />(1) <br />&lt;%@page buffer="1kb"%&gt; <br />  <br />&lt;% <br />long i=0; <br />  <br />for(i=0;i&lt;10;i++) <br />{ <br />       out.println("@@@@@@@@@@@@@@@@@"); <br />} <br />%&gt; <br />  <br />&lt;jsp:forward page="./index.html" /&gt; <br />  <br />  <br />(2) <br />&lt;%@page buffer="1kb"%&gt; <br />  <br />&lt;% <br />long i=0; <br />  <br />for(i=0;i&lt;600;i++) <br />{                  <br />       out.println("@@@@@@@@@@@@@@@@@"); <br />} <br />%&gt; <br />  <br /><br />说明： <br />1. 方法(1),(2)可以使用变量表示重定向的地址;方法(3)不能使用变量表示重定向的地址。 <br />String add="./index.html";  <br />&lt;jsp:forward page= add /&gt;  <br />无法重定向到index.html中去  <br /><br />String add=http://localhost:7001/index.html  <br />response.sendRedirect(add);  <br />可以重定向到http://localhost:7001/index.html中去。  <br /><br />2. 采用方法(1),(2)request中的变量(通过request.setAttribute()保存到request中的值)不能在新的页面中采用,采用方法(3)能. 综上,我们应该采用(1),(2)重定向比较好.  <br /><br /><br />四、JSP中正确应用类:  <br /><br />应该把类当成JAVA BEAN来用，不要在&lt;% %&gt; 中直接使用. 如下的代码(1)经过JSP引擎转化后会变为代码(2): <br />从中可看出如果把一个类在JSP当成JAVA BEAN 使用,JSP会根据它的作用范围把它保存到相应的内部对象中. <br />如作用范围为request,则把它保存到request对象中.并且只在第一次调用(对象的值为null)它时进行实例化. 而如果在&lt;% %&gt;中直接创建该类的一个对象,则每次调用JSP时,都要重新创建该对象,会影响性能.  <br /><br />代码(1) <br />&lt;jsp:useBean id="test" scope="request" class="demo.com.testdemo"&gt; <br />&lt;/jsp:useBean&gt; <br />  <br />&lt;% <br />test.print("this is use java bean"); <br />  <br />testdemo td= new testdemo(); <br />td.print("this is use new"); <br />%&gt; <br />  <br /><br /><br />代码(2) <br />demo.com.testdemo test = (demo.com.testdemo)request.getAttribute("test");  <br />if (test == null)  <br />{  <br />       try  <br />       {  <br />                 test = (demo.com.testdemo) java.beans.Beans.instantiate(getClass().getClassLoader(),"demo.com.testdemo");  <br />       }  <br />       catch (Exception _beanException)  <br />       { <br />               throw new weblogic.utils.NestedRuntimeException("cannot instantiate 'demo.com.testdemo'",_beanException);  <br />       }  <br />       request.setAttribute("test", test);  <br />       out.print("\r\n"); <br />}  <br />out.print("\r\n\r\n\r\n"); <br />test.print("this is use java bean");  <br />  <br />testdemo td= new testdemo(); <br />td.print("this is use new"); <br /><br />  <br /><br /><br /><br />五、JSP的调试  <br /><br />JSP的调试比较麻烦,特别是当bean是在一个session中存在时，更加困难。得从好几个页面开始往里面走才行。通常是用out.println()或System.out.print()来打一大堆的信息来查问题。如果是用jbuilder做开发,它能直接调试JSP.不过更重要的是知道错误产生的原因及解决方法。下面对一些JSP编程常见错误进行分析。  <br /><br />(1).java.lang.NullPointerException异常 <br />一般是对一个为NULL值的变量进行操作引起的.如下面的操作就会抛出 <br />java.lang.NullPointerException <br />String a = null;  <br />a.substring(0,1);  <br />  <br />为避免这种异常最好在对变量操作之前检查看它是否为NULL值.如: <br />&lt;% String ss=Session.getAttribute("NAME")  <br />if isnull(ss)  <br />{  <br /><br />}  <br />else  <br />{  <br /><br />}  <br />%&gt;  <br /><br />(2).JSP是用JAVA写的，所以它是大小写敏感的，用过其他编程语言的人最容易犯这个错误。另外在浏览器的地址栏中输入的访问JSP的地址也是区分大小写的.如http://localhost:7001/demo/t.jsp与http://localhost:7001/Demo/t.jsp是不一样的 <br /><br />(3).在jsp中判断字符串要使用compareTo方法，不要用==，因为在java中String变量不是一个简单的变量而是一个类实例，不同的方法会得到 不同的结果，如下所示：  <br /><br />　　 <br /><br />　　String str1="ABCD";  <br />　　String str2="ABCD"; (或 String str2="AB"+"CD";   <br />　　if (str1==str2)  <br />　　 out.print("yes");  <br />　　else  <br />　　 out.print("no");  <br />　　结果是"yes"。  <br />　  <br /><br />　　String str1,str2,str3;  <br />　　str1="ABCD";  <br />　　str2="AB";  <br />　　str3=str2+"CD";  <br />　　if (str1==str3)  <br />　　 out.print("yes");  <br />　　else  <br />　　 out.print("no");  <br />　　结果是"no"。  <br /><br /><br />String str1=new String("ABCD");  <br />　　String str2=new String("ABCD");  <br />　　if (str1==str2)  <br />　　 out.print("yes");  <br />　　else  <br />　　 out.print("no");  <br />　　结果是"no"。  <br /><br /><br />String str1=new String("ABCD");  <br />　　String str2=new String("ABCD");  <br />　　if (str1.compareTo(str2)==0)  <br />　　 out.print("yes");  <br />　　else  <br />　　 out.print("no");  <br />　　结果是"yes"。  <br /><br />(4)防止JSP或SERVLET中的输出被浏览器保存在缓冲区中: <br />浏览器在默认情况下会把浏览过的网页保存在缓冲区中,在调试时,一般不希望这样.把下面的脚本加入程序中,就可防止JSP或SERVLET中的输出被浏览器保存在缓冲区中  <br />&lt;%  <br />response.setHeader("Cache-Control","no-store"); //HTTP 1.1  <br />response.setHeader("Pragma","no-cache"); //HTTP 1.0  <br />response.setDateHeader ("Expires", 0); //prevents caching at the proxy server  <br />%&gt;  <br />在IE中也可通过设置实现：把/工具/INTERNET选项/常规/设置/的检察所存页面的较新版本,设为每次访问该页时都检查. <br /><br /><br />六、COOKIE <br /><br />HTTP COOKIE实质是服务端与在客户端之间传送的普通HTTP头,可保存也可不保存在客户的硬盘上.如果保存,每一个文件大小不超过4K的文本文件.多个COOKIE可保存到同一个文件中. 如果从编程角度来看,在JSP中COOKIE就是JAVA提供的一个类.常用的方法如下所表示，因为客户端可能不接受COOKIE，所以建议不用它，改用SESSION等其他方式。  <br /><br /><br />public class cookie  <br />{  <br />public String getDomain() //返回该COOKIE的有效域  <br />public int getMaxAge() //返回该COOKIE的有效期,单位为秒  <br />public String getName() //返回该COOKIE的名称  <br />public String getPath() //返回该COOKIE的有效路径  <br />public boolean getSecure() //返回该COOKIE的安全设置  <br />public String getValue() //返回该COOKIE的值  <br />public void setDomain(java.lang.String pattern) //设置该COOKIE的有效域  <br />public void setMaxAge(int expiry) //设置该COOKIE的有效期,单位为秒  <br />public void setPath(java.lang.String uri) //设置该COOKIE的有效路径  <br />public void setSecure(boolean flag) //设置该COOKIE的安全设置  <br />public void setValue(java.lang.String newValue) //设置该COOKIE的值  <br />}  <br />一个COOKIE包含以下五部分:  <br /><br />NAME/VALUE对,设置该COOKIE的名字及它保存的值  <br />COOKIE通常和服务器相关,如果将域设为JAVA.SUN.COM,那么该COOKIE就和这个域相关,只对该网址起作用,当浏览该网址时,浏览器将把该COOKIE的内容发送给服务端,COOKIE是作为HTTP HEADER的一部分被发送的，如果没有设置域,那么COOKIE就只和创建该COOKIE的服务器相关.  <br />路径用于指定服务器上可以使用该COOKIE的文件所在的路径,它只对该网址下的该路径下的应用起作用."/"表示服务器上所有目录都可以使用该COOKIE.  <br />COOKIE都有一个有效期,有效期默认值为-1,这表示没有保存该COOKIE,当该浏览器退出时,该COOKIE立即失效.  <br />安全选项true/false,如果设置为true,那么在服务端与在客户端之间传送该COOKIE的内容时,采用HTTPS协议.  <br />如何检查一个客户端是否支持COOKIE的方法:  <br />用下面的方法写一个COOKIE到客户端,并确认成功  <br />try  <br />{  <br />Cookie c = new Cookie("mycookie","COOKIE TEST");  <br />response.addCookie(c);  <br />}  <br />catch(Exception e)  <br />{  <br />      System.out.println(e);  <br />}  <br /><br /><br />然后在一个新的JSP文件中:用下面的方法取客户端的COOKIE到cookies中, 如果cookies.length ==0,说明该客户端的浏览器不支持COOKIE  <br />try  <br />{  <br />Cookie[] cookies = request.getCookies();  <br />if(cookies.length ==0)  <br />{  <br />      System.out.println("not support cookie");  <br />}  <br />}  <br />catch(Exception e)  <br />{  <br />      System.out.println(e);  <br />}  <br /><br /><br /><br />七、JSP和SERVLET的区别: <br /><br />SUN首先发展出SERVLET，其功能比较强劲，体系设计也很先进，只是，它输出HTML语句还是采用了老的CGI方式，是一句一句输出，所以，编写和修改HTML非常不方便。 后来SUN推出了类似于ASP的JSP，把JAVA代码嵌套到HTML语句中，这样，就大大简化和方便了网页的设计和修改。ASP，PHP，JSP都是嵌套型的SCRIPT语言。 一个分布式系统应分为三层：表示层,业务逻辑层,数据存取层,在J2EE体系结构中,SERVLET用来写业务逻辑层是很强大的，但是对于写表示层就很不方便。JSP则主要是为了方便写表示层而设计的。ENTITY BEAN实现数据存取层，SESSION BEAN实现业务逻辑层。如果是简单的应用系统,可采用JSP+BEANS的结构进行设计,JSP中应该仅仅存放与表示层有关的东西，也就是说，只放输出HTML网页的部份。而所有的数据计算，数据分析，数据库联结处理，统统是属于业务逻辑层，应该放在JAVA BEANS中。通过JSP调用JAVA BEANS，实现两层的整合。 实际上，微软的DNA技术，简单说，就是ASP+COM/DCOM技术。与JSP+BEANS完全类似，所有的表示层由ASP完成，所有的业务逻辑由COM/DCOM完成。 为什么要采用这些组件技术呢？因为单纯的ASP/JSP语言是非常低效率执行的，如果出现大量用户点击，纯SCRIPT语言很快就到达了他的功能上限，而组件技术就能大幅度提高功能上限，加快执行速度。另外一方面，纯SCRIPT语言将表示层和业务逻辑层混在一起，造成修改不方便，并且代码不能重复利用，采用组件技术就只改组件就可以了。 对于复杂的应用，应该采用ENTITY BEAN实现数据存取层，SESSION BEAN实现业务逻辑层，用JSP来调用SESSION BEAN，由SESSION BEAN调用ENTITY BEAN。即采用JSP+EJB来构建一个复杂的分布式系统。它比JSP+BEAN具有更高的吞吐量，可靠性，安全性。综上所述，对简单应用，可采用JSP+BAEN，对复杂的应用系统，应采用JSP+EJB，SERVLET变的无足轻重。用JSP完全可替代它。 
<div></div></div>
<img src ="http://www.blogjava.net/ltc603/aggbug/67151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ltc603/" target="_blank">阿成</a> 2006-09-01 16:53 <a href="http://www.blogjava.net/ltc603/archive/2006/09/01/67151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>