﻿<?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-笨笨猪</title><link>http://www.blogjava.net/cxh8318/</link><description>冰江独行</description><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 06:28:00 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 06:28:00 GMT</pubDate><ttl>60</ttl><item><title>关于opendrive网盘</title><link>http://www.blogjava.net/cxh8318/archive/2015/01/21/422306.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Tue, 20 Jan 2015 18:00:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2015/01/21/422306.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/422306.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2015/01/21/422306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/422306.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/422306.html</trackback:ping><description><![CDATA[网络上的网盘有很多很多，但真正比较好用的，值得信赖的，个人感觉也就是opendrive了。可以有https外链。大家可以注册试试看。<a href="http://www.opendrive.com">www.opendrive.com</a>。<img src ="http://www.blogjava.net/cxh8318/aggbug/422306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2015-01-21 02:00 <a href="http://www.blogjava.net/cxh8318/archive/2015/01/21/422306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>云存储 网络硬盘</title><link>http://www.blogjava.net/cxh8318/archive/2011/05/23/350839.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Mon, 23 May 2011 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2011/05/23/350839.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/350839.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2011/05/23/350839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/350839.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/350839.html</trackback:ping><description><![CDATA[  <img src ="http://www.blogjava.net/cxh8318/aggbug/350839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2011-05-23 15:29 <a href="http://www.blogjava.net/cxh8318/archive/2011/05/23/350839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>云存储dropbox的替代品</title><link>http://www.blogjava.net/cxh8318/archive/2010/09/23/332681.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Thu, 23 Sep 2010 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2010/09/23/332681.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/332681.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2010/09/23/332681.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/332681.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/332681.html</trackback:ping><description><![CDATA[<div class="postbody">众所周知，dropbox是云存储中的老大，但由于种种原因被墙了。那好，我就再找个。<br />1、金山快盘，由金山公司出品，公司大，应该有保障。金山快盘可以在本地生成一个新的盘符，方便用户浏览使用。推荐使用金山快盘，15G超大免费空间，相当于给电脑增加了一块永不消失的硬盘，传输速度快，并且可以通过电脑和手机随时随地访问快盘里的文件！通过下面地址注册，登录快盘客户端后你还能额外获取1GB快盘空间奖励(也就是说通过邀请注册会额外多加1个G)。 <a href="http://k.wps.cn/register/?invite=vkmkbt">http://k.wps.cn/register/?invite=vkmkbt</a><br />&nbsp;2、数据银行，貌似是华为出品，也很不错。注册之后默认是3G。<br />我认为这两个软件都差不多，大家使用下就知道了。<br />附上链接地址：<br />金山快盘：http://k.wps.cn/register/?invite=vkmkbt<br />数据银行：http://www.dbank.com/invite/414238 </div><script type="text/javascript">
//<![cdata[ Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1'));
Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90);
//]]&gt;
</script><img src ="http://www.blogjava.net/cxh8318/aggbug/332681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2010-09-23 13:51 <a href="http://www.blogjava.net/cxh8318/archive/2010/09/23/332681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何处理Java及其相关字符集编码的问题</title><link>http://www.blogjava.net/cxh8318/archive/2008/02/27/182527.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Wed, 27 Feb 2008 09:46:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2008/02/27/182527.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/182527.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2008/02/27/182527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/182527.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/182527.html</trackback:ping><description><![CDATA[1. 概述
<p>　　本文主要包括以下几个方面：编码基本知识，java，系统软件，url，工具软件等。</p>
<p>　　在下面的描述中，将以"中文"两个字为例，经查表可以知道其GB2312编码是"d6d0 cec4"，Unicode编码为"4e2d 6587"，UTF编码就是"e4b8ad e69687"。注意，这两个字没有iso8859-1编码，但可以用iso8859-1编码来"表示"。</p>
<p>　　2. 编码基本知识</p>
<p>　　最早的编码是iso8859-1，和ascii编码相似。但为了方便表示各种各样的语言，逐渐出现了很多标准编码，重要的有如下几个。</p>
<p>　　2.1. iso8859-1</p>
<p>　　属于单字节编码，最多能表示的字符范围是0-255，应用于英文系列。比如，字母a的编码为0x61=97。</p>
<p>　　很明显，iso8859-1编码表示的字符范围很窄，无法表示中文字符。但是，由于是单字节编码，和计算机最基础的表示单位一致，所以很多时候，仍旧使用iso8859-1编码来表示。而且在很多协议上，默认使用该编码。比如，虽然"中文"两个字不存在iso8859-1编码，以gb2312编码为例，应该是"d6d0 cec4"两个字符，使用iso8859-1编码的时候则将它拆开为4个字节来表示："d6 d0 ce c4"(事实上，在进行存储的时候，也是以字节为单位处理的)。而如果是UTF编码，则是6个字节"e4 b8 ad e6 96 87"。很明显，这种表示方法还需要以另一种编码为基础。</p>
<p>　　2.2. GB2312/GBK</p>
<p>　　这就是汉子的国标码，专门用来表示汉字，是双字节编码，而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示繁体字和简体字，而gb2312只能表示简体字，gbk是兼容gb2312编码的。</p>
<p>　　2.3. unicode</p>
<p>　　这是最统一的编码，可以用来表示所有语言的字符，而且是定长双字节(也有四字节的)编码，包括英文字母在内。所以可以说它是不兼容iso8859-1编码的，也不兼容任何编码。不过，相对于iso8859-1编码来说，uniocode编码只是在前面增加了一个0字节，比如字母a为"00 61"。</p>
<p>　　需要说明的是，定长编码便于计算机处理(注意GB2312/GBK不是定长编码)，而unicode又可以用来表示所有字符，所以在很多软件内部是使用unicode编码来处理的，比如java。</p>
<p>　　2.4. UTF</p>
<p>　　考虑到unicode编码不兼容iso8859-1编码，而且容易占用更多的空间：因为对于英文字母，unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码，utf编码兼容iso8859-1编码，同时也可以用来表示所有语言的字符，不过，utf编码是不定长编码，每一个字符的长度从1-6个字节不等。另外，utf编码自带简单的校验功能。一般来讲，英文字母都是用一个字节表示，而汉字使用三个字节。</p>
<p>　　注意，虽然说utf是为了使用更少的空间而使用的，但那只是相对于unicode编码来说，如果已经知道是汉字，则使用GB2312/GBK无疑是最节省的。不过另一方面，值得说明的是，虽然utf编码对汉字使用3个字节，但即使对于汉字网页，utf编码也会比unicode编码节省，因为网页中包含了很多的英文字符。</p>
<p>　　3. java对字符的处理</p>
<p>　　在java应用软件中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。</p>
<p>　　3.1. getBytes(charset)</p>
<p>　　这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下(即没有错误的时候)存储为"4e2d 6587"，如果charset为"gbk"，则被编码为"d6d0 cec4"，然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1"，则由于无法编码，最后返回 "3f 3f"(两个问号)。</p>
<p>　　3.2. new String(charset)</p>
<p>　　这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587"，但iso8859-1最后变成了"003f 003f"(两个问号)。</p>
<p>　　因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) === str，即完全可逆。</p>
<p>　　3.3. setCharacterEncoding()</p>
<p>　　该函数用来设置http请求或者相应的编码。</p>
<p>　　对于request，是指提交内容的编码，指定后可以通过getParameter()则直接获得正确的字符串，如果不指定，则默认使用iso8859-1编码，需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前，不能执行任何getParameter()。java doc上说明：This method must be called prior to reading request parameters or reading input using getReader()。而且，该指定只对POST方法有效，对GET方法无效。分析原因，应该是在执行第一个getParameter()的时候，java将会按照编码分析所有的提交内容，而后续的getParameter()不再进行分析，所以setCharacterEncoding()无效。而对于GET方法提交表单是，提交的内容在URL中，一开始就已经按照编码分析所有的提交内容，setCharacterEncoding()自然就无效。</p>
<p>　　对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。</p>
<p>　　3.4. 处理过程</p>
<p>　　下面分析两个有代表性的例子，说明java对编码有关问题的处理方法。</p>
<p>　　3.4.1. 表单输入</p>
<p>　　User input *(gbk:d6d0 cec4) browser *(gbk:d6d0 cec4) web server iso8859-1(00d6 00d 000ce 00c4) class，需要在class中进行处理：getbytes("iso8859-1")为d6 d0 ce c4，new String("gbk")为d6d0 cec4，内存中以unicode编码则为4e2d 6587。</p>
<p>　　l 用户输入的编码方式和页面指定的编码有关，也和用户的操作系统有关，所以是不确定的，上例以gbk为例。</p>
<p>　　l 从browser到web server，可以在表单中指定提交内容时使用的字符集，否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数，则其编码往往是操作系统本身的编码，因为这时和页面无关。上述仍旧以gbk编码为例。</p>
<p>　　l Web server接收到的是字节流，默认时(getParameter)会以iso8859-1编码处理之，结果是不正确的，所以需要进行处理。但如果预先设置了编码(通过request. setCharacterEncoding ())，则能够直接获取到正确的结果。</p>
<p>　　l 在页面中指定编码是个好习惯，否则可能失去控制，无法指定正确的编码。</p>
<p>　　3.4.2. 文件编译</p>
<p>　　假设文件是gbk编码保存的，而编译有两种编码选择：gbk或者iso8859-1，前者是中文windows的默认编码，后者是linux的默认编码，当然也可以在编译时指定编码。</p>
<p>　　Jsp *(gbk:d6d0 cec4) java file *(gbk:d6d0 cec4) compiler read uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) compiler write utf(gbk: e4b8ad e69687; iso8859-1: *) compiled file unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4) class。所以用gbk编码保存，而用iso8859-1编译的结果是不正确的。</p>
<p>　　class unicode(4e2d 6587) system.out / jsp.out gbk(d6d0 cec4) os console / browser。</p>
<p>　　l 文件可以以多种编码方式保存，中文windows下，默认为ansi/gbk。</p>
<p>　　l 编译器读取文件时，需要得到文件的编码，如果未指定，则使用系统默认编码。一般class文件，是以系统默认编码保存的，所以编译不会出问题，但对于jsp文件，如果在中文windows下编辑保存，而部署在英文linux下运行/编译，则会出现问题。所以需要在jsp文件中用pageEncoding指定编码。</p>
<p>　　l Java编译的时候会转换成统一的unicode编码处理，最后保存的时候再转换为utf编码。</p>
<p>　　l 当系统输出字符的时候，会按指定编码输出，对于中文windows下，System.out将使用gbk编码，而对于response(浏览器)，则使用jsp文件头指定的contentType，或者可以直接为response指定编码。同时，会告诉browser网页的编码。如果未指定，则会使用iso8859-1编码。对于中文，应该为browser指定输出字符串的编码。</p>
<p>　　l browser显示网页的时候，首先使用response中指定的编码(jsp文件头指定的contentType最终也反映在response上)，如果未指定，则会使用网页中meta项指定中的contentType。</p>
<p>　　3.5. 几处设置</p>
<p>　　对于web应用程序，和编码有关的设置或者函数如下。</p>
<p>　　3.5.1. jsp编译</p>
<p>　　指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：。另外，对于一般class文件，可以在编译的时候指定编码。</p>
<p>　　3.5.2. jsp输出</p>
<p>　　指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：。该设置和response.setCharacterEncoding("GBK")等效。</p>
<p>　　3.5.3. meta设置</p>
<p>　　指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：</p>
<p>　　如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。</p>
<p>　　需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。</p>
<p>　　3.5.4. form设置</p>
<p>　　当浏览器提交表单的时候，可以指定相应的编码。例如：</p>
<p>　　。一般不必不使用该设置，浏览器会直接使用网页的编码。</p>
<p>　　4. 系统软件</p>
<p>　　下面讨论几个相关的系统软件。</p>
<p>　　4.1. mysql数据库</p>
<p>　　很明显，要支持多语言，应该将数据库的编码设置成utf或者unicode，而utf更适合与存储。但是，如果中文数据中包含的英文字母很少，其实unicode更为适合。</p>
<p>　　数据库的编码可以通过mysql的配置文件设置，例如default-character-set=utf8。还可以在数据库链接URL中设置，例如： useUnicode=true&amp;characterEncoding=UTF-8。注意这两者应该保持一致，在新的sql版本里，在数据库链接URL里可以不进行设置，但也不能是错误的设置。</p>
<p>　　4.2. apache</p>
<p>　　appache和编码有关的配置在httpd.conf中，例如AddDefaultCharset UTF-8。如前所述，该功能会将所有静态页面的编码设置为UTF-8，最好关闭该功能。</p>
<p>　　另外，apache还有单独的模块来处理网页响应头，其中也可能对编码进行设置。</p>
<p>　　4.3. linux默认编码</p>
<p>　　这里所说的linux默认编码，是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG，默认编码会影响到java URLEncode的行为，下面有描述。</p>
<p>　　建议都设置为"zh_CN.UTF-8"。</p>
<p>　　4.4. 其它</p>
<p>　　为了支持中文文件名，linux在加载磁盘时应该指定字符集，例如：mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。</p>
<p>　　另外，如前所述，使用GET方法提交的信息不支持request.setCharacterEncoding()，但可以通过tomcat的配置文件指定字符集，在tomcat的server.xml文件中，形如：。这种方法将统一设置所有请求，而不能针对具体页面进行设置，也不一定和browser使用的编码相同，所以有时候并不是所期望的。</p>
<p>　　5. URL地址</p>
<p>　　URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。</p>
<p>　　5.1. URL编码</p>
<p>　　对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。</p>
<p>　　IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%e4%b8%ad%e6%96%87.html?a=x4ex2dx65x87";而UTF-8选项无效时，将发送链接"x4ex2dx65x87.html?a=x4ex2dx65x87"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。</p>
<p>　　当web server(tomcat)接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码(上面已经描述，可以使用URLEncoding来设置成其它编码)识别。上述例子的结果分别是"ue4ub8uadue6u96u87.html?a=u4eu2du65u87"和"u4eu2du65u87.html?a=u4eu2du65u87"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"u"，表示是unicode。</p>
<p>　　所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。</p>
<p>　　5.2. rewrite</p>
<p>　　熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码(去除%)，即完成上述web server(tomcat)的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本(我使用的是apache 2.0.54)问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。</p>
<p>　　rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。</p>
<p>　　5.3. URLEncode.encode()</p>
<p>　　这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法(deprecated)。应该在使用的时候增加编码指定。</p>
<p>　　当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%4e%2d%65%87"，而默认编码为"UTF-8"，结果却是"%e4%b8%ad%e6%96%87"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。</p>
<p>　　建议统一指定为"UTF-8"编码，可能需要修改相应的程序。</p>
<p>　　5.4. 一个解决方案</p>
<p>　　上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。</p>
<p>　　针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。</p>
<p>　　比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码(比如"GBK")，下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解。</p>
<div style="scrollbar-highlight-color: buttonhighlight; overflow: auto; width: 500px">
<pre style="border-right: black 1px solid; padding-right: 4px; border-top: black 1px solid; padding-left: 4px; padding-bottom: 4px; border-left: black 1px solid; padding-top: 4px; border-bottom: black 1px solid; background-color: #ededed">
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><span style="color: #000000">　　</span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> boolean isValidUtf8(</span><span style="color: #0000ff">byte</span><span style="color: #000000">[] b,</span><span style="color: #0000ff">int</span><span style="color: #000000"> aMaxCount){
　　</span><span style="color: #0000ff">int</span><span style="color: #000000"> lLen</span><span style="color: #000000">=</span><span style="color: #000000">b.length,lCharCount</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;
　　</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000"> i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i
　　</span><span style="color: #0000ff">byte</span><span style="color: #000000"> lByte</span><span style="color: #000000">=</span><span style="color: #000000">b[i</span><span style="color: #000000">++</span><span style="color: #000000">];</span><span style="color: #008000">//</span><span style="color: #008000">to fast operation, ++ now, ready for the following for(;;)</span><span style="color: #008000">
</span><span style="color: #000000">
　　</span><span style="color: #0000ff">if</span><span style="color: #000000">(lByte</span><span style="color: #000000">&gt;=</span><span style="color: #000000">0</span><span style="color: #000000">) </span><span style="color: #0000ff">continue</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">&gt;=0 is normal ascii</span><span style="color: #008000">
</span><span style="color: #000000">
　　</span><span style="color: #0000ff">if</span><span style="color: #000000">(lByte</span><span style="color: #000000">&lt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xc0</span><span style="color: #000000"> </span><span style="color: #000000">||</span><span style="color: #000000"> lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xfd</span><span style="color: #000000">) </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;
　　</span><span style="color: #0000ff">int</span><span style="color: #000000"> lCount</span><span style="color: #000000">=</span><span style="color: #000000">lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xfc</span><span style="color: #000000">?</span><span style="color: #000000">5</span><span style="color: #000000">:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xf8</span><span style="color: #000000">?</span><span style="color: #000000">4</span><span style="color: #000000">
　　:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xf0</span><span style="color: #000000">?</span><span style="color: #000000">3</span><span style="color: #000000">:lByte</span><span style="color: #000000">&gt;</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xe0</span><span style="color: #000000">?</span><span style="color: #000000">2</span><span style="color: #000000">:</span><span style="color: #000000">1</span><span style="color: #000000">;
　　</span><span style="color: #0000ff">if</span><span style="color: #000000">(i</span><span style="color: #000000">+</span><span style="color: #000000">lCount</span><span style="color: #000000">&gt;</span><span style="color: #000000">lLen) </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;
　　</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000"> j</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;j</span><span style="color: #000000">=</span><span style="color: #000000">(</span><span style="color: #0000ff">byte</span><span style="color: #000000">)</span><span style="color: #000000">0xc0</span><span style="color: #000000">) </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;
　　}
　　</span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">true</span><span style="color: #000000">;
　　}</span></div>
</pre>
</div>
<p>　　相应地，一个使用上述方法的例子如下：</p>
<div style="scrollbar-highlight-color: buttonhighlight; overflow: auto; width: 500px">
<pre style="border-right: black 1px solid; padding-right: 4px; border-top: black 1px solid; padding-left: 4px; padding-bottom: 4px; border-left: black 1px solid; padding-top: 4px; border-bottom: black 1px solid; background-color: #ededed">
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><span style="color: #000000">　　</span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> String getUrlParam(String aStr,String aDefaultCharset)
　　throws UnsupportedEncodingException{
　　</span><span style="color: #0000ff">if</span><span style="color: #000000">(aStr</span><span style="color: #000000">==</span><span style="color: #0000ff">null</span><span style="color: #000000">) </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">;
　　</span><span style="color: #0000ff">byte</span><span style="color: #000000">[] lBytes</span><span style="color: #000000">=</span><span style="color: #000000">aStr.getBytes(</span><span style="color: #000000">"</span><span style="color: #000000">ISO-8859-1</span><span style="color: #000000">"</span><span style="color: #000000">);
　　</span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> String(lBytes,StringUtil.isValidUtf8(lBytes)</span><span style="color: #000000">?</span><span style="color: #000000">"</span><span style="color: #000000">utf8</span><span style="color: #000000">"</span><span style="color: #000000">:aDefaultCharset);
　　}</span></div>
</pre>
</div>
<p>　　不过，该方法也存在缺陷，如下两方面：</p>
<p>　　l 没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。</p>
<p>　　l 可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是" xd1xa7xcfxb0"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。</p>
<p>　　有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习"，google将无法正确识别，而其他汉字一般能够正常识别。</p>
<p>　　最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。</p>
<p>　　6. 其它</p>
<p>　　下面描述一些和编码有关的其他问题。</p>
<p>　　6.1. SecureCRT</p>
<p>　　除了浏览器和控制台与编码有关外，一些客户端也很有关系。比如在使用SecureCRT连接linux时，应该让SecureCRT的显示编码(不同的session，可以有不同的编码设置)和linux的编码环境变量保持一致。否则看到的一些帮助信息，就可能是乱码。</p>
<p>　　另外，mysql有自己的编码设置，也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候，可能无法处理中文字符，查询结果也会出现乱码。</p>
<p>　　对于Utf-8文件，很多编辑器(比如记事本)会在文件开头增加三个不可见的标志字节，如果作为mysql的输入文件，则必须要去掉这三个字符。(用linux的vi保存可以去掉这三个字符)。一个有趣的现象是，在中文windows下，创建一个新txt文件，用记事本打开，输入"连通"两个字，保存，再打开，你会发现两个字没了，只留下一个小黑点。</p>
<p>　　6.2. 过滤器</p>
<p>　　如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例子SetCharacterEncodingFilter。</p>
<p>　　6.3. POST和GET</p>
<p>　　很明显，以POST提交信息时，URL有更好的可读性，而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容，也能够用于收藏。</p>
<p>　　从统一的角度考虑问题，建议采用GET方法，这要求在程序中获得参数是进行特殊处理，而无法使用setCharacterEncoding()的便利，如果不考虑rewrite，就不存在IE的UTF-8问题，可以考虑通过设置URIEncoding来方便获取URL中的参数。</p>
<p>　　6.4. 简繁体编码转换</p>
<p>　　GBK同时包含简体和繁体编码，也就是说同一个字，由于编码不同，在GBK编码下属于两个字。有时候，为了正确取得完整的结果，应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所有繁体字，转换为相应的简体字，BIG5编码的数据，也应该转化成相应的简体字。当然，仍旧以UTF编码存储。</p>
<p>　　例如，对于"语言 語言"，用UTF表示为"xE8xAFxADxE8xA8x80 xE8xAAx9ExE8xA8x80"，进行简繁体编码转换后应该是两个相同的 "xE8xAFxADxE8xA8x80&gt;"。</p>
<img src ="http://www.blogjava.net/cxh8318/aggbug/182527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2008-02-27 17:46 <a href="http://www.blogjava.net/cxh8318/archive/2008/02/27/182527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse快捷操作</title><link>http://www.blogjava.net/cxh8318/archive/2007/11/16/161020.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Fri, 16 Nov 2007 07:03:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/11/16/161020.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/161020.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/11/16/161020.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/161020.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/161020.html</trackback:ping><description><![CDATA[1.&nbsp;Control-Shift-T:&nbsp;打开类型（Open&nbsp;type）。如果你不是有意磨洋工，还是忘记通过源码树（source&nbsp;tree）打开的方式吧。<br />
<br />
2.&nbsp;Control-Shift-R:&nbsp;打开资源（不只是用来寻找Java文件）。小提示：利用Navigator视图的黄色双向箭头按钮让你的编辑窗口和导航器相关联。这会让你打开的文件对应显示在导航器的层级结构中，这样便于组织信息。如果这影响了速度，就关掉它。<br />
<br />
3.&nbsp;F3:&nbsp;打开申明（Open&nbsp;declaration）。或者，利用Declaration&nbsp;Tab（在Java视图模式下，选择Windows&nbsp;--&gt;&nbsp;Show&nbsp;View&nbsp;--&nbsp;&gt;&nbsp;Declaration）。当你选中代码中的一个方法，然后按这个按键，它会把整个方法在申明方框里显示出来。<br />
<br />
4.&nbsp;Alt-left&nbsp;arrow:&nbsp;在导航历史记录（Navigation&nbsp;History）中后退。就像Web浏览器的后退按钮一样，在利用F3跳转之后，特别有用。（用来返回原先编译的地方）<br />
<br />
5.&nbsp;Alt-right&nbsp;arrow:&nbsp;导航历史记录中向前。<br />
<br />
6.&nbsp;Control-Q:&nbsp;回到最后依次编辑的地方。这个快捷键也是当你在代码中跳转后用的。特别是当你钻的过深，忘记你最初在做什么的时候。<br />
<br />
7.&nbsp;Control-Shift-G:&nbsp;在workspace中搜索引用（reference）。这是重构的前提。对于方法，这个热键的作用和F3恰好相反。它使你在方法的栈中，向上找出一个方法的所有调用者。一个与此相关的功能是开启&#8220;标记&#8221;功能（occurrence&nbsp;marking）&nbsp;。选择Windows-&gt;Preferences-&gt;Java-&gt;&nbsp;Editor-&gt;&nbsp;Mark&nbsp;Occurrences，勾选选项。这时，当你单击一个元素的时候，代码中所有该元素存在的地方都会被高亮显示。我个人只使用&#8220;标记本地变量&#8221;（Mark&nbsp;Local&nbsp;Variables）。注意：太多的高亮显示会拖慢Eclipse。<br />
<br />
8.&nbsp;Control-Shift-F:&nbsp;根据代码风格设定重新格式化代码。我们的团队有统一的代码格式，我们把它放在我们的wiki上。要这么做，我们打开Eclipse，选择Window?Preferences?Java?Code&nbsp;Style，然后设置Code&nbsp;Formatter，Code&nbsp;Style和Organize&nbsp;Imports。利用导出（Export）功能来生成配置文件。我们把这些配置文件放在wiki上，然后团队里的每个人都导入到自己的Eclipse中。<br />
<br />
9.&nbsp;Control-O:&nbsp;快速概要(quick&nbsp;outline)。通过这个快捷键，你可以迅速的跳到一个方法或者属性，只需要输入名字的头几个字母。&nbsp;<br />
<br />
10.&nbsp;Control-/:&nbsp;对一行注释或取消注释。对于多行也同样适用。<br />
<br />
11.&nbsp;Control-Alt-down&nbsp;arrow:&nbsp;复制高亮显示的一行或多行。<br />
<br />
12.&nbsp;Alt-down&nbsp;arrow:&nbsp;将一行或多行向下移动。Alt-up&nbsp;arrow会向上移动。<br />
<br />
其他的热键在菜单里有。你可以通过按下Control-Shift-L（从3.1版本开始），看到所有快捷键的列表。按下Control-Shift-L两次，会显示热键对话框（Keys&nbsp;Preferences&nbsp;dialog），你可以在这里自己设置热键。我欢迎你在Talkback部分发表你的Eclipse提示。
<img src ="http://www.blogjava.net/cxh8318/aggbug/161020.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-11-16 15:03 <a href="http://www.blogjava.net/cxh8318/archive/2007/11/16/161020.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一篇关于web.xml配置的详细说明(转载) </title><link>http://www.blogjava.net/cxh8318/archive/2007/09/27/148502.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Thu, 27 Sep 2007 01:12:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/09/27/148502.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/148502.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/09/27/148502.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/148502.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/148502.html</trackback:ping><description><![CDATA[<p>1 定义头和根元素</p>
<p>部署描述符文件就像所有XML文件一样，必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。<br />
DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本（如2.2或2.3）并指定管理此文件其余部分内容的语法的DTD(Document Type Definition，文档类型定义)。<br />
所有部署描述符文件的顶层（根）元素为web-app。请注意，XML元素不像HTML，他们是大小写敏感的。因此，web-App和WEB-APP都是不合法的，web-app必须用小写。</p>
<p>2 部署描述符文件内的元素次序</p>
<p>XML 元素不仅是大小写敏感的，而且它们还对出现在其他元素中的次序敏感。例如，XML头必须是文件中的第一项，DOCTYPE声明必须是第二项，而web- app元素必须是第三项。在web-app元素内，元素的次序也很重要。服务器不一定强制要求这种次序，但它们允许（实际上有些服务器就是这样做的）完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。<br />
下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如，此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意，所有这些元素都是可选的。因此，可以省略掉某一元素，但不能把它放于不正确的位置。<br />
l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。<br />
l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。<br />
l description description元素给出与此有关的说明性文本。<br />
l context-param context-param元素声明应用范围内的初始化参数。<br />
l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。<br />
l filter-mapping 一旦命名了一个过滤器，就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。<br />
l listener servlet API的版本2.3增加了对事件监听程序的支持，事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。<br />
l servlet 在向servlet或JSP页面制定初始化参数或定制URL时，必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。<br />
l servlet-mapping 服务器一般为servlet提供一个缺省的URL：http://host/webAppPrefix/servlet/ServletName。但是，常常会更改这个URL，以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时，使用servlet-mapping元素。<br />
l session-config 如果某个会话在一定时间内未被访问，服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值，或者可利用session-config元素制定缺省超时值。<br />
l mime-mapping 如果Web应用具有想到特殊的文件，希望能保证给他们分配特定的MIME类型，则mime-mapping元素提供这种保证。<br />
l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时，使用哪个文件。<br />
l error-page error-page元素使得在返回特定HTTP状态代码时，或者特定类型的异常被抛出时，能够制定将要显示的页面。<br />
l taglib taglib元素对标记库描述符文件（Tag Libraryu Descriptor file）指定别名。此功能使你能够更改TLD文件的位置，而不用编辑使用这些文件的JSP页面。<br />
l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。<br />
l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。<br />
l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用<br />
l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。<br />
l security-role security-role元素给出安全角色的一个列表，这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。<br />
l env-entry env-entry元素声明Web应用的环境项。<br />
l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。<br />
l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。</p>
<p>3 分配名称和定制的UL</p>
<p>在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称，使用servlet-mapping元素将定制的URL与刚分配的名称相关联。<br />
3.1 分配名称<br />
为了提供初始化参数，对servlet或JSP页面定义一个定制URL或分配一个安全角色，必须首先给servlet或JSP页面一个名称。可通过 servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素（在web-app元素内），如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt; <br />
这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名称具有两个主要的含义。首先，初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在 URL而不是类名中使用此名称。因此，利用刚才给出的定义，URL http://host/webAppPrefix/servlet/Test可用于http://host/webAppPrefix/servlet/moreservlets.TestServlet的场所。<br />
请记住：XML元素不仅是大小写敏感的，而且定义它们的次序也很重要。例如，web-app元素内所有servlet元素必须位于所有servlet- mapping元素（下一小节介绍）之前，而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素（如果有的话）之前。类似地，servlet 的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。<br />
例如，程序清单5-1给出了一个名为TestServlet的简单servlet，它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分，所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图 5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。</p>
<p>程序清单5-1 TestServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to illustrate servlet naming<br />
* and custom URLs.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* http://www.moreservlets.com/.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class TestServlet 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 uri = request.getRequestURI();<br />
out.println(ServletUtilities.headWithTitle("Test Servlet") +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;URI: " + uri + "&lt;/H2&gt;\n" +<br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}<br />
}</p>
<p><br />
程序清单5-2 web.xml（说明servlet名称的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- &#8230; --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- &#8230; --&gt;<br />
&lt;/web-app&gt;</p>
<p>3.2 定义定制的URL<br />
大多数服务器具有一个缺省的serlvet URL：<br />
http://host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用这个URL很方便，但是我们常常会希望另一个URL用于部署。例如，可能会需要一个出现在Web应用顶层的URL（如，http: //host/webAppPrefix/Anyname），并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外，对许多开发人员来说，顶层URL看上去比更长更麻烦的缺省URL更简短。<br />
事实上，有时需要使用定制的URL。比如，你可能想关闭缺省URL映射，以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL，那么你怎样访问servlet呢？这时只有使用定制的URL了。<br />
为了分配一个定制的URL，可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一个任意名称，可利用此名称引用相应的servlet；url-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必须以斜杠（/）起始。<br />
下面给出一个简单的web.xml摘录，它允许使用URL http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或<br />
http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意，仍然需要XML头、 DOCTYPE声明以及web-app封闭元素。此外，可回忆一下，XML元素出现地次序不是随意的。特别是，需要把所有servlet元素放在所有 servlet-mapping元素之前。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.TestServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
URL模式还可以包含通配符。例如，下面的小程序指示服务器发送所有以Web应用的URL前缀开始，以..asp结束的请求到名为BashMS的servlet。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;msUtils.ASPTranslator&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;BashMS&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/*.asp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
3.3 命名JSP页面<br />
因为JSP页面要转换成sevlet，自然希望就像命名servlet一样命名JSP页面。毕竟，JSP页面可能会从初始化参数、安全设置或定制的URL中受益，正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的，但存在一个关键的猜疑：即，你不知道JSP页面的实际类名（因为系统自己挑选这个名字）。因此，为了命名JSP页面，可将jsp-file元素替换为servlet-calss元素，如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Test&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
命名JSP页面的原因与命名servlet的原因完全相同：即为了提供一个与定制设置（如，初始化参数和安全设置）一起使用的名称，并且，以便能更改激活 JSP页面的URL（比方说，以便多个URL通过相同页面得以处理，或者从URL中去掉.jsp扩展名）。但是，在设置初始化参数时，应该注意，JSP页面是利用jspInit方法，而不是init方法读取初始化参数的。<br />
例如，程序清单5-3给出一个名为TestPage.jsp的简单JSP页面，它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName，然后将此注册名与http://host/webAppPrefix/UrlTest2/anything形式的URL相关联的web.xml文件（即，deployDemo/WEB-INF/web.xml）的一部分。</p>
<p>程序清单5-3 TestPage.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;<br />
&lt;TITLE&gt;<br />
JSP Test Page<br />
&lt;/TITLE&gt;<br />
&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;URI: &lt;%= request.getRequestURI() %&gt;&lt;/H2&gt;<br />
&lt;/BODY&gt;<br />
&lt;/HTML&gt;</p>
<p><br />
程序清单5-4 web.xml（说明JSP页命名的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/TestPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
4 禁止激活器servlet</p>
<p>对servlet或JSP页面建立定制URL的一个原因是，这样做可以注册从 init（servlet）或jspInit（JSP页面）方法中读取得初始化参数。但是，初始化参数只在是利用定制URL模式或注册名访问 servlet或JSP页面时可以使用，用缺省URL http://host/webAppPrefix/servlet/ServletName访问时不能使用。因此，你可能会希望关闭缺省URL，这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet，因为多数服务器具有一个用缺省的servlet URL注册的标准servlet，并激活缺省的URL应用的实际servlet。<br />
有两种禁止此缺省URL的主要方法：<br />
l 在每个Web应用中重新映射/servlet/模式。<br />
l 全局关闭激活器servlet。<br />
重要的是应该注意到，虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多，但重新映射可以用一种完全可移植的方式来完成。相反，全局禁止激活器servlet完全是针对具体机器的，事实上有的服务器（如ServletExec）没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。<br />
4.1 重新映射/servlet/URL模式<br />
在一个特定的Web应用中禁止以http://host/webAppPrefix/servlet/开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet，并使用前一节讨论的url-pattern元素将所有匹配请求转向该 servlet。只要简单地使用：<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
作为servlet-mapping元素中的模式即可。<br />
例如，程序清单5-5给出了将SorryServlet servlet（程序清单5-6）与所有以http://host/webAppPrefix/servlet/开头的URL相关联的部署描述符文件的一部分。</p>
<p>程序清单5-5 web.xml（说明JSP页命名的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Sorry&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.SorryServlet&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; Sorry &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
程序清单5-6 SorryServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to give error messages to<br />
* users who try to access default servlet URLs<br />
* (i.e., http://host/webAppPrefix/servlet/ServletName)<br />
* in Web applications that have disabled this<br />
* behavior.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* http://www.moreservlets.com/.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class SorryServlet 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 = "Invoker Servlet Disabled.";<br />
out.println(ServletUtilities.headWithTitle(title) +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;" + title + "&lt;/H2&gt;\n" +<br />
"Sorry, access to servlets by means of\n" +<br />
"URLs that begin with\n" +<br />
"http://host/webAppPrefix/servlet/\n" +<br />
"has been disabled.\n" + <br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}</p>
<p>public void doPost(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
doGet(request, response);<br />
}<br />
}</p>
<p><br />
4.2 全局禁止激活器：Tomcat<br />
Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法：<br />
1．禁止激活器： Tomcat 4<br />
Tomcat 4用与前面相同的方法关闭激活器servlet，即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件，而前面使用的是存放在每个Web应用的WEB-INF目录中的标准 web.xml文件。<br />
因此，为了在Tomcat 4中关闭激活器servlet，只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可，如下所示：<br />
&lt;!-- <br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;invoker&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
--&gt;<br />
再次提醒，应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的，此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。<br />
2．禁止激活器：Tomcat3<br />
在Apache Tomcat的版本3中，通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省 servlet URL。例如，下面是禁止使用缺省servlet URL的server.xml文件的一部分。<br />
&lt;!-- <br />
&lt;RequsetInterceptor <br />
className="org.apache.tomcat.request.InvokerInterceptor"<br />
debug="0" prefix="/servlet/" /&gt;<br />
--&gt;</p>
<p>5 初始化和预装载servlet与JSP页面</p>
<p>这里讨论控制servlet和JSP页面的启动行为的方法。特别是，说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。<br />
5.1 分配servlet初始化参数<br />
利用init-param元素向servlet提供初始化参数，init-param元素具有param-name和param-value子元素。例如，在下面的例子中，如果initServlet servlet是利用它的注册名（InitTest）访问的，它将能够从其方法中调用getServletConfig(). getInitParameter("param1")获得"Value 1"，调用getServletConfig().getInitParameter("param2")获得"2"。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;param1&lt;/param-name&gt;<br />
&lt;param-value&gt;value1&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;param2&lt;/param-name&gt;<br />
&lt;param-value&gt;2&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
在涉及初始化参数时，有几点需要注意：<br />
l 返回值。GetInitParameter的返回值总是一个String。因此，在前一个例子中，可对param2使用Integer.parseInt获得一个int。<br />
l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。<br />
l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此，在这个例子中，param1和 param2初始化参数将能够在使用URL http://host/webAppPrefix/servlet/InitTest时可用，但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet时不能使用。<br />
例如，程序清单5-7给出一个名为InitServlet的简单servlet，它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。<br />
程序清单5-7 InitServlet.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;</p>
<p>/** Simple servlet used to illustrate servlet<br />
* initialization parameters.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* http://www.moreservlets.com/.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class InitServlet extends HttpServlet {<br />
private String firstName, emailAddress;</p>
<p>public void init() {<br />
ServletConfig config = getServletConfig();<br />
firstName = config.getInitParameter("firstName");<br />
emailAddress = config.getInitParameter("emailAddress");<br />
}</p>
<p>public void doGet(HttpServletRequest request,<br />
HttpServletResponse response)<br />
throws ServletException, IOException {<br />
response.setContentType("text/html");<br />
PrintWriter out = response.getWriter();<br />
String uri = request.getRequestURI();<br />
out.println(ServletUtilities.headWithTitle("Init Servlet") +<br />
"&lt;BODY BGCOLOR=\"#FDF5E6\"&gt;\n" +<br />
"&lt;H2&gt;Init Parameters:&lt;/H2&gt;\n" +<br />
"&lt;UL&gt;\n" +<br />
"&lt;LI&gt;First name: " + firstName + "\n" +<br />
"&lt;LI&gt;Email address: " + emailAddress + "\n" +<br />
"&lt;/UL&gt;\n" + <br />
"&lt;/BODY&gt;&lt;/HTML&gt;");<br />
}<br />
}</p>
<p><br />
程序清单5-8 web.xml（说明初始化参数的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitTest&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;moreservlets.InitServlet&lt;/servlet-class&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;firstName&lt;/param-name&gt;<br />
&lt;param-value&gt;Larry&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />
&lt;param-value&gt;Ellison@Microsoft.com&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p>5.2 分配JSP初始化参数<br />
给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。<br />
1）使用jsp-file而不是servlet-class。因此，WEB-INF/web.xml文件的servlet元素如下所示：<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;...&lt;/param-name&gt;<br />
&lt;param-value&gt;...&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
...<br />
&lt;/servlet&gt;<br />
2) 几乎总是分配一个明确的URL模式。对servlet，一般相应地使用以http://host/webAppPrefix/servlet/开始的缺省URL。只需记住，使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如，在上面给出的例子中，可用URL http://host/webAppPrefix/servlet/PageName访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时，许多用户似乎不喜欢应用常规的servlet的URL。此外，如果 JSP页面位于服务器为其提供了目录清单的目录中（如，一个既没有index.html也没有index.jsp文件的目录），则用户可能会连接到此 JSP页面，单击它，从而意外地激活未初始化的页面。因此，好的办法是使用url-pattern（5.3节）将JSP页面的原URL与注册的 servlet名相关联。这样，客户机可使用JSP页面的普通名称，但仍然激活定制的版本。例如，给定来自项目1的servlet定义，可使用下面的 servlet-mapping定义：<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/RealPage.jsp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
3）JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此，使用JSP声明提供一个init方法是不合法的，必须制定jspInit方法。<br />
为了说明初始化JSP页面的过程，程序清单5-9给出了一个名为InitPage.jsp的JSP页面，它包含一个jspInit方法且放置于 deployDemo Web应用层次结构的顶层。一般，http://host/deployDemo/InitPage.jsp形式的URL将激活此页面的不具有初始化参数访问权的版本，从而将对firstName和emailAddress变量显示null。但是， web.xml文件（程序清单5-10）分配了一个注册名，然后将该注册名与URL模式/InitPage.jsp相关联。</p>
<p>程序清单5-9 InitPage.jsp<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<br />
&lt;HTML&gt;<br />
&lt;HEAD&gt;&lt;TITLE&gt;JSP Init Test&lt;/TITLE&gt;&lt;/HEAD&gt;<br />
&lt;BODY BGCOLOR="#FDF5E6"&gt;<br />
&lt;H2&gt;Init Parameters:&lt;/H2&gt;<br />
&lt;UL&gt;<br />
&lt;LI&gt;First name: &lt;%= firstName %&gt;<br />
&lt;LI&gt;Email address: &lt;%= emailAddress %&gt;<br />
&lt;/UL&gt;<br />
&lt;/BODY&gt;&lt;/HTML&gt;<br />
&lt;%!<br />
private String firstName, emailAddress;</p>
<p>public void jspInit() {<br />
ServletConfig config = getServletConfig();<br />
firstName = config.getInitParameter("firstName");<br />
emailAddress = config.getInitParameter("emailAddress");<br />
}<br />
%&gt;</p>
<p><br />
程序清单5-10 web.xml（说明JSP页面的init参数的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;InitPage&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/InitPage.jsp&lt;/jsp-file&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;firstName&lt;/param-name&gt;<br />
&lt;param-value&gt;Bill&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;emailAddress&lt;/param-name&gt;<br />
&lt;param-value&gt;gates@oracle.com&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt; <br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; InitPage&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/InitPage.jsp&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
5.3 提供应用范围内的初始化参数<br />
一般，对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是，在某些情形下，希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。<br />
可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素，如下所示：<br />
&lt;context-param&gt;<br />
&lt;param-name&gt;support-email&lt;/param-name&gt;<br />
&lt;param-value&gt;blackhole@mycompany.com&lt;/param-value&gt;<br />
&lt;/context-param&gt;<br />
可回忆一下，为了保证可移植性，web.xml内的元素必须以正确的次序声明。但这里应该注意，context-param元素必须出现任意与文档有关的元素（icon、display-name或description）之后及filter、filter-mapping、listener或 servlet元素之前。<br />
5.4 在服务器启动时装载servlet<br />
假如servlet或JSP页面有一个要花很长时间执行的init （servlet）或jspInit（JSP）方法。例如，假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下，在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此，可利用servlet的load-on- startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt; &#8230; &lt;/servlet-name&gt;<br />
&lt;servlet-class&gt; &#8230; &lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup/&gt;<br />
&lt;/servlet&gt;<br />
可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如，下面的servlet项（放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内）将指示服务器首先装载和初始化SearchServlet，然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的 servlet。<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Search&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;myPackage.SearchServlet&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&lt;/servlet&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;Results&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;/results/index.jsp&lt;/servlet-class&gt; &lt;!-- Or jsp-file --&gt;<br />
&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />
&lt;/servlet&gt;</p>
<p>6 声明过滤器</p>
<p>servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器，但为了使用与过滤器有关的元素，必须在web.xml中使用版本2.3的DTD。<br />
过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前，必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时，执行链中的下一个过滤器。如果没有其他过滤器，servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权，因此，它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出，过滤器可将响应对象包裹在一个替身对象（stand-in object）中，比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后，过滤器可检查缓冲区，如有必要，就对它进行修改，然后传送到客户机。<br />
例如，程序清单5-11帝国难以了一个简单的过滤器，只要访问相关的servlet或JSP页面，它就截取请求并在标准输出上打印一个报告（开发过程中在桌面系统上运行时，大多数服务器都可以使用这个过滤器）。</p>
<p>程序清单5-11 ReportFilter.java<br />
package moreservlets;</p>
<p>import java.io.*;<br />
import javax.servlet.*;<br />
import javax.servlet.http.*;<br />
import java.util.*;</p>
<p>/** Simple filter that prints a report on the standard output <br />
* whenever the associated servlet or JSP page is accessed.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* http://www.moreservlets.com/.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class ReportFilter implements Filter {<br />
public void doFilter(ServletRequest request,<br />
ServletResponse response,<br />
FilterChain chain)<br />
throws ServletException, IOException {<br />
HttpServletRequest req = (HttpServletRequest)request;<br />
System.out.println(req.getRemoteHost() +<br />
" tried to access " +<br />
req.getRequestURL() +<br />
" on " + new Date() + ".");<br />
chain.doFilter(request,response);<br />
}</p>
<p>public void init(FilterConfig config)<br />
throws ServletException {<br />
}</p>
<p>public void destroy() {}<br />
}</p>
<p>一旦建立了一个过滤器，可以在web.xml中利用filter元素以及filter-name（任意名称）、file-class（完全限定的类名）和（可选的）init-params子元素声明它。请注意，元素在web.xml的web-app元素中出现的次序不是任意的；允许服务器（但不是必需的）强制所需的次序，并且实际中有些服务器也是这样做的。但这里要注意，所有filter元素必须出现在任意filter-mapping元素之前， filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。<br />
例如，给定上述的ReportFilter类，可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter（位于moreservlets程序包中）相关联。<br />
&lt;filter&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />
&lt;/filter&gt;<br />
一旦命名了一个过滤器，可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。<br />
首先，可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名（此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明）关联。例如，下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName 的servlet或JSP页面，就运行名为Reporter的过滤器。<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;servlet-name&gt;SomeServletName&lt;/servlet-name&gt;<br />
&lt;/filter-mapping&gt;<br />
其次，可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如，相面的程序片段指示系统只要访问Web应用中的任意URL，就运行名为Reporter的过滤器。<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&lt;/filter-mapping&gt;<br />
例如，程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上，程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项，可看到下面的标准输出形式的调试报告（换行是为了容易阅读）。<br />
audit.irs.gov tried to access <br />
http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html<br />
on Tue Dec 25 13:12:29 EDT 2001.</p>
<p>程序清单5-12 Web.xml（说明filter用法的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;filter&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;filter-class&gt;moresevlets.ReportFilter&lt;/filter-class&gt;<br />
&lt;/filter&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;filter-mapping&gt;<br />
&lt;filter-name&gt;Reporter&lt;/filter-name&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;/filter-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;PageName&lt;/servlet-name&gt;<br />
&lt;jsp-file&gt;/RealPage.jsp&lt;/jsp-file&gt;<br />
&lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt; PageName &lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/UrlTest2/*&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
7 指定欢迎页</p>
<p>假如用户提供了一个像http: //host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的URL，会发生什么事情呢？用户能得到一个目录表？一个错误？还是标准文件的内容？如果得到标准文件内容，是 index.html、index.jsp、default.html、default.htm或别的什么东西呢？<br />
Welcome-file-list 元素及其辅助的welcome-file元素解决了这个模糊的问题。例如，下面的web.xml项指出，如果一个URL给出一个目录名但未给出文件名，服务器应该首先试用index.jsp，然后再试用index.html。如果两者都没有找到，则结果有赖于所用的服务器（如一个目录列表）。<br />
&lt;welcome-file-list&gt;<br />
&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />
&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;<br />
&lt;/welcome-file-list&gt;<br />
虽然许多服务器缺省遵循这种行为，但不一定必须这样。因此，明确地使用welcom-file-list保证可移植性是一种良好的习惯。</p>
<p>8 指定处理错误的页面</p>
<p>现在我了解到，你在开发servlet和JSP页面时从不会犯错误，而且你的所有页面是那样的清晰，一般的程序员都不会被它们的搞糊涂。但是，是人总会犯错误的，用户可能会提供不合规定的参数，使用不正确的URL或者不能提供必需的表单字段值。除此之外，其它开发人员可能不那么细心，他们应该有些工具来克服自己的不足。<br />
error-page元素就是用来克服这些问题的。它有两个可能的子元素，分别是：error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息，这两个属性分别是：javax.servlet.error.status_code和javax.servlet.error.message。<br />
可回忆一下，在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住，error-page出现在web.xml文件的末尾附近，servlet、servlet-name和welcome-file-list之后即可。</p>
<p>8.1 error-code元素<br />
为了更好地了解error-code元素的值，可考虑一下如果不正确地输入文件名，大多数站点会作出什么反映。这样做一般会出现一个404错误信息，它表示不能找到该文件，但几乎没提供更多有用的信息。另一方面，可以试一下在www.microsoft.com、www.ibm.com处或者特别是在www.bea.com处输出未知的文件名。这是会得出有用的消息，这些消息提供可选择的位置，以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上rm-error-page子元素）。由form-login-page给出的HTML表单必须具有一个j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。<br />
例如，程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令，并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。</p>
<p>程序清单5-19 web.xml（说明login-config的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;security-constraint&gt; ... &lt;/security-constraint&gt;<br />
&lt;login-config&gt;<br />
&lt;auth-method&gt; FORM &lt;/auth-method&gt;<br />
&lt;form-login-config&gt;<br />
&lt;form-login-page&gt;/login.jsp&lt;/form-login-page&gt;<br />
&lt;form-error-page&gt;/login-error.jsp&lt;/form-error-page&gt;<br />
&lt;/form-login-config&gt;<br />
&lt;/login-config&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
9.2 限制对Web资源的访问<br />
现在，可以指示服务器使用何种验证方法了。"了不起，"你说道，"除非我能指定一个来收到保护的 URL，否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在 web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素，分别是：web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。<br />
l web-resource-collection<br />
此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的 HTTP命令（GET、POST等，缺省为所有方法）的http-method元素和一个提供资料的可选description元素组成。例如，下面的 Web-resource-collection项（在security-constratint元素内）指出Web应用的proprietary目录中所有文档应该受到保护。<br />
&lt;security-constraint&gt;<br />
&lt;web-resource-coolection&gt;<br />
&lt;web-resource-name&gt;Proprietary&lt;/web-resource-name&gt;<br />
&lt;url-pattern&gt;/propritary/*&lt;/url-pattern&gt;<br />
&lt;/web-resource-coolection&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/security-constraint&gt;<br />
重要的是应该注意到，url-pattern仅适用于直接访问这些资源的客户机。特别是，它不适合于通过MVC体系结构利用 RequestDispatcher来访问的页面，或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如，servlet可利用MVC体系结构查找数据，把它放到bean中，发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面，而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是，这种不匀称的行为可能让开发人员放松警惕，使他们偶然对应受保护的资源提供不受限制的访问。 <br />
l auth-constraint<br />
尽管web-resource-collention元素质出了哪些URL应该受到保护，但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role- name元素，以及包含（可选）一个描述角色的description元素。例如，下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna（或两者）的用户具有指定资源的访问权。<br />
&lt;security-constraint&gt;<br />
&lt;web-resource-coolection&gt; ... &lt;/web-resource-coolection&gt;<br />
&lt;auth-constraint&gt;<br />
&lt;role-name&gt;administrator&lt;/role-name&gt;<br />
&lt;role-name&gt;kahuna&lt;/role-name&gt;<br />
&lt;/auth-constraint&gt;<br />
&lt;/security-constraint&gt;<br />
重要的是认识到，到此为止，这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令，完全有赖于具体的系统。<br />
例如，Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联，正如下面例子中所示，它指出用户joe（口令bigshot）和jane（口令enaj）属于administrator和kahuna角色。<br />
&lt;tomcat-users&gt;<br />
&lt;user name="joe" password="bigshot" roles="administrator,kahuna" /&gt;<br />
&lt;user name="jane" password="enaj" roles="kahuna" /&gt;<br />
&lt;/tomcat-users&gt;<br />
l user-data-constraint<br />
这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素（合法值为NONE、 INTEGRAL或CONFIDENTIAL），并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上（并且在未来的HTTP版本中），在 INTEGRAL和CONFIDENTIAL之间可能会有差别，但在当前实践中，他们都只是简单地要求用SSL。例如，下面指示服务器只允许对相关资源做 HTTPS连接：<br />
&lt;security-constraint&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;user-data-constraint&gt;<br />
&lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />
&lt;/user-data-constraint&gt;<br />
&lt;/security-constraint&gt;<br />
l display-name<br />
security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。<br />
9.3 分配角色名<br />
迄今为止，讨论已经集中到完全由容器（服务器）处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。<br />
例如，容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面，但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法，并据此修改访问。<br />
Servlet的 security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如，假如编写了一个调用 request.isUserInRole（"boss"）的servlet，但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。<br />
&lt;servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;security-role-ref&gt;<br />
&lt;role-name&gt;boss&lt;/role-name&gt; &lt;!-- New alias --&gt;<br />
&lt;role-link&gt;manager&lt;/role-link&gt; &lt;!-- Real name --&gt;<br />
&lt;/security-role-ref&gt;<br />
&lt;/servlet&gt;<br />
也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。</p>
<p>10 控制会话超时</p>
<p>如果某个会话在一定的时间内未被访问，服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法，则缺省的超时值由具体的服务器决定。但可利用session-config和session- timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟，因此，下面的例子设置缺省会话超时值为三个小时（180分钟）。<br />
&lt;session-config&gt;<br />
&lt;session-timeout&gt;180&lt;/session-timeout&gt;<br />
&lt;/session-config&gt;</p>
<p>11 Web应用的文档化</p>
<p>越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio（写此文时，已被Macromedia收购）以及IBM VisuaAge for Java等。<br />
大量的web.xml元素不仅是为服务器设计的，而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。<br />
可回忆一下，在web.xml内以适当地次序声明web-app子元素很重要。不过，这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。<br />
l icon<br />
icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像，用large-icon元素指定一幅32 x 32的图像。下面举一个例子： <br />
&lt;icon&gt;<br />
&lt;small-icon&gt;/images/small-book.gif&lt;/small-icon&gt;<br />
&lt;large-icon&gt;/images/tome.jpg&lt;/large-icon&gt;<br />
&lt;/icon&gt;<br />
l display-name<br />
display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。<br />
&lt;display-name&gt;Rare Books&lt;/display-name&gt;<br />
l description<br />
description元素提供解释性文本，如下所示：<br />
&lt;description&gt;<br />
This Web application represents the store developed for<br />
rare-books.com, an online bookstore specializing in rare<br />
and limited-edition books.<br />
&lt;/description&gt;</p>
<p>12 关联文件与MIME类型</p>
<p>服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如，将会自动给予名为mom.jpg的文件一个image/jpeg的MIME 类型。但是，假如你的Web应用具有几个不寻常的文件，你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素（具有 extension和mime-type子元素）可提供这种保证。例如，下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。<br />
&lt;mime-mapping&gt;<br />
&lt;extension&gt;foo&lt;/extension&gt;<br />
&lt;mime-type&gt;application/x-fubar&lt;/mime-type&gt;<br />
&lt;/mime-mapping&gt;<br />
或许，你的Web应用希望重载（override）标准的映射。例如，下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本（text/plain）而不是作为PostScript（application/postscript）。<br />
&lt;mime-mapping&gt;<br />
&lt;extension&gt;ps&lt;/extension&gt;<br />
&lt;mime-type&gt;application/postscript&lt;/mime-type&gt;<br />
&lt;/mime-mapping&gt;</p>
<p><br />
13 定位TLD</p>
<p>JSP taglib元素具有一个必要的uri属性，它给出一个TLD（Tag Library Descriptor）文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变，但我们希望避免更改所有现有JSP页面。此外，可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素：taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如，假如你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。现在，假如web.xml在web-app元素内包含下列内容。<br />
&lt;taglib&gt;<br />
&lt;taglib-uri&gt;/charts.tld&lt;/taglib-uri&gt;<br />
&lt;taglib-location&gt;<br />
/WEB-INF/tlds/chart-tags-1.3beta.tld<br />
&lt;/taglib-location&gt;<br />
&lt;/taglib&gt;<br />
给出这个说明后，JSP页面可通过下面的简化形式使用标签库。<br />
&lt;%@ taglib uri="/charts.tld" prefix="somePrefix" %&gt;</p>
<p>14 指定应用事件监听程序</p>
<p>应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。<br />
注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内，listener-class元素列出监听程序的完整的限定类名，如下所示：<br />
&lt;listener&gt;<br />
&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />
&lt;/listener&gt;<br />
虽然listener元素的结构很简单，但请不要忘记，必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外，因为应用生存期监听程序是serlvet规范的2.3版本中的新内容，所以必须使用 web.xml DTD的2.3版本，而不是2.2版本。<br />
例如，程序清单5-20给出一个名为ContextReporter的简单的监听程序，只要Web应用的Servlet-Context建立（如装载Web应用）或消除（如服务器关闭）时，它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。</p>
<p>程序清单5-20 ContextReporterjava<br />
package moreservlets;</p>
<p>import javax.servlet.*;<br />
import java.util.*;</p>
<p>/** Simple listener that prints a report on the standard output <br />
* when the ServletContext is created or destroyed.<br />
* &lt;P&gt;<br />
* Taken from More Servlets and JavaServer Pages<br />
* from Prentice Hall and Sun Microsystems Press,<br />
* http://www.moreservlets.com/.<br />
* &#169; 2002 Marty Hall; may be freely used or adapted.<br />
*/</p>
<p>public class ContextReporter implements ServletContextListener {<br />
public void contextInitialized(ServletContextEvent event) {<br />
System.out.println("Context created on " +<br />
new Date() + ".");<br />
}</p>
<p>public void contextDestroyed(ServletContextEvent event) {<br />
System.out.println("Context destroyed on " +<br />
new Date() + ".");<br />
}<br />
}</p>
<p><br />
程序清单5-21 web.xml（声明一个监听程序的摘录）<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE web-app<br />
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt;</p>
<p>&lt;web-app&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;filter-mapping&gt; &#8230; &lt;/filter-mapping&gt;<br />
&lt;listener&gt;<br />
&lt;listener-class&gt;package.ListenerClass&lt;/listener-class&gt;<br />
&lt;/listener&gt;<br />
&lt;servlet&gt; ... &lt;/servlet&gt;<br />
&lt;!-- ... --&gt;<br />
&lt;/web-app&gt;</p>
<p><br />
15 J2EE元素</p>
<p>本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍，详细内容可以参阅http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。<br />
l distributable<br />
distributable 元素指出，Web应用是以这样的方式编程的：即，支持集群的服务器可安全地在多个服务器上分布Web应用。例如，一个可分布的应用必须只使用 Serializable对象作为其HttpSession对象的属性，而且必须避免用实例变量（字段）来实现持续性。distributable元素直接出现在discription元素之后，并且不包含子元素或数据，它只是一个如下的标志。<br />
&lt;distributable /&gt;<br />
l resource-env-ref<br />
resource -env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素（一个相对于java:comp/env环境的JNDI名）以及一个resource-env-type元素（指定资源类型的完全限定的类），如下所示：<br />
&lt;resource-env-ref&gt;<br />
&lt;resource-env-ref-name&gt;<br />
jms/StockQueue<br />
&lt;/resource-env-ref-name&gt;<br />
&lt;resource-env-ref-type&gt;<br />
javax.jms.Queue<br />
&lt;/resource-env-ref-type&gt;<br />
&lt;/resource-env-ref&gt;<br />
l env-entry<br />
env -entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素（一个相对于java: comp/env环境JNDI名）、一个env-entry-value元素（项值）以及一个env-entry-type元素（java.lang程序包中一个类型的完全限定类名，java.lang.Boolean、java.lang.String等）组成。下面是一个例子：<br />
&lt;env-entry&gt;<br />
&lt;env-entry-name&gt;minAmout&lt;/env-entry-name&gt;<br />
&lt;env-entry-value&gt;100.00&lt;/env-entry-value&gt;<br />
&lt;env-entry-type&gt;minAmout&lt;/env-entry-type&gt;<br />
&lt;/env-entry&gt;<br />
l ejb-ref<br />
ejb -ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素（相对于java: comp/env的EJB应用）、一个ejb-ref-type元素（bean的类型，Entity或Session）、一个home元素（bean的主目录接口的完全限定名）、一个remote元素（bean的远程接口的完全限定名）以及一个可选的ejb-link元素（当前bean链接的另一个 bean的名称）组成。<br />
l ejb-local-ref<br />
ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外，此元素具有与ejb-ref元素相同的属性并以相同的方式使用</p>
<img src ="http://www.blogjava.net/cxh8318/aggbug/148502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-09-27 09:12 <a href="http://www.blogjava.net/cxh8318/archive/2007/09/27/148502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>word导出</title><link>http://www.blogjava.net/cxh8318/archive/2007/08/27/139831.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Mon, 27 Aug 2007 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/08/27/139831.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/139831.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/08/27/139831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/139831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/139831.html</trackback:ping><description><![CDATA[//指定页面区域内容导入Word<br>&nbsp;function AllAreaWord()<br>&nbsp;{<br>&nbsp; var oWD = new ActiveXObject("Word.Application");<br>&nbsp; var oDC = oWD.Documents.Add("",0,1);<br>&nbsp; var oRange =oDC.Range(0,1);<br>&nbsp; var sel = document.body.createTextRange();<br>&nbsp; sel.moveToElementText(PrintA);<br>&nbsp; sel.select();<br>&nbsp; sel.execCommand("Copy");<br>&nbsp; oRange.Paste();<br>&nbsp; oWD.Application.Visible = true;<br>&nbsp; //window.close();<br>&nbsp;}<br><br><br>其中PrintA为table表单的id
<img src ="http://www.blogjava.net/cxh8318/aggbug/139831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-08-27 11:31 <a href="http://www.blogjava.net/cxh8318/archive/2007/08/27/139831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>excel导出</title><link>http://www.blogjava.net/cxh8318/archive/2007/08/27/139751.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Mon, 27 Aug 2007 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/08/27/139751.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/139751.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/08/27/139751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/139751.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/139751.html</trackback:ping><description><![CDATA[function AllAreaExcel() <br>{ <br>var oXL = new ActiveXObject("Excel.Application"); <br>var oWB = oXL.Workbooks.Add(); <br>var oSheet = oWB.ActiveSheet; <br>var sel=document.body.createTextRange(); <br>sel.moveToElementText(bb); <br>sel.select(); <br>sel.execCommand("Copy"); <br>oSheet.Paste(); <br>oXL.Visible = true; <br>} <br>function CellAreaExcel() <br>{ <br>var oXL = new ActiveXObject("Excel.Application"); <br>var oWB = oXL.Workbooks.Add(); <br>var oSheet = oWB.ActiveSheet; <br>var Lenr = bb.rows.length; <br>for (i=0;i&lt;Lenr;i++) <br>{ <br>var Lenc = bb.rows(i).cells.length; <br>for (j=0;j&lt;Lenc;j++) <br>{ <br>oSheet.Cells(i+1,j+1).value = bb.rows(i).cells(j).innerText; <br>} <br>} <br>oXL.Visible = true; <br>} <br><br><br>要导出时调用以上JS就可以了，其中bb为table表单的id。 <br>还有要对浏览器进行设置：工具-internet选项-安全-自定义级别，对没有标记为安全的ActiveX控件&#8230;&#8230;这一项启用。 <br>这样就OK了。 
<img src ="http://www.blogjava.net/cxh8318/aggbug/139751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-08-27 09:54 <a href="http://www.blogjava.net/cxh8318/archive/2007/08/27/139751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自动刷新页面</title><link>http://www.blogjava.net/cxh8318/archive/2007/08/26/139467.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Sun, 26 Aug 2007 05:59:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/08/26/139467.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/139467.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/08/26/139467.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/139467.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/139467.html</trackback:ping><description><![CDATA[<p><br>&lt;script&gt;<br>&lt;!-- <br>var limit="0:600"<br>if (document.images){<br>var parselimit=limit.split(":")<br>parselimit=parselimit[0]*60+parselimit[1]*1<br>}<br>function beginrefresh(){<br>if (!document.images)<br>return<br>if (parselimit==1)<br>window.location.reload()<br>else{ <br>parselimit-=1<br>curmin=Math.floor(parselimit/60)<br>cursec=parselimit%60<br>if (curmin!=0)<br>curtime=curmin+"分"+cursec+"秒后刷新滚动公告信息！"<br>else<br>curtime=cursec+"秒后刷新滚动公告信息！"<br>window.status=curtime<br>setTimeout("beginrefresh()",1000)<br>}<br>}<br>window.onload=beginrefresh<br>//--&gt;<br>&lt;/script&gt;<br>以上代码加入HEAD区即可。<br>说明：有人说，我可以使用&lt;meta&nbsp;http-equiv="refresh"&gt;来刷新当前页面，为什么要用这个脚本呢？是的，的确是这样。但是这个脚本可以在状态栏显示剩余的时间。不管怎样，随您的便。其实这个脚本可以作出其它许多花样的。如果将window.location.reload()改成window.location.href="http://www.yahoo.com"等地址，可以在规定时间到来后指向任意的页面。<br><br>简单的做法：<br><br>&lt;meta http-equiv="refresh" content="20"&gt;<br>或者<br>&nbsp;&lt;meta http-equiv="refresh" content="20;url=http://kingsnet.126.com"&gt;</p>
<img src ="http://www.blogjava.net/cxh8318/aggbug/139467.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-08-26 13:59 <a href="http://www.blogjava.net/cxh8318/archive/2007/08/26/139467.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>注册后即可拥有免费的网络优盘空间</title><link>http://www.blogjava.net/cxh8318/archive/2007/07/17/130811.html</link><dc:creator>冰江独行</dc:creator><author>冰江独行</author><pubDate>Tue, 17 Jul 2007 05:52:00 GMT</pubDate><guid>http://www.blogjava.net/cxh8318/archive/2007/07/17/130811.html</guid><wfw:comment>http://www.blogjava.net/cxh8318/comments/130811.html</wfw:comment><comments>http://www.blogjava.net/cxh8318/archive/2007/07/17/130811.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/cxh8318/comments/commentRss/130811.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cxh8318/services/trackbacks/130811.html</trackback:ping><description><![CDATA[网上找的，个人感觉用着不错，跟大家共享下。<a href="http://www.mikebox.com/register.php?id=216448"><br>http://www.mikebox.com/register.php?id=216448</a><br>免费的网络优盘<br>大家可以注册使用看看
<img src ="http://www.blogjava.net/cxh8318/aggbug/130811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cxh8318/" target="_blank">冰江独行</a> 2007-07-17 13:52 <a href="http://www.blogjava.net/cxh8318/archive/2007/07/17/130811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>