<?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状