﻿<?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/PHP</title><link>http://www.blogjava.net/jelver/category/7674.html</link><description>每天进步一点点</description><language>zh-cn</language><lastBuildDate>Wed, 16 Mar 2011 16:03:34 GMT</lastBuildDate><pubDate>Wed, 16 Mar 2011 16:03:34 GMT</pubDate><ttl>60</ttl><item><title>深入解析form标签</title><link>http://www.blogjava.net/jelver/articles/346287.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Tue, 15 Mar 2011 02:04:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/346287.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/346287.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/346287.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/346287.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/346287.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: http://www.nowamagic.net/html/html_FormAnalysis.phpCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->在Javascript中，页面上的每一对&lt;form&gt;标记都解析...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/346287.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/346287.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2011-03-15 10:04 <a href="http://www.blogjava.net/jelver/articles/346287.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaScript prototype原型对象</title><link>http://www.blogjava.net/jelver/articles/345038.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 24 Feb 2011 02:05:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/345038.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/345038.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/345038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/345038.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/345038.html</trackback:ping><description><![CDATA[原文<a href="http://www.xiaoxiaozi.com/2009/06/29/995/"> http://www.xiaoxiaozi.com/2009/06/29/995/</a><br />
<br />
最近折腾MSDP的东西，js的东西灰常之多，之前没有很好学，现在来还账 :=)<br />
<br />
<p>在之前的<a href="http://www.xiaoxiaozi.com/2009/06/23/934/">《javascript 构造函数和方法》</a>一文中，我们知道，用构造函数把方法赋予其实例化的对象这样的效率实在让人不敢恭维。如果那样的话，构造函数创建的每一个每一个对象都会有相同的方法属性的副本。</p>
<blockquote>
<p>在JavaScript中，有一种更为有效的声明方法、常量及其他能被类所有对象共享的属性的方式，那就是prototype原型</p>
</blockquote>
<p><br />
一个对象的原型，是由创建并初始化该对象的构造函数定义的。在JavaScript中，所有的函数都具有prototype属性，它引用了一个对象。虽然
原型对象在初始化时是空的，但是你在其中定义的任何属性都会被该构造函数创建的所有对象所继承。这也是JavaScript继承的实现原理。</p>
<p>在学习prototype(原型)的时候，我们首先要搞明白这样两个规则：<br />
<font style="margin-left: 20px;" color="#0080c0">1. 使用原型可以大量减少每个对象对内存的需求量，因为对象可以继承许多属性。</font><br />
<font style="margin-left: 20px;" color="#0080c0">2. 即使属性在对象被创建之后才被添加至原型中，对象也能够继承这些属性。</font></p>
<p>我们需要了解一下，原型里定义的属性，不是简单的被实例化的对象复制过去的，只是看起来好像是这些对象的属性了，这是很重要的概念。</p>
<p>看一个实例来理解一下：</p>
<div javascript="" dawn="" style="overflow: auto; white-space: nowrap; width: 600px;">
<div codecolorer="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //创建一个构造函数 &#8220;用户&#8221;<br />
&nbsp; &nbsp; &nbsp; &nbsp; function User(name)<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.name = name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //实例化一个用户——&gt;老张<br />
&nbsp; &nbsp; &nbsp; &nbsp; var 老张 = new User('老张');<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //弹窗显示老张的名字<br />
&nbsp; &nbsp; &nbsp; &nbsp; alert(老张.name);<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //定义原型，注意这里对象&#8220;老张&#8221;已经被实例化了<br />
&nbsp; &nbsp; &nbsp; &nbsp; User.prototype.favchannel = 'CCAV';<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //弹窗显示老张最喜欢的电视台<br />
&nbsp; &nbsp; &nbsp; &nbsp; alert(老张.favchannel);</div>
</div>
<p>虽然&#8220;老张&#8221;这个对象已经被实例化出来了，不过其仍然会继承原型定义的&#8220;最喜欢的频道&#8221;这个属性</p>
<p><strong><font color="red">注意，只有读属性的时候才会使用prototype，写属性的时候是不会用到prototype的。</font></strong></p>
<p>首先我们来详细了解一下，什么时候会用到prototype。当读一个对象的属性时，其寻找这个属性的顺序是怎样的呢？例如：读取老张的favchannel属性：</p>
<blockquote>
<p>
第一步：去问老张，你有没有啥喜欢的频道啊？ 老张如果有的话就是：嗯呐，我喜欢CCAV，如果没有就说我不知道啊，问我老大吧，他说我喜欢啥，俺就喜欢啥。</p>
<p>第二步：问老张的构造函数的原型，如果原型内定义了，就会告诉你，我的小弟都喜欢CCAV，除非有的非常有个性可能喜欢某岛国的小电影频道。如果原型内也没定义，就会告诉你，去找我们经理，经理知道。</p>
<p>第三步：去问经理，即Object的prototype，如果经理说他们一般都喜欢CCAV，那么就是CCAV，如果经理也不知道，那就返回undefined。
</p>
</blockquote>
<p>所以顺序是 老张——&gt;User prototype——&gt;Object prototype</p>
<p>那么为啥写属性的时候不用prototype呢？举个例子你就清楚了</p>
<div javascript="" dawn="" style="overflow: auto; white-space: nowrap; width: 600px;">
<div codecolorer="">&nbsp; &nbsp; &nbsp; &nbsp; //老李是一个新的用户<br />
&nbsp; &nbsp; &nbsp; &nbsp; var 老李 = new User('老李');<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //老李喜欢小电影<br />
&nbsp; &nbsp; &nbsp; &nbsp; 老李.favchannel = 'JAPANTV';<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; //弹窗显示JAPANTV<br />
&nbsp; &nbsp; &nbsp; &nbsp; alert(老李.favchannel);<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; //弹窗显示老张还是中意CCAV<br />
&nbsp; &nbsp; &nbsp; &nbsp; alert(老张.favchannel);</div>
</div>
<p>如果，写属性也去改prototype的时候，那改变其中任何一个对象的属性，比如老李现在得意JAPANTV，如果也去改原型的话，老张也只能得意JAPANTV了。。</p>
<p><strong><font color="#0080c0"> 上面我们已经了解了，属性的继承(从原型处继承)只发生在读属性时。另外，原型对象的属性被一个类的所有对象共享，所以通常只用它们来定义类中所有对象相同的属性。例如我们可以定义&#8220;圆&#8221;这个类的PI值为1.34。</font></strong></p>
<br />
<img src ="http://www.blogjava.net/jelver/aggbug/345038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2011-02-24 10:05 <a href="http://www.blogjava.net/jelver/articles/345038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IE和FireFox下通用的Javascript模拟回车－－点击事件(转)</title><link>http://www.blogjava.net/jelver/articles/242933.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 27 Nov 2008 02:14:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/242933.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/242933.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/242933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/242933.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/242933.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">最近做东西发现用户在网页输入框里面按回车的行为是不固定的。。。<br />
特别是在网页有多个表单的时候<br />
于是搜了一把找了一个模拟点击的js，经测试能在firefox和ie上运行<br />
</span><span style="color: #0000ff;">function</span><span style="color: #000000;">&nbsp;doClick(linkId,&nbsp;e){&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(e.keyCode&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">13</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;fireOnThis&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;document.getElementById(linkId)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(document.createEvent)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;evObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;document.createEvent('MouseEvents')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evObj.initEvent(&nbsp;'click',&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fireOnThis.dispatchEvent(evObj)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(document.createEventObject)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fireOnThis.fireEvent('onclick')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
其中e是event，内置对象，linkId是模拟被点击的对象id<br />
比如</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">INPUT&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">test</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;onkeypress</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">doClick(</span><span style="color: #000000;">"</span><span style="color: #000000;">buttonId</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;event)</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
这样的话就能让用户按回车来提交表单了～<br />
<br />
<br />
opera可以再改一下&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">img&nbsp;&nbsp;&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">a</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;src</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">/a.jpg</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;onclick</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">alert('a');</span><span style="color: #000000;">"</span><span style="color: #000000;">/&gt;&lt;</span><span style="color: #000000;">div&nbsp;&nbsp;&nbsp;onclick</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">clickObj('a')</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">click&nbsp;&nbsp;&nbsp;me</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">div</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">script&nbsp;&nbsp;&nbsp;language</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">javascript</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #000000;">&lt;!--</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">function</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;clickObj(o){&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;o&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;document.getElementById(o);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;&nbsp;&nbsp;document.all&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">typeof</span><span style="color: #000000;">(&nbsp;&nbsp;&nbsp;document.all&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">object</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;)&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">IE&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;o.fireEvent(</span><span style="color: #000000;">"</span><span style="color: #000000;">onclick</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;e&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;document.createEvent('MouseEvent');&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;e.initEvent('click',</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;o.dispatchEvent(e);&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">--&gt;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">script</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;<br />
<br />
</span></div>
<img src ="http://www.blogjava.net/jelver/aggbug/242933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-11-27 10:14 <a href="http://www.blogjava.net/jelver/articles/242933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Js表单常用处理方法</title><link>http://www.blogjava.net/jelver/articles/231312.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Fri, 26 Sep 2008 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/231312.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/231312.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/231312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/231312.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/231312.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JavaScript表单处理[JavaScript高级程序设计]&nbsp;//表单var&nbsp;FormUtil&nbsp;=&nbsp;new&nbsp;Object();//表单中的文本框var&nbsp;TextUtil&nbsp;=&nbsp;new&nbsp;Object();//表单中的列表框和组合框&lt;select&gt;var&nbsp;ListU...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/231312.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/231312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-09-26 15:56 <a href="http://www.blogjava.net/jelver/articles/231312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>控制textarea文本长度,限制输入字数(带统计)的特效[zhuan]</title><link>http://www.blogjava.net/jelver/articles/230830.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 24 Sep 2008 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/230830.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/230830.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/230830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/230830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/230830.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &lt;script&gt; function&nbsp;getStringUTFLength(str)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;value&nbsp;=&nbsp;str.replace(/[^\x00-\xff]/g,"&nbsp;&nbsp;"); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;va...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/230830.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/230830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-09-24 11:03 <a href="http://www.blogjava.net/jelver/articles/230830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>也谈一下文件上传  </title><link>http://www.blogjava.net/jelver/articles/201722.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Tue, 20 May 2008 10:28:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/201722.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/201722.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/201722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/201722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/201722.html</trackback:ping><description><![CDATA[也谈一下文件上传 &nbsp; &nbsp; &nbsp; &nbsp; moqiong（原作）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp; 在这里看到很多讨论文件上传的文章,觉得各有利敝,有些只限于上传文件,而不能同时取得文本字段值,尤其是上传多个文件比较少,现本人做这个上传文件的类最多可支持上传255个文件,同时可取得文本字段值,请各位高手指正. &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; 文件上传类:MoqUploadBean.java &nbsp; &nbsp; <br />
&nbsp; package &nbsp; net.moq.www; &nbsp; <br />
&nbsp; import &nbsp; java.io.*; &nbsp; <br />
&nbsp; import &nbsp; java.util.*; &nbsp; <br />
&nbsp; import &nbsp; javax.servlet.*; &nbsp; <br />
&nbsp; import &nbsp; javax.servlet.http.*; &nbsp; <br />
&nbsp; /** &nbsp; <br />
&nbsp; &nbsp; * &nbsp; <br />
&nbsp; &nbsp; * &nbsp; Title: &nbsp; 文件上传类 &nbsp; <br />
&nbsp; &nbsp; * &nbsp; Description: &nbsp; 既能对文件进行上传,又能取得输入框的值,最多可同时上传255个文件 &nbsp; <br />
&nbsp; &nbsp; * &nbsp; Copyright: &nbsp; Copyright &nbsp; (c) &nbsp; 2002 &nbsp; <br />
&nbsp; &nbsp; * &nbsp; Company: &nbsp; Tekson &nbsp; <br />
&nbsp; &nbsp; * &nbsp; @author &nbsp; 莫琼 &nbsp; <br />
&nbsp; &nbsp; * &nbsp; @version &nbsp; 1.0 &nbsp; <br />
&nbsp; &nbsp; */ &nbsp; <br />
&nbsp; public &nbsp; class &nbsp; MoqUploadBean &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; sourceFile &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //源文件名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; suffix &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //文件后缀名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String &nbsp; canSuffix &nbsp; = &nbsp; ".gif.jpg.jpeg.png"; &nbsp; &nbsp; &nbsp; &nbsp; //可上传的文件后缀名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String &nbsp; objectPath &nbsp; = &nbsp; "c:/"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //目标文件目录 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; objectFileName &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; //目标文件名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; ServletInputStream &nbsp; sis &nbsp; = &nbsp; null; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //输入流 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; String[] &nbsp; description &nbsp; = &nbsp; new &nbsp; String[255]; &nbsp; &nbsp; &nbsp; &nbsp; //描述状态 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; long &nbsp; size &nbsp; = &nbsp; 100 &nbsp; * &nbsp; 1024; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //限制大小 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; int &nbsp; count &nbsp; = &nbsp; 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //已传输文件数目 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; byte[] &nbsp; b &nbsp; = &nbsp; new &nbsp; byte[4096]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //字节流存放数组 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; boolean &nbsp; successful &nbsp; = &nbsp; true; &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; Hashtable &nbsp; fields &nbsp; = &nbsp; new &nbsp; Hashtable(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; MoqUploadBean() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //设置上传文件的后缀名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSuffix(String &nbsp; canSuffix) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.canSuffix &nbsp; = &nbsp; canSuffix; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //设置文件保存路径 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setObjectPath(String &nbsp; objectPath) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.objectPath &nbsp; = &nbsp; objectPath; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //设置文件保存路径 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSize(long &nbsp; maxSize) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.size &nbsp; = &nbsp; maxSize; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //文件上传处理程序 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; void &nbsp; setSourceFile(HttpServletRequest &nbsp; request) &nbsp; throws &nbsp; IOException &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis &nbsp; = &nbsp; request.getInputStream(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; a &nbsp; = &nbsp; 0; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; k &nbsp; = &nbsp; 0; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; s &nbsp; = &nbsp; ""; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("filename=\"")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; 取得文件数据 &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; s.substring(k &nbsp; + &nbsp; 10); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k &nbsp; = &nbsp; s.indexOf("\""); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; s.substring(0, &nbsp; k); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sourceFile[count] &nbsp; = &nbsp; s; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k &nbsp; = &nbsp; s.lastIndexOf("."); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suffix[count] &nbsp; = &nbsp; s.substring(k &nbsp; + &nbsp; 1); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (canTransfer(count)) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transferFile(count); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ++count; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; else &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("name=\"")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; 普通表单输入元素，获取输入元素名字 &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; fieldName &nbsp; = &nbsp; s.substring(k+6, &nbsp; s.length()-3); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringBuffer &nbsp; fieldValue &nbsp; = &nbsp; new &nbsp; StringBuffer(b.length); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a-2); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (b[0] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[1] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[2] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[3] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[4] &nbsp; == &nbsp; 45)) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; else &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldValue.append(s); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fields.put(fieldName, &nbsp; fieldValue.toString()); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (!successful) &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得表单元素值 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; getFieldValue(String &nbsp; fieldName) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (fields &nbsp; == &nbsp; null &nbsp; || &nbsp; fieldName &nbsp; == &nbsp; null) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; null; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; (String) &nbsp; fields.get(fieldName); &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得上传文件数 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; int &nbsp; getCount() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; count; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得目标路径 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; String &nbsp; getObjectPath() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; objectPath; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得源文件名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getSourceFile() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; sourceFile; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得目标文件名 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getObjectFileName() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; objectFileName; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //取得上传状态描述 &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; String[] &nbsp; getDescription() &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; description; &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //判断上传文件的类型 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; boolean &nbsp; canTransfer(int &nbsp; i) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; suffix[i] &nbsp; = &nbsp; suffix[i].toLowerCase(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //这个是用来传图片的，各位可以把后缀名改掉或者不要这个条件 &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (sourceFile[i].equals("") &nbsp; || &nbsp; (!(canSuffix.indexOf("."+suffix[i])&gt;=0))) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[i] &nbsp; = &nbsp; "ERR: &nbsp; File &nbsp; suffix &nbsp; is &nbsp; wrong."; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; false; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &nbsp; true; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; //上传文件转换 &nbsp; <br />
&nbsp; &nbsp; &nbsp; private &nbsp; void &nbsp; transferFile(int &nbsp; i) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; x &nbsp; = &nbsp; Long.toString(new &nbsp; java.util.Date().getTime()); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; objectFileName[i] &nbsp; = &nbsp; x &nbsp; + &nbsp; "." &nbsp; + &nbsp; suffix[i]; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FileOutputStream &nbsp; out &nbsp; = &nbsp; new &nbsp; FileOutputStream(objectPath &nbsp; + &nbsp; objectFileName[i]); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; a &nbsp; = &nbsp; 0; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; k &nbsp; = &nbsp; 0; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long &nbsp; hastransfered &nbsp; = &nbsp; 0; &nbsp; //标示已经传输的字节数 &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String &nbsp; s &nbsp; = &nbsp; ""; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (k &nbsp; = &nbsp; s.indexOf("Content-Type:")) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while &nbsp; ( &nbsp; (a &nbsp; = &nbsp; sis.readLine(b, &nbsp; 0, &nbsp; b.length)) &nbsp; != &nbsp; -1) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s &nbsp; = &nbsp; new &nbsp; String(b, &nbsp; 0, &nbsp; a); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; ( &nbsp; (b[0] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[1] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[2] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[3] &nbsp; == &nbsp; 45) &nbsp; &amp;&amp; &nbsp; (b[4] &nbsp; == &nbsp; 45)) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.write(b, &nbsp; 0, &nbsp; a); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hastransfered &nbsp; += &nbsp; a; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (hastransfered &nbsp; &gt;= &nbsp; size) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[count] &nbsp; = &nbsp; "ERR: &nbsp; The &nbsp; file &nbsp; " &nbsp; + &nbsp; sourceFile[count] &nbsp; + &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " &nbsp; is &nbsp; too &nbsp; large &nbsp; to &nbsp; transfer. &nbsp; The &nbsp; whole &nbsp; process &nbsp; is &nbsp; interrupted."; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; successful &nbsp; = &nbsp; false; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (successful) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[count] &nbsp; = &nbsp; "Right: &nbsp; The &nbsp; file &nbsp; " &nbsp; + &nbsp; sourceFile[count] &nbsp; + &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; " &nbsp; has &nbsp; been &nbsp; transfered &nbsp; successfully."; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.close(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &nbsp; (!successful) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sis.close(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; File &nbsp; tmp &nbsp; = &nbsp; new &nbsp; File(objectPath &nbsp; + &nbsp; objectFileName[count]); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp.delete(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch &nbsp; (IOException &nbsp; ioe) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description[i] &nbsp; = &nbsp; ioe.toString(); &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; &nbsp; &nbsp; public &nbsp; static &nbsp; void &nbsp; main(String[] &nbsp; args) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Test &nbsp; OK"); &nbsp; <br />
&nbsp; &nbsp; &nbsp; } &nbsp; <br />
&nbsp; } &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; 文件上传调用:MoqUpload.jsp &nbsp; <br />
&nbsp; 〈%@ &nbsp; page &nbsp; contentType="text/html; &nbsp; charset=GB2312" &nbsp; %&gt; &nbsp; <br />
&nbsp; 〈html&gt; &nbsp; <br />
&nbsp; 〈head&gt; &nbsp; <br />
&nbsp; 〈title&gt;文件上载〈/title&gt; &nbsp; <br />
&nbsp; 〈/head&gt; &nbsp; <br />
&nbsp; 〈body&gt; &nbsp; <br />
&nbsp; 〈form &nbsp; action="MoqUploadSubmit.jsp" &nbsp; enctype="MULTIPART/FORM-DATA" &nbsp; method="post"&gt; &nbsp; <br />
&nbsp; 作者姓名:〈input &nbsp; type="text" &nbsp; name="Author" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 公司名称:〈input &nbsp; type="text" &nbsp; name="Company" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 文件描述:〈input &nbsp; type="text" &nbsp; name="Comment" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 选择文件1:〈input &nbsp; type="file" &nbsp; name="filename1" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 选择文件2:〈input &nbsp; type="file" &nbsp; name="filename2" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 选择文件3:〈input &nbsp; type="file" &nbsp; name="filename3" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 选择文件4:〈input &nbsp; type="file" &nbsp; name="filename4" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈br &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈input &nbsp; type="submit" &nbsp; value="上载" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈/form&gt; &nbsp; <br />
&nbsp; 〈/body&gt; &nbsp; <br />
&nbsp; 〈/html&gt; &nbsp; <br />
&nbsp; &nbsp; <br />
&nbsp; 文件上传提交:MoqUploadSubmit.jsp &nbsp; <br />
&nbsp; 〈%@ &nbsp; page &nbsp; contentType="text/html;charset=gb2312"%&gt; &nbsp; <br />
&nbsp; 〈jsp:useBean &nbsp; id="fileBean" &nbsp; scope="page" &nbsp; class="net.moq.www.MoqUploadBean" &nbsp; /&gt; &nbsp; <br />
&nbsp; 〈% &nbsp; <br />
&nbsp; fileBean.setObjectPath("D:\\Temp\\"); &nbsp; <br />
&nbsp; fileBean.setSize(10000*1024); &nbsp; <br />
&nbsp; fileBean.setSuffix(".gif.jpg.png.jpge.html.htm"); &nbsp; <br />
&nbsp; fileBean.setSourceFile(request); &nbsp; <br />
&nbsp; String &nbsp; [] &nbsp; saSourceFile &nbsp; = &nbsp; fileBean.getSourceFile(); &nbsp; <br />
&nbsp; String &nbsp; [] &nbsp; saObjectFile &nbsp; = &nbsp; fileBean.getObjectFileName(); &nbsp; <br />
&nbsp; String &nbsp; [] &nbsp; saDescription &nbsp; = &nbsp; fileBean.getDescription(); &nbsp; <br />
&nbsp; int &nbsp; iCount &nbsp; = &nbsp; fileBean.getCount(); &nbsp; <br />
&nbsp; String &nbsp; sObjectPath &nbsp; = &nbsp; fileBean.getObjectPath(); &nbsp; <br />
&nbsp; for(int &nbsp; i=0;i〈iCount;i++) &nbsp; { &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;源始文件:"); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println(saSourceFile[i]); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;目标文件:"); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println(sObjectPath+saObjectFile[i]); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;上传说明:"); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println(saDescription[i]); &nbsp; <br />
&nbsp; &nbsp; &nbsp; out.println("〈br&gt;"); &nbsp; <br />
&nbsp; } &nbsp; <br />
&nbsp; out.println("〈br&gt;作者:" &nbsp; + &nbsp; fileBean.getFieldValue("Author")); &nbsp; <br />
&nbsp; out.println("〈br&gt;公司:" &nbsp; + &nbsp; fileBean.getFieldValue("Company")); &nbsp; <br />
&nbsp; out.println("〈br&gt;说明:" &nbsp; + &nbsp; fileBean.getFieldValue("Comment")); &nbsp; <br />
&nbsp; %&gt;&nbsp;&nbsp;
<img src ="http://www.blogjava.net/jelver/aggbug/201722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-05-20 18:28 <a href="http://www.blogjava.net/jelver/articles/201722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>说说大型高并发高负载网站的系统架构</title><link>http://www.blogjava.net/jelver/articles/191621.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 09 Apr 2008 01:01:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/191621.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/191621.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/191621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/191621.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/191621.html</trackback:ping><description><![CDATA[<p>转载请保留出处：俊麟 Michael&#8217;s blog (http://www.toplee.com/blog/?p=71)<br />
Trackback Url : <a href="http://www.toplee.com/blog/wp-trackback.php?p=71">http://www.toplee.com/blog/wp-trackback.php?p=71</a></p>
<p>　　我在CERNET做过拨号接入平台的搭建，而后在Yahoo&amp;3721从事过搜索引擎前端开发，又在MOP处理过大型社区猫扑大杂烩的架构升级等工作，同时自己接触和开发过不少大中型网站的模块，因此在大型网站应对高负载和并发的解决方案上有一些积累和经验，可以和大家一起探讨一下。</p>
<p><br />
　　一个小型的网站，比如个人网站，可以使用最简单的html静态页面就实现了，配合一些图片达到美化效果，所有的页面均存放在一个目录下，这样的网站对系统架构、性能的要求都很简单，随着互联网业务的不断丰富，网站相关的技术经过这些年的发展，已经细分到很细的方方面面，尤其对于大型网站来说，所采用的技术更是涉及面非常广，从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求，已经不是原来简单的html静态网站所能比拟的。</p>
<p>　　大型网站，比如门户网站。在面对大量用户访问、高并发请求方面，基本的解决方案集中在这样几个环节：使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面，还没法根本解决大型网站面临的高负载和高并发问题。</p>
<p>　　上面提供的几个解决思路在一定程度上也意味着更大的投入，并且这样的解决思路具备瓶颈，没有很好的扩展性，下面我从低成本、高性能和高扩张性的角度来说说我的一些经验。</p>
<p><strong>1、HTML静态化</strong><br />
　　其实大家都知道，效率最高、消耗最小的就是纯静态化的html页面，所以我们尽可能使我们的网站上的页面采用静态页面来实现，这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站，我们无法全部手动去挨个实现，于是出现了我们常见的信息发布系统CMS，像我们常访问的各个门户站点的新闻频道，甚至他们的其他频道，都是通过信息发布系统来管理和实现的，信息发布系统可以实现最简单的信息录入自动生成静态页面，还能具备频道管理、权限管理、自动抓取等功能，对于一个大型网站来说，拥有一套高效、可管理的CMS是必不可少的。</p>
<p>　　除了门户和信息发布类型的网站，对于交互性要求很高的社区类型网站来说，尽可能的静态化也是提高性能的必要手段，将社区内的帖子、文章进行实时的静态化，有更新的时候再重新静态化也是大量使用的策略，像Mop的大杂烩就是使用了这样的策略，网易社区等也是如此。目前很多博客也都实现了静态化，我使用的这个Blog程序WordPress还没有静态化，所以如果面对高负载访问，www.toplee.com一定不能承受 <img class="wp-smiley" alt=":)" src="http://www.toplee.com/blog/wp-includes/images/smilies/icon_smile.gif" /> </p>
<p>　　同时，html静态化也是某些缓存策略使用的手段，对于系统中频繁使用数据库查询但是内容更新很小的应用，可以考虑使用html静态化来实现，比如论坛中论坛的公用设置信息，这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中，这些信息其实大量被前台程序调用，但是更新频率很小，可以考虑将这部分内容进行后台更新的时候进行静态化，这样避免了大量的数据库访问请求。</p>
<p>　　在进行html静态化的时候可以使用一种折中的方法，就是前端使用动态实现，在一定的策略下进行定时静态化和定时判断调用，这个能实现很多灵活性的操作，我开发的台球网站故人居(<a href="http://www.8zone.cn/">www.8zone.cn</a>)就是使用了这样的方法，我通过设定一些html静态化的时间间隔来对动态网站内容进行缓存，达到分担大部分的压力到静态页面上，可以应用于中小型网站的架构上。故人居网站的地址：<a href="http://www.8zone.cn/">http://www.8zone.cn</a>，顺便提一下，有喜欢台球的朋友多多支持我这个免费网站:)</p>
<p><strong>2、图片服务器分离</strong><br />
　　大家知道，对于Web服务器来说，不管是Apache、IIS还是其他容器，图片是最消耗资源的，于是我们有必要将图片与页面进行分离，这是基本上大型网站都会采用的策略，他们都有独立的图片服务器，甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力，并且可以保证系统不会因为图片问题而崩溃。</p>
<p>　　在应用服务器和图片服务器上，可以进行不同的配置优化，比如Apache在配置ContentType的时候可以尽量少支持，尽可能少的LoadModule，保证更高的系统消耗和执行效率。</p>
<p>　　我的台球网站故人居<a href="http://www.8zone.cn/">8zone.cn</a>也使用了图片服务器架构上的分离，目前是仅仅是架构上分离，物理上没有分离，由于没有钱买更多的服务器:)，大家可以看到故人居上的图片连接都是类似img.9tmd.com或者img1.9tmd.com的URL。</p>
<p>　　另外，在处理静态页面或者图片、js等访问方面，可以考虑使用<a href="http://www.lighttpd.net/">lighttpd</a>代替Apache，它提供了更轻量级和更高效的处理能力。</p>
<p><strong>3、数据库集群和库表散列</strong><br />
　　大型网站都有复杂的应用，这些应用必须使用数据库，那么在面对大量访问的时候，数据库的瓶颈很快就能显现出来，这时一台数据库将很快无法满足应用，于是我们需要使用数据库集群或者库表散列。</p>
<p>　　在数据库集群方面，很多数据库都有自己的解决方案，Oracle、Sybase等都有很好的方案，常用的MySQL提供的Master/Slave也是类似的方案，您使用了什么样的DB，就参考相应的解决方案来实施即可。</p>
<p>　　上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制，于是我们需要从应用程序的角度来考虑改善系统架构，库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离，不同的模块对应不同的数据库或者表，再按照一定的策略对某个页面或者功能进行更小的数据库散列，比如用户表，按照用户ID进行表散列，这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架构，将论坛的用户、设置、帖子等信息进行数据库分离，然后对帖子、用户按照板块和ID进行散列数据库和表，最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。</p>
<p><strong>4、缓存</strong><br />
　　缓存一词搞技术的都接触过，很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。</p>
<p>　　架构方面的缓存，对Apache比较熟悉的人都能知道Apache提供了自己的mod_proxy缓存模块，也可以使用外加的Squid进行缓存，这两种方式均可以有效的提高Apache的访问响应能力。</p>
<p>　　网站程序开发方面的缓存，Linux上提供的<a href="http://www.danga.com/memcached/">Memcached</a>是常用的缓存方案，不少web编程语言都提供memcache访问接口，<a href="http://cn.php.net/memcached">php</a>、perl、c和java都有，可以在web开发中使用，可以实时或者Cron的把数据、对象等内容进行缓存，策略非常灵活。一些大型社区使用了这样的架构。</p>
<p>　　另外，在使用web语言开发的时候，各种语言基本都有自己的缓存模块和方法，PHP有<a href="http://pear.php.net/">Pear</a>的Cache模块和<a href="http://www.toplee.com/blog/?p=100">eAccelerator</a>加速和Cache模块，还要知名的Apc、XCache（国人开发的，支持！）php缓存模块，Java就更多了，.net不是很熟悉，相信也肯定有。</p>
<p><strong>5、镜像</strong><br />
　　镜像是大型网站常采用的提高性能和数据安全性的方式，镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异，比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点，数据进行定时更新或者实时更新。在镜像的细节技术方面，这里不阐述太深，有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路，比如Linux上的rsync等工具。</p>
<p><strong>6、负载均衡</strong><br />
　　负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。</p>
<p>　　负载均衡技术发展了多年，有很多专业的服务提供商和产品可以选择，我个人接触过一些解决方法，其中有两个架构可以给大家做参考。另外有关初级的负载均衡DNS轮循和较专业的CDN架构就不多说了。</p>
<p><strong>6.1 硬件四层交换</strong><br />
　　第四层交换使用第三层和第四层信息包的报头信息，根据应用区间识别业务流，将整个区间段的业务流分配到合适的应用服务器进行处理。　第四层交换功能就象是虚IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上，需要复杂的载量平衡算法。在IP世界，业务类型由终端TCP或UDP端口地址来决定，在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。</p>
<p>　　在硬件四层交换产品领域，有一些知名的产品可以选择，比如Alteon、F5等，这些产品很昂贵，但是物有所值，能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。</p>
<p><strong>6.2 软件四层交换</strong><br />
　　大家知道了硬件四层交换机的原理后，基于OSI模型来实现的软件四层交换也就应运而生，这样的解决方案实现的原理一致，不过性能稍差。但是满足一定量的压力还是游刃有余的，有人说软件实现方式其实更灵活，处理能力完全看你配置的熟悉能力。</p>
<p>　　软件四层交换我们可以使用Linux上常用的LVS来解决，LVS就是Linux Virtual Server，他提供了基于心跳线heartbeat的实时灾难应对解决方案，提高系统的鲁棒性，同时可供了灵活的虚拟VIP配置和管理功能，可以同时满足多种应用需求，这对于分布式的系统来说必不可少。</p>
<p>　　一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。</p>
<p>总结：<br />
　　对于大型网站来说，前面提到的每个方法可能都会被同时使用到，Michael这里介绍得比较浅显，具体实现过程中很多细节还需要大家慢慢熟悉和体会，有时一个很小的squid参数或者apache参数设置，对于系统性能的影响就会很大，希望大家一起讨论，达到抛砖引玉之效。</p>
<p>　　转载请保留出处：俊麟 Michael&#8217;s blog (http://www.toplee.com/blog/?p=71)<br />
Trackback Url : <a href="http://www.toplee.com/blog/wp-trackback.php?p=71">http://www.toplee.com/blog/wp-trackback.php?p=71</a></p>
<img src ="http://www.blogjava.net/jelver/aggbug/191621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-04-09 09:01 <a href="http://www.blogjava.net/jelver/articles/191621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不同Web主机上的Servlet之间数据对象的相互传输(转) </title><link>http://www.blogjava.net/jelver/articles/186066.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Mar 2008 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/186066.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/186066.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/186066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/186066.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/186066.html</trackback:ping><description><![CDATA[<div class="storytext">为什么要这样做<br />
在目前所做的一个项目中，我们使用了两台独立的数据库服务器，出于安全方面的考虑，我们同时使用两台Web服务器分别操作这两个数据库。这就形成了这样的一个结构图：<br />
<br />
<div align="center"><img alt="" src="http://blog.itpub.net/upload/2006/4/19/2/14/11453840699060158.gif" border="0" /></div>
<br />
<br />
由于数据库服务器A和服务库服务器B之间存在着数据的交换，而WEB服务器A并不能直接访问数据库服务器B，同理WEB服务器B也不能直接访问数据库服务器A。这样的交换只能是通过两台Web主机来进行。而在绝大多数时候，我们涉及的是较大规模的数据交换，使用带参数的格式显然不能满足我们的要求，这就涉及了不同Web主机上的Servlet之间数据对象的相互传输的问题。<br />
使用通常的Application域或是Session域的javabean看上去不能满足我们的要求，虽然我们相信会有很多更为完美的方案可以解决这个问题，但是我们今天想看看如何直接通过HTTP连接来完成这样的传输。<br />
首先对于我们的每一个独立的应用来说，两台WEB服务器都会存在一个主次的关系，情况也许是这样的：访问者访问WEB服务器A上的一个servlet A，而这个servlet A产生一个数据对象传输到WEB服务器B上的另一个servlet B，servlet B接收到这个数据对象后对其进行相应的处理，然后它可能还会生成另一个数据对象传输到servlet A中。这样的过程看上去有点象一个远程函数调用的概念。限于篇幅的限制，我们这里讨论一种较为简单的情况，test将passobject传输到test2，test2对passobject进行处理后将其传回到test。<br />
<br />
简单示例的源码<br />
passobject.java<br />
首先，我们需要在两台WEB主机上分别建立对passobject的定义，在两台主机上的定义应该是完全一样，这样的类定义和我们通常使用并没有什么不同。只是这样的类必须实现序列化，也就是要实现Serializable：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;test;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_108_400_Open_Image" onclick="this.style.display='none'; Codehighlighter1_108_400_Open_Text.style.display='none'; Codehighlighter1_108_400_Closed_Image.style.display='inline'; Codehighlighter1_108_400_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_108_400_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_108_400_Closed_Text.style.display='none'; Codehighlighter1_108_400_Open_Image.style.display='inline'; Codehighlighter1_108_400_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;PassObject&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Serializable&nbsp;</span><span id="Codehighlighter1_108_400_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_108_400_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;PassValue1;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;PassValue2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setNewPassObject()<br />
<img id="Codehighlighter1_227_293_Open_Image" onclick="this.style.display='none'; Codehighlighter1_227_293_Open_Text.style.display='none'; Codehighlighter1_227_293_Closed_Image.style.display='inline'; Codehighlighter1_227_293_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_227_293_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_227_293_Closed_Text.style.display='none'; Codehighlighter1_227_293_Open_Image.style.display='inline'; Codehighlighter1_227_293_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_227_293_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_227_293_Open_Text"><span style="color: #000000">{PassValue1</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">yzysynew</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PassValue2</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">new</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setOldPassObject()<br />
<img id="Codehighlighter1_350_386_Open_Image" onclick="this.style.display='none'; Codehighlighter1_350_386_Open_Text.style.display='none'; Codehighlighter1_350_386_Closed_Image.style.display='inline'; Codehighlighter1_350_386_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_350_386_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_350_386_Closed_Text.style.display='none'; Codehighlighter1_350_386_Open_Image.style.display='inline'; Codehighlighter1_350_386_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_350_386_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_350_386_Open_Text"><span style="color: #000000">{PassValue1</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">yzysyold</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
test.java<br />
在其中的一台web主机上建立。除去加注释的那几行，这完全是一个通常意义上的用于显示的servlet，不过那几行的内容看上去也许会有点让你眼花缭乱。这几行将数据对象传输到了另一台主机的test2中，并接收经过test2处理的数据对象。对于这里所涉及的一些不太常用的API，我们将会在最后一并说明。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;test;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.sql.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.jsp.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.jsp.tagext.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.net.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_364_2083_Open_Image" onclick="this.style.display='none'; Codehighlighter1_364_2083_Open_Text.style.display='none'; Codehighlighter1_364_2083_Closed_Image.style.display='inline'; Codehighlighter1_364_2083_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_364_2083_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_364_2083_Closed_Text.style.display='none'; Codehighlighter1_364_2083_Open_Image.style.display='inline'; Codehighlighter1_364_2083_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Test&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;HttpServlet&nbsp;</span><span id="Codehighlighter1_364_2083_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_364_2083_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doGet(HttpServletRequest&nbsp;request,<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException<br />
<img id="Codehighlighter1_527_1853_Open_Image" onclick="this.style.display='none'; Codehighlighter1_527_1853_Open_Text.style.display='none'; Codehighlighter1_527_1853_Closed_Image.style.display='inline'; Codehighlighter1_527_1853_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_527_1853_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_527_1853_Closed_Text.style.display='none'; Codehighlighter1_527_1853_Open_Image.style.display='inline'; Codehighlighter1_527_1853_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_527_1853_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_527_1853_Open_Text"><span style="color: #000000">{PassObject&nbsp;passobject&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;PassObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passobject.setNewPassObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter&nbsp;out&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;response.getWriter();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(passobject.PassValue1);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(passobject.PassValue2);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">创建一个新的URL实例url</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL&nbsp;url&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;URL(</span><span style="color: #000000">"</span><span style="color: #000000">http://141.56.16.8/examples/servlet/test.Test2</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">根据url建立连接</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URLConnection&nbsp;con&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;url.openConnection();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">设置该连接可写</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.setDoOutput(</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">禁用cache</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.setUseCaches(</span><span style="color: #0000ff">false</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">取出输出流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputStream&nbsp;outs</span><span style="color: #000000">=</span><span style="color: #000000">con.getOutputStream();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">将该输出流转换为对象输出流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectOutputStream&nbsp;objout&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ObjectOutputStream(outs);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">将要传输的对象写入该对象输出流中</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objout.writeObject(passobject);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">取得返回的输入流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;in&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;con.getInputStream();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">将该输入流定义为对象输入流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInputStream&nbsp;objStream;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objStream&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ObjectInputStream(in);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">按指定类的格式读取输入流的内容</span><span style="color: #008000"><br />
<img id="Codehighlighter1_1551_1720_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1551_1720_Open_Text.style.display='none'; Codehighlighter1_1551_1720_Closed_Image.style.display='inline'; Codehighlighter1_1551_1720_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1551_1720_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1551_1720_Closed_Text.style.display='none'; Codehighlighter1_1551_1720_Open_Image.style.display='inline'; Codehighlighter1_1551_1720_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1551_1720_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1551_1720_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passobject</span><span style="color: #000000">=</span><span style="color: #000000">(PassObject)objStream.readObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(passobject.PassValue1);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(passobject.PassValue2);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(java.lang.ClassNotFoundException&nbsp;ysy&nbsp;)<br />
<img id="Codehighlighter1_1792_1839_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1792_1839_Open_Text.style.display='none'; Codehighlighter1_1792_1839_Closed_Image.style.display='inline'; Codehighlighter1_1792_1839_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1792_1839_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1792_1839_Closed_Text.style.display='none'; Codehighlighter1_1792_1839_Open_Image.style.display='inline'; Codehighlighter1_1792_1839_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1792_1839_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1792_1839_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(</span><span style="color: #000000">"</span><span style="color: #000000">fail</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doPost(HttpServletRequest&nbsp;request,<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException<br />
<img id="Codehighlighter1_2017_2069_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2017_2069_Open_Text.style.display='none'; Codehighlighter1_2017_2069_Closed_Image.style.display='inline'; Codehighlighter1_2017_2069_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_2017_2069_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_2017_2069_Closed_Text.style.display='none'; Codehighlighter1_2017_2069_Open_Image.style.display='inline'; Codehighlighter1_2017_2069_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_2017_2069_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_2017_2069_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doGet(request,&nbsp;response);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
test2.java<br />
在其中的另一台web主机上建立，用来接收test发送的数据对象，并对其进行处理后返回到test。<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;test;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.sql.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.http.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.jsp.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;javax.servlet.jsp.tagext.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.net.</span><span style="color: #000000">*</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_364_1385_Open_Image" onclick="this.style.display='none'; Codehighlighter1_364_1385_Open_Text.style.display='none'; Codehighlighter1_364_1385_Closed_Image.style.display='inline'; Codehighlighter1_364_1385_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_364_1385_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_364_1385_Closed_Text.style.display='none'; Codehighlighter1_364_1385_Open_Image.style.display='inline'; Codehighlighter1_364_1385_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Test2&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;HttpServlet&nbsp;</span><span id="Codehighlighter1_364_1385_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_364_1385_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doGet(HttpServletRequest&nbsp;request,<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException<br />
<img id="Codehighlighter1_527_1155_Open_Image" onclick="this.style.display='none'; Codehighlighter1_527_1155_Open_Text.style.display='none'; Codehighlighter1_527_1155_Closed_Image.style.display='inline'; Codehighlighter1_527_1155_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_527_1155_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_527_1155_Closed_Text.style.display='none'; Codehighlighter1_527_1155_Open_Image.style.display='inline'; Codehighlighter1_527_1155_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_527_1155_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_527_1155_Open_Text"><span style="color: #000000">{</span><span style="color: #008000">//</span><span style="color: #008000">封装用于返回的对象输出流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectOutputStream&nbsp;out&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ObjectOutputStream(response.getOutputStream());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">封装用于接收的对象输入流</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInputStream&nbsp;in&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ObjectInputStream(request.getInputStream());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PassObject&nbsp;passobject</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;PassObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">按指定类的格式读取对象输入流中的内容</span><span style="color: #008000"><br />
<img id="Codehighlighter1_844_910_Open_Image" onclick="this.style.display='none'; Codehighlighter1_844_910_Open_Text.style.display='none'; Codehighlighter1_844_910_Closed_Image.style.display='inline'; Codehighlighter1_844_910_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_844_910_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_844_910_Closed_Text.style.display='none'; Codehighlighter1_844_910_Open_Image.style.display='inline'; Codehighlighter1_844_910_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_844_910_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_844_910_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passobject</span><span style="color: #000000">=</span><span style="color: #000000">(PassObject)in.readObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(java.lang.ClassNotFoundException&nbsp;ysy&nbsp;)<br />
<img id="Codehighlighter1_982_996_Open_Image" onclick="this.style.display='none'; Codehighlighter1_982_996_Open_Text.style.display='none'; Codehighlighter1_982_996_Closed_Image.style.display='inline'; Codehighlighter1_982_996_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_982_996_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_982_996_Closed_Text.style.display='none'; Codehighlighter1_982_996_Open_Image.style.display='inline'; Codehighlighter1_982_996_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_982_996_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_982_996_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">对接受到的数据对象进行处理</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passobject.setOldPassObject();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">将处理后的数据对象返回到对象输出流中</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.writeObject(passobject);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doPost(HttpServletRequest&nbsp;request,<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException<br />
<img id="Codehighlighter1_1319_1371_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1319_1371_Open_Text.style.display='none'; Codehighlighter1_1319_1371_Closed_Image.style.display='inline'; Codehighlighter1_1319_1371_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1319_1371_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1319_1371_Closed_Text.style.display='none'; Codehighlighter1_1319_1371_Open_Image.style.display='inline'; Codehighlighter1_1319_1371_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1319_1371_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1319_1371_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doGet(request,&nbsp;response);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
程序中涉及的部分API的说明<br />
java.net.URL<br />
URL类表示了一个统一资源路径。这样的资源可能是一个文件或目录，也可能是更为复杂的诸如数据库的查询或是搜索引擎。<br />
在我们的程序中使用了URL的一种构造函数： <br />
URL(String spec) <br />
直接使用字符串作为构造函数的参数，这实际上是URL的众多构造函数中最为简单的一种。<br />
此外，我们还用到了URL的openConnection()方法：<br />
public URLConnection openConnection()<br />
throws IOException<br />
该方法返回了一个URLConnection对象。每次调用该方法时会开启一个到指定URL的新的连接。<br />
这里需要注意的是，调用该方法的结果是建立了一个连接，这与通常的页面跳转完全是两回事。在更多的情况下，这里仅仅是建立了一个连接的通路，而并没有实现任何其它的操作。<br />
java.net.URLConnection<br />
这是一个抽象类，是所有反映application和一个URL之前的通信的类的超类。这个类的实例可以用来对一个URL表示的资源进行读写。<br />
在我们的程序中我们使用了这个类的如下方法： <br />
getInputStream<br />
public InputStream getInputStream()<br />
throws IOException<br />
返回从这个连接读取的一个输入流<br />
getOutputStream<br />
public OutputStream getOutputStream()<br />
throws IOException<br />
返回一个用于写入这个连接的输出流<br />
setDoOutput<br />
public void setDoOutput(boolean dooutput)<br />
设置该连接是否可以写入<br />
setUseCaches<br />
public void setUseCaches(boolean usecaches)<br />
设置该连接是否使用cache<br />
java.io.OutputStream<br />
这是一个抽象类，是所有反映一个二进制输出流的类的超类。一个这样的输出流可以对二进制数据进行输出或发送。<br />
java.io.ObjectOutputStream<br />
该类用来向一个OutputStream写入java的对象。这个对象可以使用ObjectInputStream进行读取或再造。<br />
只有实现java.io.Serializable接口的对象可以写入该数据流中。<br />
在我们的程序中还使用了该类的writeObject()方法：<br />
public final void writeObject(Object obj)<br />
throws IOException<br />
将指定的对象写入ObjectOutputStream。<br />
java.io.InputStream<br />
这是一个抽象类，是所有反映一个二进制输入流的类的超类。<br />
java.io.ObjectInputStream<br />
一个ObjectInputStream对一个使用ObjectOutputStream写入的对象进行解析。<br />
在我们的程序中使用了该类的readObject()方法：<br />
public final Object readObject()<br />
throws OptionalDataException,<br />
ClassNotFoundException,<br />
IOException<br />
从一个ObjectInputStream中读取一个对象。<br />
<br />
程序执行的结果<br />
如果一切正常，访问test.Test你应该可以看到这样的结果：<br />
yzysynew<br />
new<br />
yzysyold<br />
new<br />
其中yzysynew，new是对象原来的内容，而yzysyold，new所反映的那个对象已经是传送到test2后经test2处理过的了。<br />
</div>
<img src ="http://www.blogjava.net/jelver/aggbug/186066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2008-03-13 15:53 <a href="http://www.blogjava.net/jelver/articles/186066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet 监听器应用（转）</title><link>http://www.blogjava.net/jelver/articles/164916.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 03 Dec 2007 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/164916.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/164916.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/164916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/164916.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/164916.html</trackback:ping><description><![CDATA[<h3><font color="#993300" size="2">监听器概述</font><br />
<font color="#993300" size="2">&nbsp;&nbsp;1.Listener是Servlet的监听器&nbsp;<br />
&nbsp;&nbsp;2.可以监听客户端的请求、服务端的操作等。<br />
&nbsp;&nbsp;3.通过监听器，可以自动激发一些操作，如监听在线用户数量,当增加一个HttpSession时，给在线人数加1。<br />
&nbsp;&nbsp;4.编写监听器需要实现相应的接口<br />
&nbsp;&nbsp;5.编写完成后在web.xml文件中配置一下,就可以起作用了<br />
&nbsp;&nbsp;6.可以在不修改现有系统基础上,增加web应用程序生命周期事件的跟踪<br />
<br />
</font></h3>
<h3><font color="#993300" size="2">常用的监听接口</font></h3>
<br />
<font color="#993300" size="2">&nbsp;&nbsp;1.ServletContextAttributeListener<br />
&nbsp;&nbsp;监听对ServletContext属性的操作，比如增加/删除/修改<br />
&nbsp;&nbsp;2.ServletContextListener<br />
&nbsp;&nbsp;监听ServletContext,当创建ServletContext时，激发contextInitialized(ServletContextEvent&nbsp;sce)方法；当销毁ServletContext时，激发contextDestroyed(ServletContextEvent&nbsp;sce)方法。<br />
&nbsp;&nbsp;3.HttpSessionListener<br />
&nbsp;&nbsp;监听HttpSession的操作。当创建一个Session时，激发session&nbsp;Created(SessionEvent&nbsp;se)方法；当销毁一个Session时，激发sessionDestroyed&nbsp;(HttpSessionEvent&nbsp;se)方法。<br />
&nbsp;&nbsp;4.HttpSessionAttributeListener<br />
&nbsp;&nbsp;监听HttpSession中的属性的操作。当在Session增加一个属性时，激发attributeAdded(HttpSessionBindingEvent&nbsp;se)&nbsp;方法；当在Session删除一个属性时，激发attributeRemoved(HttpSessionBindingEvent&nbsp;se)方法；当在Session属性被重新设置时，激发attributeReplaced(HttpSessionBindingEvent&nbsp;se)&nbsp;方法。<br />
<br />
使用范例： </font>
<h3><font color="#993300" size="2">由监听器管理共享数据库连接</font></h3>
<br />
<font color="#993300" size="2">&nbsp;&nbsp;生命周期事件的一个实际应用由context监听器管理共享数据库连接。在web.xml中如下定义监听器：<br />
&lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;listener-class&gt;XXX.MyConnectionManager&lt;/listener-class&gt;<br />
&lt;/listener&gt;&nbsp;&#216;server创建监听器的实例,接受事件并自动判断实现监听器接口的类型。要记住的是由于监听器是配置在部署描述符web.xml中，所以不需要改变任何代码就可以添加新的监听器。<br />
<br />
public&nbsp;class&nbsp;MyConnectionManager&nbsp;implements&nbsp;ServletContextListener{&nbsp;&nbsp;<br />
&nbsp;&nbsp;public&nbsp;void&nbsp;contextInitialized(ServletContextEvent&nbsp;e)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;con&nbsp;=&nbsp;//&nbsp;create&nbsp;connection&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.getServletContext().setAttribute("con",&nbsp;con);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;contextDestroyed(ServletContextEvent&nbsp;e)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;con&nbsp;=&nbsp;(Connection)&nbsp;e.getServletContext().getAttribute("con");&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.close();&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(SQLException&nbsp;ignored)&nbsp;{&nbsp;}&nbsp;//&nbsp;close&nbsp;connection&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
}&nbsp;&nbsp;<br />
&nbsp;&nbsp;监听器保证每新生成一个servlet&nbsp;context都会有一个可用的数据库连接,并且所有的连接对会在context关闭的时候随之关闭。&nbsp;<br />
<br />
</font>
<h3><font color="#993300" size="2">计算在线用户数量的Linstener</font></h3>
<font color="#993300" size="2">(1)<br />
&nbsp;Package&nbsp;xxx;&nbsp;<br />
<br />
&nbsp;public&nbsp;class&nbsp;OnlineCounter&nbsp;{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;long&nbsp;online&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;long&nbsp;getOnline(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;online;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;raise(){&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;online++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;reduce(){&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;online--;&nbsp;<br />
&nbsp;&nbsp;&nbsp;}<br />
}&nbsp;<br />
<br />
import&nbsp;javax.servlet.http.HttpSessionEvent;<br />
import&nbsp;javax.servlet.http.HttpSessionListener;<br />
<br />
public&nbsp;class&nbsp;OnlineCounterListener&nbsp;implements&nbsp;HttpSessionListener{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;sessionCreated(HttpSessionEvent&nbsp;hse)&nbsp;{&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OnlineCounter.raise();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;sessionDestroyed(HttpSessionEvent&nbsp;hse){&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OnlineCounter.reduce();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
&nbsp;}&nbsp;<br />
<br />
在需要显示在线人数的JSP中可是使用<br />
目前在线人数：<br />
&lt;%@&nbsp;page&nbsp;import=&#8220;xxx.OnlineCounter"&nbsp;%&gt;<br />
&lt;%=OnlineCounter.getOnline()%&gt;<br />
<br />
退出会话(可以给用户提供一个注销按钮)：<br />
&lt;form&nbsp;action="exit.jsp"&nbsp;method=post&gt;&nbsp;<br />
&nbsp;&nbsp;&lt;input&nbsp;type=submit&nbsp;value="exit"&gt;&nbsp;<br />
&lt;/form&gt;&nbsp;<br />
<br />
exit.jsp:&nbsp;&lt;%session.invalidate()&nbsp;;%&gt;&nbsp;<br />
<br />
在web.xml中加入:<br />
&lt;listener&gt;&nbsp;<br />
&nbsp;&nbsp;&lt;listener-class&gt;servletlistener111111.SecondListener&lt;/listener-class&gt;&nbsp;&lt;/listener&gt;<br />
<br />
怎么样，就是这么简单，不用对现有代码做任何的修改。&nbsp;</font>&nbsp;<br />
<img src ="http://www.blogjava.net/jelver/aggbug/164916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2007-12-03 16:51 <a href="http://www.blogjava.net/jelver/articles/164916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>B/S系统权限控制的一种简单方法 (转)</title><link>http://www.blogjava.net/jelver/articles/141767.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Fri, 31 Aug 2007 08:37:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/141767.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/141767.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/141767.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/141767.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/141767.html</trackback:ping><description><![CDATA[<p>&nbsp;看了网上一些关于权限控制的帖子，越看越迷糊，什么用AOP(Aspect Oriented Programming,面向方面编程)，用容器，RBAC(基于角色的访问控制方法),SSO,Jive的Proxy模式等等等等，且又是role又是group，真是头都大了，先写个简单的实现方法，以后再研究高深的。<br />
&nbsp; 此方法不依赖容器 框架，适用于小系统(主要JSP页面要少于100,因为是硬编码到JSP)，适用于要精确控制页面field的情况较多的系统。<br />
&nbsp; (插句话：要分清权限控制与业务逻辑，业务逻辑就是情况由系统运行时的某些条件决定，如学生管理系统中，某一学生进入系统，只能看自己的记录，因为可看的记录是由学号来决定的，所以这是业务逻辑，而又如学生不能看老师的记录，这是有学生的身份来决定的，所以这是权限控制。)<br />
&nbsp; 好了，进入正题！<br />
&nbsp; 建表：<br />
&nbsp; user(user信息： userID userPassword 等)<br />
&nbsp; role(role描述：roleID roleDesc)<br />
&nbsp; permission(permission描述：permissionID permissionDesc)<br />
&nbsp; user-role(user role对应关系表：userID roleID)<br />
&nbsp; role-permission(role permission对应关系表：roleID permissionID)<br />
&nbsp; user-permission(user permission对应关系表：userID permissionID)<br />
&nbsp; <br />
&nbsp; 重要申明： </p>
<p>&nbsp;<strong>1</strong> 此处role没有继承关系,只是permission的集合<br />
&nbsp;<strong>2</strong> user-permission表只是为了方便，其数据是根据user-role role-permission两表得来，只有在user-role role-permission两表有更新的时候更新此表，并不能单独赋予user某个permission,只能赋予user一个或多个role。<br />
<strong>3</strong> permission的分配，这是一个难点，很多比较复杂的权限控制系统也是因为这个才发展出来，此处把它尽量想简单，不考虑业务逻辑，以页面为视角，分两层，首先是需要控制的jsp页面，然后是需要控制的页面field(包括link,text,textbox,button等等)，field这一层还有privilege之分(R和W，即可读和可写)<br />
&nbsp; 基本思路：进入JSP页面时，检查用户信息，查到用户有此permission就包含此代码，如果没有此permission就不包含此代码，此功能由Tag来完成(不会写Tag？不要紧，抄！)。看代码吧！<br />
&nbsp; <strong>1</strong> 建表(如上)<br />
&nbsp; <strong>2</strong> 建两个class(bean) (UserProfile是用户基本信息&nbsp;&nbsp; UserPermission是permission )<br />
&nbsp;&nbsp;&nbsp; UserProfile.java:<br />
package com.&#215;&#215;.&#215;&#215;.&#215;&#215;;<br />
import java.util.Collection;</p>
<p>public class UserProfile {<br />
&nbsp; private String userId;<br />
&nbsp; private String userType;<br />
&nbsp; private String companyNo;<br />
&nbsp; private String companyName;<br />
&nbsp; private String companyType;<br />
&nbsp; private Collection userPermissions;</p>
<p>&nbsp; public String getUserId() {<br />
&nbsp;&nbsp;&nbsp; return userId;<br />
&nbsp; }<br />
&nbsp; public void setUserId(String userId) {<br />
&nbsp;&nbsp;&nbsp; this.userId = userId;<br />
&nbsp; }<br />
&nbsp; public String getUserType() {<br />
&nbsp;&nbsp;&nbsp; return userType;<br />
&nbsp; }<br />
&nbsp; public void setUserType(String userType) {<br />
&nbsp;&nbsp;&nbsp; this.userType = userType;<br />
&nbsp; }<br />
&nbsp; public String getCompanyNo() {<br />
&nbsp;&nbsp;&nbsp; return companyNo;<br />
&nbsp; }<br />
&nbsp; public void setCompanyNo(String companyNo) {<br />
&nbsp;&nbsp;&nbsp; this.companyNo = companyNo;<br />
&nbsp; }<br />
&nbsp; public String getCompanyName() {<br />
&nbsp;&nbsp;&nbsp; return companyName;<br />
&nbsp; }<br />
&nbsp; public void setCompanyName(String companyName) {<br />
&nbsp;&nbsp;&nbsp; this.companyName = companyName;<br />
&nbsp; }<br />
&nbsp; public String getCompanyType() {<br />
&nbsp;&nbsp;&nbsp; return companyType;<br />
&nbsp; }<br />
&nbsp; public void setCompanyType(String companyType) {<br />
&nbsp;&nbsp;&nbsp; this.companyType = companyType;<br />
&nbsp; }<br />
&nbsp; public Collection getUserPermissions() {<br />
&nbsp;&nbsp;&nbsp; return userPermissions;<br />
&nbsp; }<br />
&nbsp; public void setUserPermissions(Collection userPermissions) {<br />
&nbsp;&nbsp;&nbsp; this.userPermissions = userPermissions;<br />
&nbsp; }<br />
}</p>
<p>&nbsp; UserPermission.java:<br />
package com.&#215;&#215;.&#215;&#215;.&#215;&#215;;</p>
<p>public class UserPermission {<br />
&nbsp; private int permissionId;<br />
&nbsp; private String privilege;<br />
&nbsp; public int getPermissionId() {<br />
&nbsp;&nbsp;&nbsp; return permissionId;<br />
&nbsp; }<br />
&nbsp; public void setPermissionId(int permissionId) {<br />
&nbsp;&nbsp;&nbsp; this.permissionId = permissionId;<br />
&nbsp; }<br />
&nbsp; public String getPrivilege() {<br />
&nbsp;&nbsp;&nbsp; return privilege;<br />
&nbsp; }<br />
&nbsp; public void setPrivilege(String privilege) {<br />
&nbsp;&nbsp;&nbsp; this.privilege = privilege;<br />
&nbsp; }<br />
}&nbsp; <br />
&nbsp; <br />
&nbsp; <br />
&nbsp; <strong>3</strong> 加两个Tag(Page与Field)：<br />
&nbsp; SecurityTagForPage.java：<br />
package com.**.**.taglib;<br />
import java.util.*;</p>
<p>public class SecurityTagForPage extends TagSupport<br />
{<br />
&nbsp;<br />
&nbsp; private int permissionID;<br />
&nbsp; <br />
&nbsp; public int doEndTag() throws JspException<br />
&nbsp; {<br />
&nbsp; HttpSession session = pageContext.getSession();<br />
&nbsp; //登陆时把该user的userProfile放到session里 <br />
&nbsp; UserProfile userProfile = (UserProfile)session.getAttribute("userProfile");<br />
&nbsp; Collection collection= userProfile.getUserPermissions();<br />
&nbsp; Iterator it = collection.iterator() ;<br />
&nbsp; while(it.hasNext())<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserPermission userPermission = (UserPermission)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((permissionID == userPermission.getPermissionId()))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EVAL_PAGE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return SKIP_PAGE;<br />
&nbsp; }</p>
<p>&nbsp; public int getPermissionID()<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return permissionID;<br />
&nbsp; }<br />
&nbsp; public void setPermissionID(int permissionID)<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; this.permissionID = permissionID;<br />
&nbsp; }<br />
}</p>
<p>&nbsp; SecurityTagForField：<br />
public class SecurityTagForField extends TagSupport<br />
{<br />
&nbsp; private int permissionID;<br />
&nbsp; private String privilege;</p>
<p>&nbsp; public int doStartTag() throws JspException<br />
&nbsp; {<br />
&nbsp;&nbsp; HttpSession session = pageContext.getSession();<br />
&nbsp;&nbsp; UserProfile userProfile = (UserProfile)session.getAttribute("userProfile");</p>
<p>&nbsp;&nbsp;&nbsp; Collection collection= userProfile.getUserPermissions();<br />
&nbsp;&nbsp;&nbsp; Iterator it = collection.iterator() ;<br />
&nbsp;&nbsp;&nbsp; while(it.hasNext())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserPermission userPermission = (UserPermission)it.next();<br />
&nbsp;&nbsp;&nbsp; if (privilege ==null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p><br />
if ( (permissionID == userPermission.getPermissionId()))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EVAL_BODY_INCLUDE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((permissionID == userPermission.getPermissionId())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp;(privilege.equals(userPermission.getPrivilege())))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return EVAL_BODY_INCLUDE;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return SKIP_BODY;<br />
&nbsp; } </p>
<p>&nbsp;</p>
<p><br />
&nbsp; public int getPermissionID()<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return permissionID;<br />
&nbsp; }<br />
&nbsp; public void setPermissionID(int permissionID)<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; this.permissionID = permissionID;<br />
&nbsp; }<br />
&nbsp; public String getPrivilege()<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; return privilege;<br />
&nbsp; }<br />
&nbsp; public void setPrivilege(String privilege)<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; this.privilege = privilege;<br />
&nbsp; }<br />
}<br />
&nbsp; <strong>4</strong> 在web-inf目录下建个securityTag.tld文件，内容如下：(改一下class的目录)<br />
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />
&lt;!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"<br />
&nbsp;"<a href="http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd</a>"&gt;<br />
&lt;!-- a tag library descriptor --&gt;<br />
&lt;taglib&gt;<br />
&nbsp;&lt;tlibversion&gt;1.0&lt;/tlibversion&gt;<br />
&nbsp;&lt;jspversion&gt;1.1&lt;/jspversion&gt;<br />
&nbsp;&lt;shortname&gt;security&lt;/shortname&gt;<br />
&nbsp;&lt;uri/&gt;<br />
&nbsp;&lt;info&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;access control!<br />
&nbsp; &nbsp;&lt;/info&gt;<br />
&nbsp;&lt;tag&gt;<br />
&nbsp;&nbsp;&lt;name&gt;securityForField&lt;/name&gt;<br />
&nbsp;&nbsp;&lt;tagclass&gt;com.companyname.prjname.taglib.SecurityTagForField&lt;/tagclass&gt;<br />
&nbsp;&nbsp;&lt;attribute&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;permissionID&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;required&gt;true&lt;/required&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/attribute&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;attribute&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;privilege&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/attribute&gt;</p>
<p>&nbsp;&lt;/tag&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tag&gt;<br />
&nbsp;&nbsp;&lt;name&gt;securityForPage&lt;/name&gt;<br />
&nbsp;&nbsp;&lt;tagclass&gt;com.companyname.prjname.taglib.SecurityTagForPage&lt;/tagclass&gt;<br />
&nbsp;&nbsp;&lt;attribute&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;permissionID&lt;/name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;required&gt;true&lt;/required&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/attribute&gt;</p>
<p>&nbsp;&lt;/tag&gt;<br />
&lt;/taglib&gt;</p>
<p>&nbsp; <strong>5</strong> 修改需要控制的jsp<br />
&nbsp; 在jsp页面这样写：<br />
&lt;%@ taglib uri="/WEB-INF/securityTag.tld" prefix="security" %&gt;<br />
&lt;%@ page import="com.hp.elog2.util.Util" %&gt;<br />
&lt;security:securityForPage permissionID="36" /&gt;<br />
.......<br />
&lt;security:securityForField permissionID="46" privilege="R"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;&lt;html:text name="formBean" property="property1" readonly="true" /&gt;&lt;/td&gt;<br />
&lt;/security:securityForField&gt;<br />
&lt;security:securityForField permissionID="46" privilege="W"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;&lt;html:text name="formBean" property="property1" /&gt;&lt;/td&gt;<br />
&lt;/security:securityForField&gt;<br />
......<br />
&nbsp; 这样就大功告成了，建议在所有jsp页面完成后再做权限控制这一块(添加Tag)，主要都是些Copy＋C和Copy＋V的工作。<br />
&nbsp; 此方法最大的问题就是hardcode太多，但结构简单，思路清晰，适用范围广。<br />
&nbsp; 复杂的方法希望同道之士于我联系<a href="mailto:leon_sandy@tom.com">leon_sandy@tom.com</a>，共同研究！</p>
<img src ="http://www.blogjava.net/jelver/aggbug/141767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2007-08-31 16:37 <a href="http://www.blogjava.net/jelver/articles/141767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat5.0-5.5连接池配置指南 （转）</title><link>http://www.blogjava.net/jelver/articles/88127.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sat, 16 Dec 2006 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/88127.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/88127.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/88127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/88127.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/88127.html</trackback:ping><description><![CDATA[本文以目前最流行的MySQL为例，讲解通过Tomcat连接池连接MySQL数据库的基本步骤，如果你了解MySQL可跳过第一步。<br /><br />　　在进行Tomcat连接池配置前，先解压缩mysql-connector-java-xxx.zip，将其中的mysql-connector-java-3.x.x-xxx.jar取出，置于&lt;%TOMCAT_HOME%&gt;\common\lib中。<br /><br />　　接下来，让我们一起进入精彩的Tomcat配置之旅。<br /><br />一.新建用户及数据库<br /><br />操作步骤如下：<br /><br />C:\Documents and Settings\Administrator&gt;d:<br /><br />D:\&gt;cd mysql\bin<br /><br />D:\MySQL\bin&gt;mysql -u root -p<br />Enter password: *******<br />Welcome to the MySQL monitor.  Commands end with ; or \g.<br />Your MySQL connection id is 51 to server version: 4.1.12a-nt<br /><br />Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br />mysql&gt; GRANT ALL PRIVILEGES ON jcc.* TO jcc@localhost IDENTIFIED BY 'jsp.com.cn'<br />WITH GRANT OPTION;<br />Query OK, 0 rows affected (0.01 sec)<br /><br />mysql&gt; USE mysql;<br />Database changed<br />mysql&gt; SELECT Host,User,Password FROM user;<br />+-----------+------+-------------------------------------------+<br />| Host      | User | Password                                  |<br />+-----------+------+-------------------------------------------+<br />| localhost | root | *60D5B730382EC2170CA366DE181767E4C5343DE8 |<br />| %         | jsp  | *C22AB0FD8A289C7D337C9998B63B8EA8335E5F35 |<br />| localhost | jcc  | *C22AB0FD8A289C7D337C9998B63B8EA8335E5F35 |<br />+-----------+------+-------------------------------------------+<br />3 rows in set (0.01 sec)<br /><br />mysql&gt; exit<br />Bye<br /><br />D:\MySQL\bin&gt;mysql -u jcc -p<br />Enter password: **********<br />Welcome to the MySQL monitor.  Commands end with ; or \g.<br />Your MySQL connection id is 57 to server version: 4.1.12a-nt<br /><br />Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br /><br />mysql&gt; CREATE DATABASE jcc;<br />Query OK, 1 row affected (0.02 sec)<br /><br />mysql&gt; USE jcc;<br />Database changed<br />mysql&gt; CREATE TABLE user(<br />    -&gt;   id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />    -&gt;   name VARCHAR(8) NOT NULL<br />    -&gt; );<br />Query OK, 0 rows affected (0.08 sec)<br /><br />mysql&gt; INSERT INTO user (name) VALUES ('Corebit');<br />Query OK, 1 row affected (0.03 sec)<br /><br />mysql&gt; INSERT INTO user (name) VALUES ('Ivan');<br />Query OK, 1 row affected (0.03 sec)<br /><br />mysql&gt; SELECT * FROM user;<br />+----+---------+<br />| id | name    |<br />+----+---------+<br />|  1 | Corebit |<br />|  2 | Ivan    |<br />+----+---------+<br />2 rows in set (0.00 sec)<br /><br />mysql&gt;<br /><br />二.配置Tomcat连接池<br /><br />Tomcat5.0进行如下配置：<br /><br />在&lt;%TOMCAT_HOME%&gt;\conf\server.xml的&lt;Host&gt;...&lt;/Host&gt;之间加入以下代码：<br /><br />&lt;Context path="" docBase="D:/jcc"<br />        debug="5" reloadable="true" crossContext="true"&gt;<br /><br />  &lt;Logger className="org.apache.catalina.logger.FileLogger"<br />             prefix="localhost_DBTest_log." suffix=".txt"<br />             timestamp="true"/&gt;<br /><br />  &lt;Resource name="jdbc/JCC"<br />               auth="Container"<br />               type="javax.sql.DataSource"/&gt;<br /><br />  &lt;ResourceParams name="jdbc/JCC"&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;factory&lt;/name&gt;<br />      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />      &lt;name&gt;maxActive&lt;/name&gt;<br />      &lt;value&gt;100&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />      &lt;name&gt;maxIdle&lt;/name&gt;<br />      &lt;value&gt;30&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />      &lt;name&gt;maxWait&lt;/name&gt;<br />      &lt;value&gt;10000&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />     &lt;name&gt;username&lt;/name&gt;<br />     &lt;value&gt;jcc&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;parameter&gt;<br />     &lt;name&gt;password&lt;/name&gt;<br />     &lt;value&gt;jsp.com.cn&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />       &lt;name&gt;driverClassName&lt;/name&gt;<br />       &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br />      &lt;name&gt;url&lt;/name&gt;<br />      &lt;value&gt;jdbc:mysql://localhost/jcc&lt;/value&gt;<br />    &lt;/parameter&gt;<br />  &lt;/ResourceParams&gt;<br />&lt;/Context&gt;<br /><br />Tomcat5.5进行如下配置：<br /><br />在&lt;%TOMCAT_HOME%&gt;\conf\server.xml的&lt;Host&gt;...&lt;/Host&gt;之间加入以下代码：<br /><br />&lt;Context path="" docBase="D:/jcc"<br />        debug="5" reloadable="true" crossContext="true"&gt;<br /><br />  &lt;Resource name="jdbc/JCC" auth="Container" type="javax.sql.DataSource"<br />               maxActive="100" maxIdle="30" maxWait="10000"<br />               username="jcc" password="jsp.com.cn" driverClassName="com.mysql.jdbc.Driver"<br />               url="jdbc:mysql://localhost/jcc"/&gt;<br /><br />&lt;/Context&gt;<br /><br />三.在&lt;%wwwroot%&gt;/下，新建MySQL数据库连接文件Select.jsp<br /><br />　　Select.jsp源码如下：<br /><br />&lt;%@page contentType="text/html;charset=gb2312"%&gt;<br />&lt;%@page import="java.sql.*"%&gt;<br />&lt;%@page import="javax.sql.DataSource"%&gt;<br />&lt;%@page import="javax.naming.*"%&gt;<br />&lt;html&gt;<br />&lt;body&gt;<br />&lt;%<br />try{<br />  Context initCtx=new InitialContext();<br />  DataSource db = (DataSource)initCtx.lookup("java:comp/env/jdbc/JCC");<br />  Connection conn = db.getConnection();<br />  Statement stmt = conn.createStatement();<br />  ResultSet rs = stmt.executeQuery("SELECT * FROM user");<br />  out.println("User-list"+"&lt;br&gt;");<br />  while(rs.next()){<br />    out.print(rs.getString(1)+" ");<br />    out.print(rs.getString(2)+"&lt;br&gt;");<br />  }<br />  rs.close();<br />  stmt.close();<br />  conn.close();<br />}<br />catch(Exception e){<br />  out.print(e);<br />}<br />%&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br /><br />四.运行http://localhost/Select.jsp，显示结果如下：<br /><br />User-list<br />1 Corebit<br />2 Ivan<br /><br />　　则表示数据库连接成功！恭喜！恭喜！<br /><br />　　否则请检查数据库连接器版本，出错可能性比较高！<br /><br />　　＊注：<br /><br />　　Tomcat连接池中，部分参数说明如下：<br /><br />　　maxActive="100"　　&lt;!--最大活跃连接数，这里取值为100，表示同时最多有100个数据库连接。设为0表示无限制。--&gt;<br /><br />　　maxIdle="30"       &lt;!--最大的空闲连接数，这里取值为30，表示即使没有数据库连接时依然可以保持30个空闲的连接，而不被清除，随时处于待命状态。设为0表示无限制。--&gt;<br /><br />　　maxWait="10000"    &lt;!--最大建立连接等待时间。如果超过此时间将接到异常。这里设置为10000，表示10秒后超时。设为-1表示无限制，直到超时为止。--&gt;<br /><br />    jdbc:mysql://localhost/jcc    &lt;!--数据库连接字符串,同jdbc:mysql://localhost:3306/jcc?autoReconnect=true--&gt;<br /><br />    PS：如果最大数据库活跃连接数过大，可想而知，内存占用量是非常惊人的！如果空闲连接数过大，则资源利用率低，连接池长期未释放，可导致连接池结点异常。所以选好maxActive和maxIdle是连接池性能的关键因素，当然这取决于服务器环境。<br /><br />　　＊附：<br /><br />　　连接池运作原理：<br /><br />　　在实际应用开发中，特别是在WEB应用系统中，如果JSP、Servlet或EJB使用JDBC直接访问数据库中的数据，每一次数据访问请求都必须经历建立数据库连接、打开数据库、存取数据和关闭数据库连接等步骤，而连接并打开数据库是一件既消耗资源又费时的工作，如果频繁发生这种数据库操作，系统的性能必然会急剧下降，甚至会导致系统崩溃。数据库连接池技术是解决这个问题最常用的方法，在许多应用程序服务器（例如：Weblogic,WebSphere,JBoss）中，基本都提供了这项技术，无需自己编程，但是，深入了解这项技术是非常必要的。<br /><br />　　数据库连接池技术的思想非常简单，将数据库连接作为对象存储在一个Vector对象中，一旦数据库连接建立后，不同的数据库访问请求就可以共享这些连接，这样，通过复用这些已经建立的数据库连接，可以克服上述缺点，极大地节省系统资源和时间。<br /><br />　　数据库连接池的主要操作如下：<br /><br />　　（1）建立数据库连接池对象（服务器启动）。<br /><br />　　（2）按照事先指定的参数创建初始数量的数据库连接（即：空闲连接数）。<br /><br />　　（3）对于一个数据库访问请求，直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接，且连接数没有达到最大（即：最大活跃连接数），创建一个新的数据库连接。<br /><br />　　（4）存取数据库。<br /><br />　　（5）关闭数据库，释放所有数据库连接（此时的关闭数据库连接，并非真正关闭，而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接）。<br /><br />　　（6）释放数据库连接池对象（服务器停止、维护期间，释放数据库连接池对象，并释放所有连接）。<br /><br />　　希望本文能对你使用Tomcat连接池连接MySQL数据库有所帮助！<br /><br />参考文献：<br />http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html<br />http://jakarta.apache.org/tomcat/tomcat-5.5-doc/jndi-datasource-examples-howto.html<br /><br /><img src ="http://www.blogjava.net/jelver/aggbug/88127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-12-16 11:08 <a href="http://www.blogjava.net/jelver/articles/88127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一篇介绍标签库很详细的文章，可以做为参考手册 (zhuan)</title><link>http://www.blogjava.net/jelver/articles/73954.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 09 Oct 2006 01:13:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73954.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73954.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73954.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73954.html</trackback:ping><description><![CDATA[
		<p>摘要：</p>
		<p>标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求，这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib，其实换句话说，taglib可以看成是对JSP标记的一种扩展，正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中，这种标签库存放着你自己定义的tag标签。简而言之，如果使用taglib，那么你可以设计自己的JSP标记！</p>
		<p>一般来说，自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务，诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通，而且对数据访问和企业级服务访问都非常熟悉的程序员，对于HTML设计者来说，使得他可以不去关注那些较复杂的商业逻辑，而将精力放在网页设计上。同时，它也将库开发者和库使用者进行合理分工，自定义tag标签将那些重复工作进行封装，从而大大提高了生产力，而且可以使得tag库可用于不同的项目中，完美地体现了软件复用的思想。</p>
		<p>在这篇文章中，我们主要讨论：</p>
		<p>· 什么是自定义tag标签？</p>
		<p>· 怎么使用tag标签？</p>
		<p>o 声明要使用的tag库</p>
		<p>o 找到与之对应的tag处理类</p>
		<p>o tag标签的类型</p>
		<p>· 自定义tag标签</p>
		<p>o tag处理类</p>
		<p>o tag库描述</p>
		<p>o tag标签示例</p>
		<p>o 带属性的tag</p>
		<p>o 带body的tag</p>
		<p>o 定义了脚本变量的tag</p>
		<p>o 具有协作关系的tag</p>
		<p>· 自定义tag标签</p>
		<p>o 一个迭代tag的例子</p>
		<p>o 一个模板tag库</p>
		<p>o tag处理类到底是怎样被调用的？</p>
		<p>
				<br />什么是自定义的tag?</p>
		<p>一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时，tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后，实际上tag标签被转化成为了对tag处理类的操作。</p>
		<p>自定义tag标签有很多特色，诸如：</p>
		<p>· 可以在JSP页面中自定义tag标签的属性</p>
		<p>· 访问JSP页面中的所有对象</p>
		<p>· 可以动态地修改页面输出</p>
		<p>· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件，然后在一个tag中调用此JavaBeans组件，同时可以在另一个tag中调用它。</p>
		<p>· tag允许相互嵌套，可以在一个JSP页面中完成一些复杂的交互。</p>
		<p>
				<br />使用tag标签</p>
		<p>
				<br />本节主要描述怎样在JSP页面中使用tag标签，以及tag标签的不同类型。</p>
		<p>要使用tag标签，JSP程序员必须做2件事：</p>
		<p>· 声明此tag标签的tag库</p>
		<p>· 实现此tag标签</p>
		<p>声明tag标签所在的tag库</p>
		<p>如果要使用tag标签，则应用JSP的taglib指示符来指定其tag库（注意：taglib要在在使用此tag标签之前声明）</p>
		<p>&lt;%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %&gt;</p>
		<p>uri属性定义了唯一的标签库描述(以下简称TLD)，它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。</p>
		<p>TLD必须以.tld作为扩展名，并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它，也可以通过别的方式间接地引用它。</p>
		<p>以下taglib指示符直接引用一个TLD：</p>
		<p>&lt;%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %&gt;</p>
		<p>以下的taglib指示符通过一个逻辑名称间接地引用一个TLD：</p>
		<p>&lt;%@ taglib uri=”/tutorial-template” prefix=”tt” %&gt;</p>
		<p>如果是间接引用TLD的话，那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射，具体做法是在web.xml中加入一个名为taglib的元素：</p>
		<p>&lt;taglib&gt;</p>
		<p>&lt;taglib-uri&gt;/tutorial-template&lt;/taglib-uri&gt;</p>
		<p>&lt;taglib-location&gt;</p>
		<p>/WEB-INF/tutorial-template.tld</p>
		<p>&lt;/taglib-location&gt;</p>
		<p>&lt;/taglib&gt;</p>
		<p>
				<br />实现此tag标签</p>
		<p>
				<br />为了实现tag标签，你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下，二、如果tag处理类是以JAR包的形式存在的话，那可以放在当前应用的WEB-INF/lib目录下，如果tag处理类要在多个应用中共享，那么它就应放在jsp服务器上的common/lib目录下，对于tomcat来说，就是tomcat/common/lib目录下。</p>
		<p>
				<br />tag标签类型</p>
		<p>
				<br />自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记，有的还有body（即文本节点）：</p>
		<p>&lt;tt:tag&gt;</p>
		<p>body</p>
		<p>&lt;/tt:tag&gt;</p>
		<p>
				<br />一个不带body的tag标签如下：</p>
		<p>&lt;tt:tag /&gt;</p>
		<p>
				<br />简单的tag标签</p>
		<p>一个没有body和属性的tag标签如下：</p>
		<p>&lt;tt:simple /&gt;</p>
		<p>
				<br />带属性的tag标签</p>
		<p>
				<br />自定义标签可以有自己的属性。属性一般在开始标记中定义，语法为 attr=”value”。属性的作用相当于自定义标签的一个参数，它影响着tag处理类的行为。你可以在TLD中详细定义它。</p>
		<p>你可以用一个String常量给一个属性赋值，也可以通过表达式给它赋值，如&lt;%= ...%&gt;。以struts为例，它的logic:present标签就是用的String常量来给属性赋值：</p>
		<p>&lt;loglic:present parameter = “Clear”&gt;</p>
		<p>而另一个标签logic:iterate是用表达式来给属性赋值：</p>
		<p>&lt;logci:iterate collection=”&lt;%= bookDB.getBooks() %&gt;”</p>
		<p>id=”book” type=”database.BookDetails”&gt;</p>
		<p>
				<br />带body的tag标签</p>
		<p>一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。</p>
		<p>在下述例子中，此JSP页面使用了struts的logic:present标签，如果些标签定义了parameter=”Clear”的属性，则将清除购物车的内容，然后打印出一条信息：</p>
		<p>&lt;logic:present parameter=”Clear”&gt;</p>
		<p>&lt;% cart.clear(); %&gt;</p>
		<p>&lt;font color=”#ff0000” size=”+2”&gt;&lt;strong&gt;</p>
		<p>你选择了清除购物车！</p>
		<p>&lt;/strong&gt;&lt;/font&gt;</p>
		<p>&lt;/logic:present&gt;</p>
		<p>
				<br />到底是用属性还是用body来传递信息？</p>
		<p>如上所述，我们既可以通过属性，也可以通过body来传递信息。但一般来说，比较简单的类型，如字符串或简单表达式最好采用属性来传递信息。</p>
		<p>
				<br />定义脚本变量的tag标签</p>
		<p>所谓脚本变量，是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等：</p>
		<p>&lt;tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /&gt;</p>
		<p>&lt;% tx.begin(); %&gt;</p>
		<p>...</p>
		<p>
				<br />具有协作关系的tag标签</p>
		<p>自定义tag标签之间可以通过共享对象来实现协作。在下述例子中，标签tag1创建了一个名为obj1的对象，在标签tag2仍可以重复使用obj。</p>
		<p>&lt;tt:tag1 attr1=”obj1” value1=”value” /&gt;</p>
		<p>&lt;tt:tag2 attr1=”obj1” /&gt;</p>
		<p>在以下这个例子当中，如果外层的tag标签创建了一个对象，那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字，那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。</p>
		<p>&lt;tt:outerTag&gt;</p>
		<p>&lt;tt:innerTag /&gt;</p>
		<p>&lt;/tt:outerTag&gt;</p>
		<p>
		</p>
		<p>Tag处理类</p>
		<p>
				<br />Tag处理类必须实现Tag接口或BodyTag接口，不过现在一般都流行从TagSupport或BodyTagSupport类中继承，这些类或接口都可以在javax.servlet.jsp.tagext包中找到。</p>
		<p>当JSP引擎看到自己的JSP页面中包含有tag标签时，它会调用doStartTag方法来处理tag标签的开头，调用doEndTag方法来处理tag标签的结束。</p>
		<p>下表说明不同类型的tag所需要不同的处理过程：</p>
		<p>Tag处理类的方法 </p>
		<p>Tag标签类型<br />所调用的方法</p>
		<p>基本标签<br />doStartTag, doEndTag, release</p>
		<p>带属性的标签<br />doStartTag, doEndTag, set/getAttribute1...N, release</p>
		<p>带内容的标签<br />doStartTag, doEndTag, release</p>
		<p>带内容的标签，且内容重复循环<br />doStartTag, doAfterBody, doEndTag, release</p>
		<p>带内容的标签，且内容与JSP交互<br />doStartTag, doEndTag, release, doInitBody, doAfterBody, release</p>
		<p>一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互，通过javax.servlet.jsp.PageContext类，tag处理类可以访问JSP中的request、session和application对像。</p>
		<p>如果tag标签是互相嵌套的，那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。</p>
		<p>一般情况都将所有的tag处理类打成了JAR的包，以便于发布。</p>
		<p>
				<br />Tag库描述(简称TLD)</p>
		<p>
				<br />Tag库是用xml语言描述的，TLD包括了tag库中所有tag标签的描述，它一般用来被jsp服务器用来校验tag的语法正确性，或者被jsp开发者用来开发新的标签。</p>
		<p>TLD的文件扩展名必须为.tld，而且必须放在当前WEB应用的WEB-INF目录或其子目录中。</p>
		<p>一个TLD的内容的开头必须遵守标准的XML开头，用于描述DTD和xml的版本，例如：</p>
		<p>&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;</p>
		<p>&lt;!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "<a href="http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd</a>"&gt;<br />TLD必须以&lt;taglib&gt;来作为它的根元素，&lt;taglib&gt;的子元素如下表：</p>
		<p>
				<br />&lt;taglib&gt;的子元素 </p>
		<p>Element<br />Description</p>
		<p>tlib-version<br />Tag库的版本</p>
		<p>jsp-version<br />Tag库所需要的jsp的版本</p>
		<p>short-name<br />助记符，tag的一个别名（可选）</p>
		<p>uri<br />用于确定一个唯一的tag库</p>
		<p>display-name<br />被可视化工具（诸如Jbuilder）用来显示的名称（可选）</p>
		<p>small-icon<br />被可视化工具（诸如Jbuilder）用来显示的小图标（可选）</p>
		<p>large-icon<br />被可视化工具（诸如Jbuilder）用来显示的大图标（可选）</p>
		<p>description<br />对tag库的描述（可选）</p>
		<p>listener<br />参见下面listener元素</p>
		<p>tag<br />参见下面tag 元素</p>
		<p>Listener元素</p>
		<p>一个tag库可能定义一些类做为它的事件侦听类，这些类在TLD中被称为listener 元素，jsp服务器将会实例化这些侦听类，并且注册它们。Listener元素中有一个叫listener-class的子元素，这个元素的值必须是该侦听类的完整类名。</p>
		<p>Tag元素</p>
		<p>每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略，它的值是否可以通过&lt;%= …%&gt;这样的JSP语法来获得，以及属性的类型。</p>
		<p>每一个tag在TLD中对应一个tag元素，下表是tag元素的子元素：</p>
		<p>Tag元素的子元素</p>
		<p>元素名称<br />描述</p>
		<p>name<br />独一无二的元素名</p>
		<p>tag-class<br />Tag标签对应的tag处理类</p>
		<p>tei-class<br />javax.servlet.jsp.tagext.TagExtraInfo的子类，用于表达脚本变量（可选）</p>
		<p>body-content<br />Tag标签body的类型</p>
		<p>display-name<br />被可视化工具（诸如Jbuilder）用来显示的名称（可选）</p>
		<p>small-icon<br />被可视化工具（诸如Jbuilder）用来显示的小图标（可选）</p>
		<p>large-icon<br />被可视化工具（诸如Jbuilder）用来显示的大图标（可选）</p>
		<p>description<br />此tag标签的描述</p>
		<p>variable<br />提供脚本变量的信息（同tei-class）(可选)</p>
		<p>attribute<br />Tag标签的属性名</p>
		<p>以下章节介绍对于不同类型的tag，如何具体地实现它们。</p>
		<p>
				<br />简单的tag</p>
		<p>
				<br />tag处理类</p>
		<p>简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时，doStartTag被调用，因为简单的tag没有body，所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时，doEndTag被调用，如果余下的页面还要被计算，那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。</p>
		<p>以下是例子：对于标签 &lt;tt:simple /&gt; ，它的tag处理类实现如下：</p>
		<p>
				<br />public SimpleTag extends TagSupport </p>
		<p>{ </p>
		<p>public int doStartTag() throws JspException </p>
		<p>{ </p>
		<p>try{ </p>
		<p>pageContext.getOut().print(“Hello.”); </p>
		<p>}catch(Exception e){ </p>
		<p>throw new JspTagException(“SimpleTag: “ + e.getMessage()); </p>
		<p>} </p>
		<p>return SKIP_BODY; </p>
		<p>} </p>
		<p>public int doEndTag() </p>
		<p>{ </p>
		<p>return EVAL_PAGE; </p>
		<p>} </p>
		<p>} </p>
		<p>
				<br />注意：如果tag标签没有内容的话，那必须定义body-content元素为空，例如</p>
		<p>&lt;body-content&gt;empty&lt;/body-content&gt;</p>
		<p>
				<br />带属性的tag标签</p>
		<p>
				<br />tag处理类</p>
		<p>对于tag标签的每个属性，你必须依照JavaBeans规范来定义其属性，以及get和set方法。以struts的logic:present 标签为例，</p>
		<p>&lt;logic:present parameter=”Clear”&gt;</p>
		<p>与此相应，此tag处理类应有如下方法和定义：</p>
		<p>
				<br />protected String parameter = null; </p>
		<p>public String getParameter() </p>
		<p>{ </p>
		<p>return this.parameter; </p>
		<p>} </p>
		<p>public void setParameter(String parameter) </p>
		<p>{ </p>
		<p>this.parameter = parameter; </p>
		<p>} </p>
		<p>
				<br />注意：如果你的属性名为id，而且你的tag处理类是从TagSupport类继承的，那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。</p>
		<p>Attribute元素</p>
		<p>对于tag标签的每个属性，你必须定义它是否必须的，它的值是否可以用诸如&lt;%= …%&gt;的表达式来获得，以及它的类型（可选），如果不指定它的类型，那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes，那么在type元素中就定义了attribute的返回类型。</p>
		<p>&lt;attribute&gt;</p>
		<p>&lt;name&gt;attr1&lt;/name&gt;</p>
		<p>&lt;required&gt;true|false|yes|no&lt;/required&gt;</p>
		<p>&lt;rtexprvalue&gt;true|false|yes|no&lt;/rtexprvalue&gt;</p>
		<p>&lt;type&gt;attribute的返回类型（只用当rtexprvalue为真是才有效）&lt;/type&gt;</p>
		<p>&lt;/attribute&gt;</p>
		<p>如果tag的某个属性不是必须的，那tag处理类会自动提供一个缺省值。</p>
		<p>例如，在logic:present这个tag标签中定义了一个属性叫parameter，但它不是必须的，而且它可以被诸如&lt;%= …%&gt;的表达式来赋值。</p>
		<p>&lt;tag&gt;</p>
		<p>&lt;name&gt;present&lt;/name&gt;</p>
		<p>&lt;tag-class&gt;org.apache.struts.taglib.logic.PresentTag&lt;/tag-class&gt;</p>
		<p>&lt;body-content&gt;JSP&lt;/body-content&gt;</p>
		<p>…</p>
		<p>&lt;attribute&gt;</p>
		<p>&lt;name&gt;parameter&lt;/name&gt;</p>
		<p>&lt;required&gt;false&lt;/required&gt;</p>
		<p>&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;</p>
		<p>&lt;/attribute&gt;</p>
		<p>…</p>
		<p>&lt;/tag&gt;</p>
		<p>
				<br />属性元素的校验</p>
		<p>
				<br />有关于tag标签的有效值可以从tag库的说明文档中获得，当JSP页面被编译时，jsp引擎会强制性地参照TLD中定义的规则进行检查。</p>
		<p>还有一个方法也可以进行属性元素的校验，就是先继承类TagExtraInfo，然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。</p>
		<p>IsValid方法通过TagData对象来传递属性信息，它包括着tag的所有的属性名－值的信息。由于校验发生在运行时刻，因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。</p>
		<p>例如tag标签&lt;tt:twa attr1=”value1” /&gt;在TLD中定义如下：</p>
		<p>&lt;attribute&gt;</p>
		<p>&lt;name&gt;attr1&lt;/name&gt;</p>
		<p>&lt;required&gt;true&lt;/required&gt;</p>
		<p>&lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;</p>
		<p>&lt;/attribute&gt;</p>
		<p>
				<br />这个定义说明了attr1能在运行期间被赋值。</p>
		<p>以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值，那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。</p>
		<p>
				<br />Public class TwaTEI extends TagExtraInfo </p>
		<p>{ </p>
		<p>public boolean isValid(Tagdata data) </p>
		<p>{ </p>
		<p>Object o = data.getAttribute(“attr1”); </p>
		<p>If(o != null &amp;&amp; o != TagData.REQUEST_TIME_VALUE) </p>
		<p>{ </p>
		<p>if( ( (String)o).toLowerCase().equals(“true”) ||  </p>
		<p>((String)o).toLowerCase().equals(“false”) ) </p>
		<p>return true; </p>
		<p>else </p>
		<p>return false; </p>
		<p>} </p>
		<p>else </p>
		<p>return true; </p>
		<p>} </p>
		<p>} </p>
		<p>
		</p>
		<p>带body的tag</p>
		<p>
		</p>
		<p>tag处理类</p>
		<p>
				<br />如果tag标签含有内容，那处理方式会略微有些不同，而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互，那我们认为tag处理类要可能要对body进行操作。</p>
		<p>Tag处理类不与body交互</p>
		<p>如果tag处理类不与body交互，tag处理类应该实现Tag接口或从TagSupport中派生，如果body要被计算，那么doStartTag方法应返回 EVAL_BODY_INCLUDE，否则应返回SKIP_BODY。</p>
		<p>如果tag处理类要对body反复运算，则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话，那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。</p>
		<p>Tag处理类与body交互</p>
		<p>如果tag处理类与body交互，那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。</p>
		<p>Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息，也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。</p>
		<p>如果body的内容需要被计算，那么doStartTag方法必须返回EVAL_BODY_BUFFERED，否则，它将返回 SKIP_BODY。</p>
		<p>doInitBody 方法</p>
		<p>此方法在body内容已经设好，但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。</p>
		<p>doAfterBody方法</p>
		<p>此方法在body内容已被计算后进行调用。</p>
		<p>和doStartTag方法一样，doAfterBody方法返回一个指示符指示是否要继续计算body，如果要继续计算，则doAfterBody应返回EVAL_BODY_BUFFERED，否则，它应返回SKIP_BODY。</p>
		<p>release 方法</p>
		<p>tag处理类调用此方法将它的状态重置为初始状态，并释放所有的私有资源。</p>
		<p>
				<br />以下的例子读取body的内容（其中含有一条sql语句），然后将它传递给一个对象，让它进行查询。由于此处body不须重新计算，所以doAfterBody会返回SKIP_BODY。</p>
		<p>
				<br />Public class QueryTag extends BodyTagSupport </p>
		<p>{ </p>
		<p>public int doAfterBody() throws JspTagException </p>
		<p>{ </p>
		<p>BodyContent bc = getBodyContent(); </p>
		<p>//将body的内容以字符串的格式提取出来 </p>
		<p>String query = bc.getString(); </p>
		<p>//清除body </p>
		<p>bc.clearBody(); </p>
		<p>try{ </p>
		<p>Statement stmt = connection.createStatement(); </p>
		<p>Result result = stmt.executeQuery(query); </p>
		<p>}catch(SQLException e){ </p>
		<p>throw new JspTagException(“queryTag: “ + e.getMessage() ); </p>
		<p>return SKIP_BODY; </p>
		<p>} </p>
		<p>} </p>
		<p>
				<br />body-content元素</p>
		<p>
				<br />由于tag可能会有body，你必须用body-content元素来指定body内容的类型：</p>
		<p>&lt;body-content&gt;JSP|tagdependent&lt;/body-content&gt;</p>
		<p>
				<br />如果body的内容是定制的或内部的tag、脚本元素、或HTML广本，则归类为JSP类型。其他的类型，比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。</p>
		<p>注意：实际上body-content的值并不影响tag处理类对body内容的处理，它仅仅是被tag编辑工具用来描述此body的内容。</p>
		<p>
				<br />用tags定义脚本变量</p>
		<p>
		</p>
		<p>tag处理类</p>
		<p>
				<br />tag处理类负责创建或设置页面中定义的脚本变量，用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说，tag处理类通过脚本变量的名称来获取它，脚本变量的名称一般可用get方法来获得。</p>
		<p>如果脚本变量的值依赖于tag处理类中的上下文中某一对象，那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量，再对其进行处理，然后用pageContext.setAttribute(name,object)的方法来设置它的新值。</p>
		<p>对象的生存周期(scope)如下表：</p>
		<p>对象的生存周期表</p>
		<p>名字<br />可访问范围<br />生存周期</p>
		<p>page<br />当前页面<br />一直有效，除非页面向客户提交响应或重定向到一个新页面</p>
		<p>request<br />当前页面或当前页面重定向到的页面<br />一直有效，除非页面向客户提交响应</p>
		<p>session<br />当前页面或在同一浏览器窗口中的页面<br />一直有效,除非关闭当前浏览器、超时、网络故障</p>
		<p>application<br />整个web应用程序的所有请求<br />一直有效，除非发生网络故障、服务器故障</p>
		<p>提供关于脚本变量的信息</p>
		<p>以下示例定义了一个名为“book”的脚本变量，用来访问程序中关于书的信息：</p>
		<p>&lt;bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /&gt;</p>
		<p>&lt;font color=”red” size=”+2” &gt;</p>
		<p>&lt;%= messages.getString(“CartRemoved”) %&gt;</p>
		<p>&lt;strong&gt;&lt;jsp:getProperty name=”book” property=”title” /&gt;&lt;/strong&gt;</p>
		<p>&lt;/font&gt;</p>
		<p>当包含此tag的JSP页面被编译时，jsp引擎会自动生成关于此book的同步的代码（同步可以避免几个客户同时访问此book时造成的冲突），要生成同步代码，jsp引擎需要知道此脚本变量的如下信息：</p>
		<p>· 脚本变量名称 </p>
		<p>· 脚本变量所属的类</p>
		<p>· 此脚本变量是否引用了一个新的或已存在的对象 </p>
		<p>· 此脚本变量的有效性</p>
		<p>有两种办法可以向jsp引擎提供关于脚本变量的信息：在TLD中定义variable子元素，或用tei-class子元素定义一个额外tag信息类。用variable最简单，但可能降低了一些灵活性。</p>
		<p>Variable元素</p>
		<p>Variable元素有如下子元素：</p>
		<p>· name-given ?D?D 给出的名字，是一个常量</p>
		<p>· name-from-attribute?D?D 属性名，在编译时给出的属性名 </p>
		<p>name-given或name-from-attribute两者必须选一，但以下子元素是可选的：</p>
		<p>· variable-class?D?D变量的类型，缺省为java.lang.String。 </p>
		<p>· declare?D?D此脚本变量是否引用了一个新对象，缺省为True。</p>
		<p>· scope?D?D脚本变量的范围，缺省为NESTED。下表描述了scope的几种类型：</p>
		<p>脚本变量的有效范围 </p>
		<p>值<br />有效性<br />方法 </p>
		<p>NESTED<br />在tag标签的开始和结束之间<br />如果tag处理类实现BodyTag接口，则在doInitBody和doAfterBody中调用，否则在doStartTag中调用</p>
		<p>AT_BEGIN<br />从tag标签的开始一直到页面结束<br />如果tag处理类实现BodyTag接口，则在doInitBody、doAfterBody和doEndTag中调用，否则在doStartTag和doEndTag中调用</p>
		<p>AT_END<br />从tag标签的结束一直到页面结束<br />在doEndTag中调用</p>
		<p>以struts为例，它的bean:define标签的实现遵循JSP1.1规范，此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例，你可以定义如下variable元素：</p>
		<p>&lt;tag&gt;</p>
		<p>&lt;variable&gt;</p>
		<p>&lt;name-from-attribute&gt;id&lt;/name-from-attribute&gt;</p>
		<p>&lt;variable-class&gt;database.BookDetails&lt;/variable-class&gt;</p>
		<p>&lt;declare&gt;true&lt;/declare&gt;</p>
		<p>&lt;scope&gt;AT_BEGIN&lt;/scope&gt;</p>
		<p>&lt;/variable&gt;</p>
		<p>&lt;/tag&gt;</p>
		<p>额外tag信息类</p>
		<p>如果要定义一个额外tag信息类，你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法，此方法返回一个叫VariableInfo的数组类，它包括如下信息：</p>
		<p>· 变量名</p>
		<p>· 变量所属类名 </p>
		<p>· 此变量是否引用了一个新对象</p>
		<p>· 此变量的有效范围</p>
		<p>jsp引擎将一个名为data的参数传给getVariableInfo方法，data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。</p>
		<p>以struts为例，它在bean:define标签中定义了一个名为DefineTei的额外tag信息类，用来向脚本变量提供信息。由于脚本变量的名称（book）和类名（database.BookDetails）是通过tag标签的属性来传递的，它们一般定义在VariableInfo的构建代码中，并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话，那它的范围应设为AT_BEGIN。如下所示：</p>
		<p>
				<br />public class DefineTei extends TagExtraInfo </p>
		<p>{ </p>
		<p>public VariableInfo[] getVariableInfo(TagData data) </p>
		<p>{ </p>
		<p>String type = data.getAttributeString(“type”); </p>
		<p>If( type == null) </p>
		<p>type = “java.lang.Object”; </p>
		<p>return new VariableInfo[] { </p>
		<p>new VariableInfo(data.getAttributeString(“id”),  </p>
		<p>type, </p>
		<p>true, </p>
		<p>VariableInfo.AT_BEGIN) </p>
		<p>}; </p>
		<p>} </p>
		<p>} </p>
		<p>
				<br />注意：关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此，DefineTei的tei-class中的定义看起来如下：<br />&lt;tei-class&gt;<br />org.apache.struts.taglib.bean.DefineTagTei<br />&lt;/tei-class&gt;</p>
		<p>
				<br />具有协作关系的tag</p>
		<p>
				<br />tag通过共享对象来进行协作，JSP技术支持2种方式的对象共享。</p>
		<p>第一种方法是使用pageContext对象进行对象的共享（可支持JSP页面和tag处理类之间的共享），如果在一个tag处理类中要调用由另一个tag处理类创建的对象，可调用pageContext.getAttribute(name, scope)方法。</p>
		<p>第二各方式的共享是对于tag之间有嵌套关系而言的，外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。</p>
		<p>要访问一个嵌套tag创建的对象，tag处理类必须先找到此嵌套tag对象，可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到，它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员，而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存，用getValue方法来获得。</p>
		<p>下例阐述了以上两种共享对象的方法。在这个例子当中，一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置，tag处理类从pageContext中得到这个connection对象。否则，此tag处理类先找到它的父tag处理类，然后从它的父tag处理类中找到connection对象。</p>
		<p>
				<br />public class QueryTag extends BodyTagSupport </p>
		<p>{ </p>
		<p>private String connectionId; </p>
		<p>public int doStartTag() throws JspException </p>
		<p>{ </p>
		<p>String cid = getConnection(); </p>
		<p>if(cid != null) </p>
		<p>{ </p>
		<p>//存在一个connection id，使用它。 </p>
		<p>connection = (Connection) pageContext.getAttribute(cid); </p>
		<p>} </p>
		<p>else </p>
		<p>{ </p>
		<p>ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this,  </p>
		<p>ConnectionTag.class); </p>
		<p>if(ancestorTag == null) </p>
		<p>{ </p>
		<p>throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); </p>
		<p>} </p>
		<p>connection = ancestorTag.getConnection(); </p>
		<p>} </p>
		<p>} </p>
		<p>}  </p>
		<p>
		</p>
		<p>
				<br />此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种：</p>
		<p>
		</p>
		<p>&lt;tt:connection id=”con01” ...&gt; ... &lt;/tt:connection&gt;</p>
		<p>&lt;tt:query id=”balances” connection=”con01” &gt;</p>
		<p>SELECT account, balance FROM acct_table</p>
		<p>where customer_num = &lt;%= request.getCustno() %&gt;</p>
		<p>&lt;/tt:query&gt;</p>
		<p>
		</p>
		<p>或</p>
		<p>&lt;tt:connection ...&gt;</p>
		<p>&lt;x:query id=”balances”&gt;</p>
		<p>SELECT account, balance FROM acct_table</p>
		<p>where customer_num = &lt;%= request.getCustno() %&gt;</p>
		<p>&lt;/x:query&gt;</p>
		<p>&lt;/tt:connection&gt;</p>
		<p>
		</p>
		<p>与此同时，在TLD中必须指定connection属性为可选的，定义如下：</p>
		<p>&lt;tag&gt;</p>
		<p>...</p>
		<p>&lt;attribute&gt;</p>
		<p>&lt;name&gt;connection&lt;/name&gt;</p>
		<p>&lt;required&gt;false&lt;/required&gt;</p>
		<p>&lt;/attribute&gt;</p>
		<p>&lt;/tag&gt;<br /> <br /></p>
<img src ="http://www.blogjava.net/jelver/aggbug/73954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-09 09:13 <a href="http://www.blogjava.net/jelver/articles/73954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 标签库的深入研究</title><link>http://www.blogjava.net/jelver/articles/73943.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 09 Oct 2006 00:57:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73943.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73943.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73943.html</trackback:ping><description><![CDATA[
		<p>标签库Taglib<br /><br />标签被定义和分布在一个称为标签库的结构中，一个标签库是由元信息和类组成的集合：<br />1.标签处理器：实现定制标签功能的Java类。<br />2.标签附加信息（TEI）：向JSP容器提供边辑以确认标签属性和创建变量的类。<br />3.标签库描述器（TLD）：描述单个标签和整个标签库属性的XML文档。<br /><br />标签处理器和标签附加信息需要定位在JSP容器类载入器可以找到的地方。标签库描述器可在URL指定的符意位置。JSP1.1规范要求JSP容器接受一个打包成因定结构的JAR文件的标签库。TLD必须是/META-INF目录中名为taglib.tld的文件，JAR文件则复制到/WEB-INF/lib目录下。<br /><br />一、标签实现<br /><br />1.开发步骤<br />a.定义标签的名字、属性、声明的变量和标签体的内容。<br />b.编写标签库描述器TLD。<br />c.编写标签处理器。<br />d.在JSP页面中使用标签。<br /><br />2.JSP页面在JSP容器中的转换步骤：<br />JSP页面存在三种形式：jsp文件、java文件和class文件。<br />a.指令元素&lt;%@page%&gt;、&lt;%@include%&gt;和&lt;%@taglib%&gt;向JSP容器提供转换时信息。<br />b.HTML行在_jspService()方法中依顺序转换到out.print()语名中。<br />c.脚本元素的声明被原封不动地复制到_jspService()方法外的源码中。<br />d.脚本元素的表达式在_jspService()方法中依顺序转换到out.print()语名中。<br />e.脚本元素的Scriptlet被原封不动地复制到_jspService()方法中。<br />f.行为元素被转换为执行其功能的运行时逻辑代码。<br />g.定制标签被扩展到调用其相应标签处理器中方法的Java语句中。<br /><br />3.标签在JSP容器中的转换步骤：<br />a.JSP容器使用taglib指令元素定位标签库描述器，将页面中用到的定制标签和TLD相匹配。<br />b.读取标签库描述器的标签列表和每一标签相关的类名字。<br />c.在页面中遇到一个标签时，查找与具有指定名字的标签前缀相关的一个标签库。<br />d.容器使用在TLD中找到的标签结构信息生成一系列完成标签功能的Java语句。<br /><br /><br />二、标签库描述器（TLD）<br /><br />标签库描述器是一个描述整个标签库标记信息和库中每个标签处理器及其属性的XML文档。<br /><br />标签库描述器的DTD由一个简单的&lt;taglib&gt;元素组成，此元素包含下列一些子元素。<br />整个标签库标记信息<br />tlibversion    标签库版本号。是一个点式十进制数，最多为4组小数点分隔的数字组成。<br />jspversion    标签库所需的JSP规范最低版本。例如JSP1.1<br />shortname    标签库的缩写名。JSP可以使用该名字作为库中标签的缺省前缀。<br />uri    标签库唯一URI的元素。典型URL位置来自可下载taglib的位置。<br />info    标签库描述信息。<br />每个标签处理器及其属性<br />tag    在TLD中加入标签，描述组成库的每个标签。<br />name    与标签库的名字前缀一起使用的标签的名字， 是JSP容器唯一的标签标识。<br />tagclass    实现标签的标签处理器类的全名。<br />teiclass    标签附加信息（TEI）类的全名。TEI类给出关于标签处理器创建变量及对标签司性执行的任意有效性验证的信息。<br />bodycontent    描述标签处理器如何使用标签体的内容。有三种取值：<br />    empty：表示标签体必须为空；<br />    JSP:表示脚本元素和模板及其它标签一样被评估。<br />    tagdependent：体内容被原封不动写入BodyContent，其它脚本元素以源码形式出现，而不被JSP容器解释。<br />info    标签的人工可读描述性信息。<br />attribute    使用标签时被编码的属性信息。用于定义标签的属性。<br />    &lt;name&gt;属性名&lt;/name&gt;：属性的名字。<br />    &lt;request&gt;true|false&lt;/request&gt;：属性在标签用到的位置是否要被编码。<br />    &lt;rtxexpvalue&gt;true|false&lt;/rtxexpvalue&gt;：属性值能否用表达式指定。<br /><br />三、标签处理器<br /><br />标签处理器是通过实现JSP容器调用的一系列预定义方法执行定制标签行为的一个Java类。<br />标签处理器实现了标签的行为，标签处理器是Java类。<br /><br />1.标签处理器的工作方式<br />a.导入javax.servlet.jsp和javax.servlet.jsp.tagext包。<br />b.实现javax.servlet.jsp.tagext包中的Tag接口或BodyTag接口。BodyTag是Tag的子接口。<br />c.继承TagSupport类或BodyTagSuppoert类。它们是上述接口的缺省实现。<br />d.重载public int doStartTag()throws JspException方法。<br /><br />2.标签处理器的接口与实现<br />javax.servlet.jsp.tagext.Tag是实现标签的最基本的接口。<br />javax.servlet.jsp.tagext.TagSupport是实现Tag接口的具体类。<br />通常情况下继承tagSupport类而不直接实现Tag接口通常是有益的。除了对所有必需方法提供了缺省实现外、还保存了pageContext对象及对嵌套标签的支持。<br />Tag接口包含4个常量，表示doStartTag()和doEndTag()方法可能的返回码。<br />EVAL_BODY_INCLUDE    当doStartTag()返回时，指明servlet应对标签体进行评估。<br />SKIP_BODY    当doStartTag()返回时，指明servlet应忽视标签体。<br />EVAL_PAGE    当doEndTag()返回时，指明页面其余部分应被评估。<br />SKIP_PAGE    当doEndTag()返回时，指明页面其余部分就被跳过。<br />Tag接口的方法<br />public void setPageContext (PageContext ctx)    生成的servlet在请求处理器执行其它任务前首先调用此方法，实现类应保存上下文对象以便它可以在标签生命期中使用。从页面上下文中标签处理器可以访问所有JSP隐含对象。<br />public void setParent(Tag p)    使用一个标答可以找到操作栈中它上面的标签。在setPageContext后立即调用。<br />public Tag getParent()    返回父标签。<br />public int doStartTag() throws Jsp    在设置了页面上下文、父标签和开始标记中编码的属性后调用。返回码表明JSP实现servlet是否就评估标签体。<br />public int doEndTag()throws JspException    当遇到结否标记时调用。返回码表明JSP是否就继纽页面的其余部份。<br />public void release()    确保在页面退出前被调用。释放资源并重置标签处理器状态。<br />TagSupport类的方法<br />public static Tag finAncestorWithClass(Tag thisTag, Class cls)    为所需的父标签处理器查找运行时标签栈。一个标签处理器可以提供其范围内子标签调用的方法。<br />public void setId(String id)    保存和检索在id属性中指定的名字。<br />public void setValue(String name, Object o)    在本地哈希表中设置指定名字的值。<br />public Object getValue (String name)    从本地哈希表中获取指定名称的值。<br />public void removeValue (String name)    从本地哈希表中删除指定名称的值。<br />public Enumeration getValues()    返回哈希表中关键字的一个枚举。<br /><br />3.标签处理器的生命期<br />a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器的工厂类的一个方法，工厂类包含一个标签处理器实例池以使其可重用不再处于激活状态的对象。<br />b.初始化标签处理器，使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程：setPageContext(PageContext ctx)和setParent(Tag parent)。<br />c.如果标签具有属性，属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。<br />d.页面的上下文和父标签已被调置，并已具备属性。此时调用标签处理器的doStartTag()方法，该方法可以读取这些变量并执行实现标答功能所需的计算和操作。doStartTag()方法必须返回一个整型数。返回EVAL_BODY_INCLUDE则正常处理标签体，返回SKIP_BODY则从初始JSP页面中直到此标签结束标记处的内容均被忽略。<br />e.标签体被评估或忽视后调用标签处理器的doEndTag()方法，返回EVAL_PAGE则页面的其余部分被评估，返回SKIP_PAGE则servlet代码立即从_jspService()中返回。<br /><br />4.体标签处理器的接口与实现<br />javax.servlet.jsp.tagext.BodyTag是Tag的子接口。<br />javax.servlet.jsp.tagext.BodyTagSupport是实现BodyTag类。<br />BodyContent是javax.servlet.jsp.JspWriter的子类，但与其父类有所区别。<br />BodyContent对象的内容不自动写了入servlet的输出流，而是积累在一字符串缓存中。当标签体完成后其对象仍可在doEndTag()方法中可以应用，由getString()或getReader()方法操作。并在必要时修改及写入恢复的JspWriter输出流。<br />BodyContent类的方法<br />public void flush()throws IOException    复写JspWrite.flush()方法以便它总是产生溢出。刷新写入已失效，因为它没有连接到将被写入的实际输出流中。<br />public void clearBody()    重置BodyContent缓存为空。<br />public Reader getReader()    返回Reader读取体内容。<br />public String getString()    返回包含体内容的一个字符串。<br />public void writeOut(Write w)    将体内容写入指定输出。<br />public JspWrite getEnclosing Write()    返回栈中下一个更高的写入者对象（可能是另一个BodyContent对象）。<br />BodyTag接口定义了一个新的整型常量<br />EVAL_BODY_TAG    当doStartTag()返回时，使得新的BodyContent对象被创建并与此标签处理器相关联。当doAfterBody()返回时，使得JSP servlet在修改完此标签控制的任意变量后再次评估体。<br />BodyTag接口的方法<br />public void setBodyContern (BodyContent out)    在当前JspWriter已被写入，一个新的BodyContent在被创建后由Jsp servlet调用，它发生在doStartTag()之后。<br />public void doInitBody() throws JspException    setBodyContent()之后，体被评估前调用的生命期方法。如果多次评估体，此方法只调用一次。<br />public init doAfterBody() throws JspException    体被评估后，BodyContent写入者仍处于激活状态时调用的生命期方法。此方法必须返回EVAL_BODY_TAG或SKIP_BODY，若返回EVAL_BODY_TAG时体再次被评估。<br />BodyTagSupport类的方法<br />public int doStartTag() throws JspException    复写TagSupport中的doStartTag()方法。<br />public int doEndTag() throws JspException    调用TagSupport中的doEndTag()方法，返回结果。<br />public void setBodyContent (BodyContent out)    在一保护成员变量bodyContent中保存新的体内容对象，子类可直接访问此对象。<br />public void doInitBody() throws JspException    缺省什么都不做。被需要执行初始化的子类所复写。<br />public int doAfterBody() throws JspException    每次体被评估后由JSP servlet调用，体同容对象仍处于激活状态。返回SKEP_BODY或EVAL_BODY_TAG则体再次被评估<br />public void release()    设置bodyContent对象为null，然后调用super.release()。<br />public BodyContent getBodyContent()    返回bodyContent变量。子类已经可以访问保护变量，但此方法允许无关的标签处理类对此体内容发送输出。<br />public JspWriter getPreviousOut()    在bodyContent变量上调用getEnclosingWriter()并返回结果的简便方法。<br /><br />5.体标签处理器的生命期<br /><br />a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器的工厂类的一个方法，工厂类包含一个标签处理器实例池以使其可重用不再处于激活状态的对象。<br />b.初始化标签处理器，使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程：setPageContext(PageContext ctx)和setParent(Tag parent)。<br />c.如果标签具有属性，属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。<br />d.页面的上下文和父标签已被调置，并已具备属性。调用标签处理器的doStartTag()方法，该方法可以读取这些变量并执行实现标答功能所需的计算和操作。<br />doStartTag()方法必须返回一个整型数。<br />返回EVAL_BODY_TAG则正常处理标签体（跳到e）；<br />返回SKIP_BODY则从初始JSP页面中直到此标签结束标记处的内容均被忽略。（跳到f）<br />e.如果返回EVAL_BODY_TAG时，则正常处理标签体。<br />    e1.在栈中保存当前的JspWriter对象，创建新的BodyContent对象，并将其置为JSP页面的out对象保存在上下文范围内名为name的属性中。并调用它的setBodyContent()方法。<br />    e2.调用doInitBody()方法进行初始化。<br />    e3.处理标签体。将输出写入BodyContent对象中，此过程依赖于TLD的标签元素&lt;bodycontent&gt;，有三种可能取值。<br />    e4.调用doAfterBody()方法，将体内体内容写入JspWriter，可如下实现：<br />JspWriter out=bodyContent.getEnclosingWriter();<br />out.println(bodyContent.getString());//bodyContent.writeOut(out);<br />bodyContent.clear();<br />    e5.doAfterBody()方法返回两种可能：<br />返回EVAL_BODY_TAG时，再对标签体进行评估，这是数组和枚举被循环处理的典型情况。<br />    返回SKIP_PAGE时，继续页面的其余部份。<br />e6.体内容完成，因此创建它的过程被反向：<br />    调用pageContent.popBody()方法检索前面的JspWriter对象。<br />    将写入者设置回out隐含对象。<br />f.标签体被评估或忽视后调用doEndTag()方法，允许标签处理器像输出流发回内容。<br />返回EVAL_PAGE则页面的其余部分被评估；<br />返回SKIP_PAGE则servlet代码立即从_jspService()中返回。<br />g. 此时体的内容在受保护的bodyContent对象中仍然可用。<br />可以将它写入servlet输出流中：<br />JspWriter out=pageContext.getOut();<br />out.println(bodyContent.getString());<br />或者<br />bodyContent.WriteOut(pageContext.getOut());<br /><br />6.标签附加信息类<br /><br /><br />四、标签指令<br /><br />taglib指令元素的目的是指定TLD的位置，设置在页面上与标签区分开来的一个短别名。<br />语法：&lt;%@ taglib prefix=”tag prefix” uri=”taglibURI” %&gt;<br />属性：prefix：用于标识标签库的唯一标识。uri：标签库本身的URI。<br />uri不必指向一个实际文件，它是JSP容器可以在web.xml中查找实际文件位置的唯一标识符。</p>
		<p>引自：<a href="http://www.javaresearch.org/article/showarticle.jsp?column=106&amp;thread=51309" target="_blank">http://www.javaresearch.org/article/showarticle.jsp?column=106&amp;thread=51309</a></p>
		<br />
<img src ="http://www.blogjava.net/jelver/aggbug/73943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-09 08:57 <a href="http://www.blogjava.net/jelver/articles/73943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用定制标签库和配置文件实现对JSP页面元素的访问控制</title><link>http://www.blogjava.net/jelver/articles/73941.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 09 Oct 2006 00:56:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73941.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73941.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73941.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73941.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73941.html</trackback:ping><description><![CDATA[
		<p>控制客户端访问是开发一个基于B/S的架构的系统的开发者必须考虑的问题。JSP或SERVLET规范的基于配置文件的安全策略对资源的控制是以文件为单位的，即只可以定义某个视图全部可以或全部不能被访问。一个比较复杂的系统往往要要求对视图的一部分（如JSP页面里的一个按钮）提供访问控制，只允许被某种角色的用户访问。如果采用可编程的安全策略，因为对用户角色和操作的定义在开发时不能定义，而且这种策略加大了程序员的工作量，它可能不是一种好的办法。</p>
		<p>       我采用定制标签库和和配置文件来解决这个问题：把要权限控制的JSP页面元素如BUTTON，作为标签的内容。为受保护的内容起一个唯一的名称，把这个名称作为标签的一个属性。某个角色对某个页面元素或一组页面元素是否有权限，在XML配置文件中描述。</p>
		<p> </p>
		<p>       例如，下面的JSP页面有“详细”和“修改”两个按钮。 </p>
		<p>&lt;%@ taglib uri="<a href="http://mytag">http://mytag</a>" prefix="custTag" %&gt;</p>
		<p>&lt;html&gt;</p>
		<p>&lt;head&gt;</p>
		<p>&lt;title&gt;test&lt;/title&gt;</p>
		<p>&lt;/head&gt;</p>
		<p>&lt;body &gt;</p>
		<p>&lt;form name="form1" &gt;</p>
		<p>   &lt;table width="600" border="0" cellspacing="0" cellpadding="2" &gt;</p>
		<p>      &lt;tr&gt;</p>
		<p>       &lt;td&gt;</p>
		<p>            &lt;custTag:JspSecurity elementName="employeedetail" &gt;</p>
		<p>              &lt;input type="button" name="detail"  value="详细" &gt;</p>
		<p>            &lt;/custTag:JspSecurity&gt;</p>
		<p>            &lt;custTag:JspSecurity elementName="employeemodify" &gt;</p>
		<p>              &lt;input type="button" name="modify"  value="修改" &gt;</p>
		<p>            &lt;/custTag:JspSecurity&gt;</p>
		<p>        &lt;/td&gt;</p>
		<p>      &lt;/tr&gt;</p>
		<p>&lt;/table&gt;</p>
		<p>&lt;br&gt;</p>
		<p>&lt;/form&gt;</p>
		<p>&lt;/body&gt;</p>
		<p> </p>
		<p>       下面XML配置文件内容表示对角色为common的用户，只对名为employeedetail 的页面元素即“详细”按钮有权限，对角色为“admin”的用户，对名为employeedetail 和employeemodify的页面元素即两个按钮都有权限。</p>
		<p>&lt;?xml version="1.0" encoding="GB2312"?&gt;</p>
		<p>&lt;security&gt;</p>
		<p>&lt;htmlElement name="employeedetail" &gt;</p>
		<p>&lt;roleName name="common" /&gt;</p>
		<p>&lt;roleName name="admin" /&gt;</p>
		<p>&lt;/htmlElement&gt;</p>
		<p>&lt;htmlElement name="employeemodify" &gt;</p>
		<p>&lt;roleName name="admin" /&gt;</p>
		<p>&lt;/htmlElement&gt;</p>
		<p>&lt;/security&gt;</p>
		<p> </p>
		<p>       定制标签类JspSecurityTag继承了BodyTagSupport类。BodyTagSupport有一个变量bodyContent指向起始标志和结束标志之间的内容。JspSecurityTag的私有静态变量roleList保存从XML文件中取到角色和页面元素的对应集合，私有变量ElementName对应页面元素的名称。当解析该定制标签时，首先先取到页面元素的名称，再取到当前用户的角色，如果角色有该页面元素的权限，就显示标签正文（即页面元素），否则不显示。</p>
		<p> </p>
		<p>Pagekage com.presentation.viewhelper.JspSecurityTag;</p>
		<p> </p>
		<p>import javax.servlet.jsp.tagext.*;</p>
		<p>import javax.servlet.jsp.*;</p>
		<p>import java.util.*;</p>
		<p>import org.xml.sax.*;</p>
		<p>import org.xml.sax.helpers.*;</p>
		<p>import org.w3c.dom.*;</p>
		<p>import java.io.*;</p>
		<p>import javax.xml.parsers.*;</p>
		<p> </p>
		<p>public class JspSecurityTag extends BodyTagSupport {</p>
		<p>  //保存从XML文件中取到角色和页面元素的对应集合</p>
		<p>  private static ArrayList roleList;</p>
		<p>  //页面元素的名称</p>
		<p>  private String elementName;</p>
		<p> </p>
		<p>  public void setElementName(String str)</p>
		<p>  {</p>
		<p>    this.elementName=str;</p>
		<p>  }</p>
		<p> </p>
		<p>  public int doAfterBody() throws JspException{</p>
		<p>    if(roleList==null)</p>
		<p>    {</p>
		<p>      roleList=getList();</p>
		<p>    }</p>
		<p>    try{</p>
		<p>        //如果认证通过就显示标签正文，否则跳过标签正文，就这么简单</p>
		<p>        if(isAuthentificated(elementName))</p>
		<p>        {</p>
		<p>          if(bodyContent != null){</p>
		<p>            JspWriter out=bodyContent.getEnclosingWriter();</p>
		<p>            bodyContent.writeOut(out);</p>
		<p>          }else</p>
		<p>          {</p>
		<p>          }</p>
		<p>        }</p>
		<p>    }catch(Exception e){</p>
		<p>      throw new JspException();</p>
		<p>    }</p>
		<p>    return SKIP_BODY;</p>
		<p>  }</p>
		<p>  //从XML配置文件中取到角色和页面元素的对应，保存到静态的ArrayList</p>
		<p>  private ArrayList getList()</p>
		<p>  {</p>
		<p>    DocumentBuilderFactory dbf =</p>
		<p>        DocumentBuilderFactory.newInstance();</p>
		<p>    DocumentBuilder db = null;</p>
		<p>    Document doc=null;</p>
		<p>    NodeList childlist = null;</p>
		<p>    String elementName;</p>
		<p>    String roleName;</p>
		<p>    int index;</p>
		<p>    ArrayList theList = new ArrayList();</p>
		<p> </p>
		<p>    try{</p>
		<p>      db = dbf.newDocumentBuilder();</p>
		<p>    }catch(Exception e)</p>
		<p>    {</p>
		<p>      e.printStackTrace();</p>
		<p>    }</p>
		<p>    try{</p>
		<p>      doc = db.parse(new File("security.xml"));</p>
		<p>    }catch(Exception e)</p>
		<p>    {</p>
		<p>      e.printStackTrace();</p>
		<p>    }</p>
		<p>    //读取页面元素列表</p>
		<p>    NodeList elementList = doc.getElementsByTagName("htmlElement");</p>
		<p>    for(int i=0;i&lt;elementList.getLength();i++)</p>
		<p>    {</p>
		<p>      Element name = ((Element)elementList.item(i));</p>
		<p>      //页面元素的名称</p>
		<p>      elementName = name.getAttribute("name");</p>
		<p>      //该页面元素对应的有权限的角色的列表</p>
		<p>      NodeList rolNodeList = ((NodeList)name.getElementsByTagName("roleName"));</p>
		<p>      for(int j=0;j&lt;rolNodeList.getLength();j++)</p>
		<p>      {</p>
		<p>        //有权限的角色的名称</p>
		<p>        //roleName = ((Element)rolNodeList.item(j)).getNodeValue();</p>
		<p>        roleName = ((Element)rolNodeList.item(j)).getAttribute("name");</p>
		<p>        theList.add(new ElementAndRole(elementName,roleName));</p>
		<p>      }</p>
		<p>    }</p>
		<p>    return theList;</p>
		<p>  }</p>
		<p> </p>
		<p>  //检查该角色是否有该页面元素的权限</p>
		<p>  private boolean isAuthentificated(String elementName)</p>
		<p>  {</p>
		<p>String roleName = "";</p>
		<p>//在用户登陆时把该用户的角色保存到SESSION中，这里只是直接从SESSION中取用//户角色。</p>
		<p>roleName=this.pageContext.getSession().getAttribute("rolename”); </p>
		<p>// roleList包含elementName属性为elementName，roleName属性为roleName的//ElementAndRole对象，则该角色有该页面元素的权限</p>
		<p>     if(roleList.contains(new ElementAndRole(elementName,roleName)))</p>
		<p>          {</p>
		<p>               return true;</p>
		<p>          }</p>
		<p>    }</p>
		<p>    return  false;</p>
		<p>  }</p>
		<p>  //表示角色和页面元素的对应的关系的内部类</p>
		<p>  class ElementAndRole{</p>
		<p>    String elementName;</p>
		<p>    String roleName;</p>
		<p>    public ElementAndRole(String elementName,String roleName)</p>
		<p>    {</p>
		<p>      this.elementName=elementName;</p>
		<p>      this.roleName=roleName;</p>
		<p>    }</p>
		<p>    public boolean equals(Object obj)</p>
		<p>    {</p>
		<p>      return(((ElementAndRole)obj).elementName.equals(this.elementName)&amp;&amp;((ElementAndRole)obj).roleName.equals(this.roleName));</p>
		<p>    }</p>
		<p>  }</p>
		<p>}</p>
		<p>在标签库能被JSP页面使用前，要做以下三个步骤</p>
		<p>1、  在JSP页面中包括一个taglib元素，确定需要加载到内存的标签库。前面的JSP文件的第一行：&lt;%@ taglib uri="<a href="http://mytag">http://mytag</a>" prefix="custTag" %&gt;做的就是这件事。</p>
		<p>2、  在配置文件web.xml中使用taglib元素确定TLD文件的位置。在web.xml中增加：</p>
		<p>  &lt;taglib&gt;</p>
		<p>    &lt;taglib-uri&gt;http://mytag&lt;/taglib-uri&gt;</p>
		<p>    &lt;taglib-location&gt;</p>
		<p>       /WEB-INF/mytag.tld</p>
		<p>    &lt;/taglib-location&gt;</p>
		<p>  &lt;/taglib&gt;</p>
		<p>3、TLD文件必须使用taglib元素标识每个定制标签极其属性。</p>
		<p>下面是使用这个标签库对应的TLD文件</p>
		<p>&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;</p>
		<p>&lt;!DOCTYPE taglib</p>
		<p> PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"</p>
		<p> "<a href="http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd</a>"&gt;</p>
		<p>&lt;taglib&gt;</p>
		<p>  &lt;tlibversion&gt;1.0&lt;/tlibversion&gt;</p>
		<p>  &lt;jspversion&gt;1.1&lt;/jspversion&gt;</p>
		<p>  &lt;shortname&gt;myTag&lt;/shortname&gt;</p>
		<p>  &lt;uri/&gt;</p>
		<p>  &lt;tag&gt;</p>
		<p>    &lt;name&gt;JspSecurity&lt;/name&gt;</p>
		<p>    &lt;tagclass&gt;com.presentation.viewhelper.JspSecurityTag&lt;/tagclass&gt;</p>
		<p>    &lt;info&gt;</p>
		<p>       JspSecurityTag</p>
		<p>    &lt;/info&gt;</p>
		<p>    &lt;attribute&gt;</p>
		<p>       &lt;name&gt;elementName&lt;/name&gt;</p>
		<p>       &lt;required&gt;true&lt;/required&gt;</p>
		<p>       &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt;</p>
		<p>    &lt;/attribute&gt;</p>
		<p>  &lt;/tag&gt;</p>
		<p>&lt;/taglib&gt;</p>
		<p> </p>
<img src ="http://www.blogjava.net/jelver/aggbug/73941.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-09 08:56 <a href="http://www.blogjava.net/jelver/articles/73941.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Taglib原理和实现：再论El和JSTL标签</title><link>http://www.blogjava.net/jelver/articles/73796.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sun, 08 Oct 2006 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73796.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73796.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73796.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73796.html</trackback:ping><description><![CDATA[
		<font color="#333333">　　问题：你想和JSTL共同工作。比如，在用自己的标签处理一些逻辑之后，让JSTL处理余下的工作。<br />　　<br />　　看这个JSP例子：<br />　　<br />　　＜%<br />　　String name="diego";<br />　　request.setAttribute("name",name);<br />　　%＞<br />　　＜c:out value="${name}"/＞<br />　　......<br />　　<br />　　许多JSTL标签支持El表达式，所以，只要你在自己的标签内部把值塞进request，其他jstl标签就能使用它们<br />　　<br />　　下面这个例子，从request里面取得对象，找到它属性的值，塞到request里去。<br />　　<br />　　package diegoyun;<br />　　<br />　　import javax.servlet.jsp.JspException;<br />　　import javax.servlet.jsp.tagext.TagSupport;<br />　　import org.apache.commons.beanutils.PropertyUtils;<br />　　import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;<br />　　<br />　　public class SetVarTag extends TagSupport<br />　　{<br />　　private Object value = null;<br />　　private String property = null;<br />　　private String var = null;<br />　　public void setVar(String var)<br />　　{<br />　　this.var = var;<br />　　}<br />　　public void setProperty(String property)<br />　　{<br />　　this.property = property;<br />　　}<br />　　public void setValue(Object value)throws JspException{<br />　　this.value = ExpressionEvaluatorManager.evaluate( "value", value.toString(), Object.class, this, pageContext);<br />　　}<br />　　public int doEndTag() throws JspException{<br />　　Object propertyValue = null;<br />　　try{<br />　　propertyValue = PropertyUtils.getProperty(value, property);<br />　　}<br />　　catch (Exception e) {<br />　　throw new JspException(e);<br />　　}<br />　　pageContext.setAttribute(var,propertyValue);<br />　　return EVAL_PAGE;<br />　　}<br />　　}<br />　　<br />　　编写TLD<br />　　<br />　　＜!--SetVarTag--＞<br />　　＜tag＞<br />　　＜name＞set＜/name＞<br />　　＜tag-class＞diegoyun.SetVarTag＜/tag-class＞<br />　　＜body-content＞empty＜/body-content＞<br />　　＜attribute＞<br />　　＜name＞value＜/name＞<br />　　＜required＞true＜/required＞<br />　　＜rtexprvalue＞true＜/rtexprvalue＞<br />　　＜/attribute＞<br />　　＜attribute＞<br />　　＜name＞property＜/name＞<br />　　＜required＞false＜/required＞<br />　　＜rtexprvalue＞false＜/rtexprvalue＞<br />　　＜/attribute＞<br />　　＜attribute＞<br />　　＜name＞var＜/name＞<br />　　＜required＞false＜/required＞<br />　　＜rtexprvalue＞false＜/rtexprvalue＞<br />　　＜/attribute＞<br />　　＜/tag＞<br />　　<br />　　编写JSP<br />　　<br />　　＜%@ page language="java" %＞<br />　　＜%@ page import="diegoyun.vo.*"%＞<br />　　＜%@ taglib uri="/WEB-INF/tlds/diego.tld" prefix="diego"%＞<br />　　＜%@ taglib uri="/WEB-INF/tlds/c.tld" prefix="c"%＞<br />　　＜html＞<br />　　＜body bgcolor="#FFFFFF"＞<br />　　＜%<br />　　Man man = new Man();<br />　　man.setName("diego");<br />　　request.setAttribute("man",man);<br />　　%＞<br />　　Get value from request and set it's property value into request:＜br＞<br />　　＜diego:set value="${man}" property="name" var="myname"/＞<br />　　now use OutTag of jstl taglib to get the name:＜br＞<br />　　value is : ＜c:out value="${myname}" /＞<br />　　<br />　　＜/body＞<br />　　＜/html＞<br />　　<br />　　运行，效果如下：<br />　　<br />　　Get value from request and set it's property value into request:<br />　　now use OutTag of jstl taglib to get the name:<br />　　value is : diego<br />　　<b>结束语</b><br />　　和JSTL交互是非常有用的技术。在JSTL里提供了许多完成基本功能的标签，如输出，循环，条件选择等。仅在处理自己特定逻辑的时候才实现自己的标签，并提供和jstl交互，能大大提高重用性和减少工作量。 </font>
<img src ="http://www.blogjava.net/jelver/aggbug/73796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-08 14:29 <a href="http://www.blogjava.net/jelver/articles/73796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写 "纯HTML" jsp应用--学会使用 JSTL </title><link>http://www.blogjava.net/jelver/articles/73789.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sun, 08 Oct 2006 06:21:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73789.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73789.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73789.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73789.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Arial">刚开始用JSP做web应用的时候，象使用PHP，ASP一样用JSP，在HTML代码中夹杂着一大堆的 scriptlet---即java 代码段。由于本人的“排版”技术还算可以，开始的时候觉得挺好，编写“效率”高，调试又方便！<br /><br />到了后来才知道---这是一种极其愚蠢的做法儿----JSP诞生的时候就已经明确与ASP，PHP划清了界限，使用javaBean、Servlet可以有效的将HTML中夹杂的java 代码段剥离，然后包装成一个可在多个页面复用的“逻辑处理组件”---这是JSP相对于PHP，ASP的优越之处之一。<br /><br />但有时即使使用javabean + servlet，我们也不得不将“极少量”的 java代码 嵌入到HTML中----的确，有时你必须这样：因为在 javabean中，你无法使用JSP中的隐含对象，比如 request,session,response等.<br /><br />使用Servlet虽然可以使用JSP的对象，但却不能象javaBean灵活地插入到 html 中--<br />所以，Tag(标签) 就出现了（可以使用所有的JSP隐含对象），它的出现彻底解决了这个问题，可以让你编写出“纯HTML”的JSP页码---由此带来的好处自然不言而喻：更高的可维护性、更高的组件复用效率、更易维护的HTML页面````<br /><br />小弟不才，刚刚开始学JSTL，觉得这个东东真的很不错！很想让更多的 初学者 知道这个，并能应用到实际的web开发中。<br />下面，就开始编写我们的第一个 Tag！<br /><br /><b>下面是使用了简单Tag的JSP文件，运行结果是显示当前时间：</b></font>
				<font face="Arial">
						<br /><![CDATA[<%</code>taglib&nbsp;uri="/tags"&nbsp;prefix="visa"%&gt;]]&gt;<BR>现在时间是： <BR>很明显，使用了tag的JSP页清爽了许多---如果将数据库操作等一些复杂功能也封装进去的话，tag的优势就更明显了！<BR><BR>环境：win2000&nbsp;server&nbsp;+&nbsp;Tomcat5.019&nbsp;+&nbsp;j2sdk1.42&nbsp;+&nbsp;SQLServer&nbsp;2k<BR><STRONG>开发一个Tag，需要编写2个主要文件：<BR>1-标签处理器（一个类servlet的java类）<BR>2-标签描述符（一个XML风格的tld文件）<BR>完成这两个文件，就可以在WEB应用中部署、应用了。<BR><BR>好了，下面我们就开始做吧！<BR><BR>1-编写tag处理器：datetag.java<BR><BR>它的作用就象一个Servlet，接受来自客户端的请求，但它却可以象javaBean一样在JSP中方便调用。<BR></STRONG></FONT><FONT face=Arial><STRONG>package&nbsp;tag;<BR><BR>import&nbsp;java.util.Date;<BR>import&nbsp;javax.servlet.jsp.*;<BR>import&nbsp;javax.servlet.jsp.tagext.*;<BR><BR>public&nbsp;class&nbsp;datetag&nbsp;extends&nbsp;TagSupport{<BR><BR>&nbsp;public&nbsp;int&nbsp;doStartTag()&nbsp;throws&nbsp;JspException{<BR>&nbsp;&nbsp;Date&nbsp;dte=new&nbsp;Date();<BR>&nbsp;&nbsp;try{<BR>&nbsp;&nbsp;JspWriter&nbsp;out=pageContext.getOut();<BR>&nbsp;&nbsp;out.print(dte);<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;catch(java.io.IOException&nbsp;e)<BR>&nbsp;&nbsp;&nbsp;{throw&nbsp;new&nbsp;JspTagException(e.getMessage());}<BR>&nbsp;return&nbsp;SKIP_BODY;<BR>}<BR>}<BR>用&nbsp;javac编译之后，就得到了&nbsp;datetag.class文件了，将其放在&nbsp;xxx\WEB-INF\classes\tag&nbsp;目录下。<BR><BR>2-编写tag库描述符：tags.tld<BR>比较容易看出，<TAG></TAG>部分有点象servlet&nbsp;mapping的配置--这里配置的是tag的名字与tag类之间的映射。<BR></STRONG></FONT><FONT face=Arial><BR><TLIB-VERSION>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; <BR>&lt;taglib&gt; <BR>&lt;tlib-version&gt;1.0&lt;/tlib-version&gt; <BR>&lt;jsp-version&gt;1.2&lt;/jsp-version&gt; <BR><BR>&lt;tag&gt; <BR>&lt;name&gt;date&lt;/name&gt; <BR>&lt;tag-class&gt;tag.datetag&lt;/tag-class&gt; <BR>&lt;body-content&gt;empty&lt;/body-content&gt; <BR>&lt;/tag&gt; <BR>&lt;/taglib&gt; <BR><BR><BR><BR></TLIB-VERSION><STRONG>将tags.tld保存在xxx\WEB-INF\&nbsp;目录下。<BR><BR>3-配置你的web.xml：<BR>配置web.xml，注册你的标签库：在web.xml的&nbsp;<WEB-APP>与</WEB-APP>之间添加：<BR>在这里注册你的自定义标签符，在JSP中的引用名为：/tags<BR></STRONG></FONT><FONT face=Arial><TAGLIB><BR>&lt;taglib&gt; <BR>&lt;taglib-uri&gt;/tags&lt;/taglib-uri&gt; <BR>&lt;taglib-location&gt;/WEB-INF/tags.tld&lt;/taglib-location&gt; <BR>&lt;/taglib&gt; <BR></TAGLIB><BR><STRONG>4-开始在JSP中使用！<BR>因为已经在web.xml中注册过，通过&nbsp;/tags&nbsp;引用你的标签库；<BR>prefix的作用就象<?XML:NAMESPACE PREFIX = JSP /><jsp:usebean></jsp:usebean>中的&nbsp;id，只是作为一个标志（可任意定义）<BR><?XML:NAMESPACE PREFIX = VISA /><visa:date></visa:date>&nbsp;很明显，通过调用date，就等于调用了&nbsp;datetag.class&nbsp;：<BR><BR></STRONG></FONT><FONT face=Arial><FONT color=#ff0000><FONT color=#000000>&lt;%@ page contentType="text/html;charset=gb2312" %&gt; <BR>&lt;html&gt;&lt;body&gt; <BR>&lt;%@taglib uri="/tags" prefix="visa"%&gt; <BR>现在时间是：&lt;visa:date/&gt; <BR>&lt;/body&gt;&lt;/html&gt; </FONT><STRONG><BR></STRONG></FONT><BR>相信到了这里，有人就有了疑问了：为了使用一个Tag，我就做了这么多的“多余”工作（编写tld，修改web.xml，还要重启tomcat），值得吗？！<BR><BR><DEL>-</DEL>答案是：这是很值得的！<BR>1、如果将比较复杂的逻辑功能封装进Tag，它就具有比Servlet,javaBean更高的灵活性，更多的优点，更易扩展，更易维护---彻底分离表示层与逻辑层！<BR><BR>2、因为Tag的功能并非只是这一些，还有更多高级功能---值得去学习！<BR><BR><STRONG>*</STRONG>*<BR>这只是一个很简单的应用，当然，你会有很多的“迷惑点”，这是正常的---在TAG中有一些独有的特性，想完全学会TAG并不是件简单的事情。<BR><DEL>-所以，在这里，我向大家推荐一本好书：电子工业出版社的《jsp标志库编程指南》（英文名：《Professional&nbsp;JSP&nbsp;Tag&nbsp;Libraries》）<BR><BR><BR>PS：使用JSTL配合javabean,servlet还可以有效保护你的源码哦&nbsp;</DEL>---&nbsp;因为，你可以向你的客户交付不含有java源代码的web应用，因为，所有的&nbsp;java代码&nbsp;都已经被编译成&nbsp;*.class了&nbsp;&nbsp;&nbsp;*^_^*<BR><BR>[注意]：针对&nbsp;Tomcat&nbsp;5.0x以下的版本----如：Tomcat&nbsp;4.0x：要编译标签处理器，必须将你的&nbsp;servlet.jar(在%TOMCAT_HOME%\common\lib下面)&nbsp;放进环境变量&nbsp;CLASSPATH&nbsp;中---(如果是&nbsp;tomcat5.0x&nbsp;以上的版本，好象没这个要求)---否则，会提示编译错误。</FONT> </P></html>]]&gt;</font>
		</p>
<img src ="http://www.blogjava.net/jelver/aggbug/73789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-08 14:21 <a href="http://www.blogjava.net/jelver/articles/73789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat5.x中的虚拟主机配置方法</title><link>http://www.blogjava.net/jelver/articles/73692.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sun, 08 Oct 2006 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73692.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73692.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73692.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73692.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73692.html</trackback:ping><description><![CDATA[
		<p>作者：王树利</p>
		<p>原由：<br />    搞了一段时间的WEB项目(基于JSP+JavaBean技术，服务器为Apache+Tomcat)发现我们的项目文件都放在了TOMCAT_HOME＼webapps中，虽说可以通过server.xml配置我们的项目到其他目录，但是当项目多了的时候server.xml将变得及其臃肿，而且混乱不堪；不易管理与维护．<br />    为了避免以上情形不在发生，为了项目更加便于管理接下来将向大家介绍的是只在server.xml中配置一两个虚拟主机来解决对项目的集中管理，而且每个项目所需的配置文件也不必再添加到server.xml中去了，使得server.xml不再臃肿、不在混乱不堪，而是更利于管理和维护。<br />说了半天想必你早已跃跃欲试了吧，那还不赶快跟我来，还等什么呢!（^_^）</p>
		<p>一、准备：<br />假设你已经是一个web程序员,并且对tomcat有一定了解,而且可以对其进行常规配置</p>
		<p>二、开始配置：<br />1、）首先在TOMCAT_HOME\conf目录中找到server.xml文件并在记事本中打开它；<br />2、）在文件server.xml中找到&lt;/Host&gt;标签；<br />3、）在&lt;/Host&gt;标签之后新建如下信息：<br />      &lt;Host name="onion" debug="0" appBase="f:\StudioOnion\WEB_Project" unpackWARs="true" autoDeploy="true"&gt;<br /> <br /> &lt;Logger className="org.apache.catalina.logger.FileLogger" directory="logs"  prefix="onion_log." suffix=".txt" timestamp="true"/&gt;<br /> &lt;Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  prefix="onion_access_log." suffix=".txt" pattern="common" resolveHosts="false"/&gt;</p>
		<p>&lt;/Host&gt;<br />说明：<br />【onion】为你的主机的名称或域名；<br />【f:\StudioOnion\WEB_Project】为虚拟主机的起始目录；<br />【onion_log】为日志文件名；<br />【onion_access_log】为访问主机的日志文件名。<br />4、）在虚拟主机的起始目录中为你的项目建一个目录和一个与项目同名的配置文件(我的是f:\StudioOnion\WEB_Project \shsc\和f:\StudioOnion\WEB_Project \shsc.xml)。<br />5、）打开那个刚刚建好的项目配置文件来配置你项目的基本信息（如：虚拟目录和真实路径等），总之几乎所有的配置均可在此配置文件中完成，当然servlet和bean的部署要在web.xml中来完成，本文未涉及到此内容故在此不赘述。下面是我的配置文件shsc.xml中的内容仅供参考：<br />&lt;Context path="" docBase="F:\StudioOnion\WEB_Project\shsc"  debug="0" reloadable="true" crossContext="true"&gt;<br />&lt;/Context&gt;</p>
		<p>三、测试<br />打开ie在地址栏中输入<a href="http://onion/shsc">http://onion/shsc</a>若看到你的jsp页面，恭喜你成功了；如若不然，嘿嘿哈哈············再来一遍了（^_^）。</p>
		<p>四、感谢<br />感谢Apache组织，为我提供了如此之好的服务器，而且还是免费的！</p>
		<p> </p>
<img src ="http://www.blogjava.net/jelver/aggbug/73692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-10-08 09:36 <a href="http://www.blogjava.net/jelver/articles/73692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写纯HTMLjsp应用--学会使用JSTL(转)</title><link>http://www.blogjava.net/jelver/articles/73069.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Sat, 30 Sep 2006 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/73069.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/73069.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/73069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/73069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/73069.html</trackback:ping><description><![CDATA[  先来搭下环境，jstl的包当然是不能少的拉。其次，下载必须的标签库或者是java的标签库文件。没有的话，也可以联系我 <a href="mailto:xxx_programer@163.com">xxx_programer@163.com</a> <br />     将jstl 1.1.jar加到class中，（这就不要我详细的讲了吧），然后将标签库放到WEB-INF下或则将java的标签库文件（*.jar）放到WEB-INF\lib下，就可以写测试代码了。<br />     first_jstl.jsp 
<p>     &lt;%@ taglib prefix="c" uri="<a href="http://java.sun.com/jsp/jstl/core">http://java.sun.com/jsp/jstl/core</a>" %&gt;<br />    &lt;%@ page contentType="text/html; charset=gb2312" language="java" %&gt;<br />    &lt;c:set var="userName" value="hellking"/&gt;<br />    &lt;c:set value="16" var="age"/&gt;<br />    欢迎您，&lt;c:out value="${userName}"/&gt;&lt;hr&gt;<br />   &lt;c:forEach var="i" begin="1" end="5"&gt;<br />   &lt;font size=${i}&gt;${i}&lt;/font&gt;<br />   &lt;br&gt;<br />   &lt;/c:forEach&gt;</p><p>   &lt;c:if test="${age&lt;18}"&gt;<br />    对不起，你的年龄过小，不能访问这个网页◎！<br />   &lt;/c:if&gt;<br />   &lt;br&gt;<br />   &lt;/body&gt;<br />   &lt;/html&gt;<br /><br />    web.xml <br />(使用java的标签库文件*.jar)<br />   <br />    &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</p><p>&lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>"<br />    xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />    xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a> web-app_2_4.xsd"<br />    version="2.4"&gt;<br />  &lt;display-name&gt;jstl test&lt;/display-name&gt;<br />  &lt;description&gt;<br />     jstl test<br />  &lt;/description&gt;<br />&lt;/web-app&gt;<br /><br />(使用标签库文件*.tld)<br /><br />  &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</p><p>&lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>"<br />    xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />    xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a><a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</a>"<br />    version="2.4"&gt;<br /> <br />  &lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/fmt&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/fmt.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/fmt-rt&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/fmt-rt.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/core&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/c.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/core-rt&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/c-rt.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/sql&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/sql.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/sql-rt&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/sql-rt.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/x&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/x.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;</p><p>&lt;taglib&gt;<br />    &lt;taglib-uri&gt;http://java.sun.com/jstl/x-rt&lt;/taglib-uri&gt;<br />    &lt;taglib-location&gt;/WEB-INF/x-rt.tld&lt;/taglib-location&gt;<br />&lt;/taglib&gt;<br />&lt;/web-app&gt;</p><p>好了，一个最简单的包含有jstl的页面设计完成了。下面测试。<br /><a href="http://localhost:8080/jstl/frist_jstl.jsp">http://localhost:8080/jstl/frist_jstl.jsp</a><br />页面输出结果：<br /><br />欢迎您，hellking </p><hr /><p><font size="1">1</font><br /><font size="2">2</font><br /><font size="3">3</font><br /><font size="4">4</font><br /><font size="5">5</font><br />对不起，你的年龄过小，不能访问这个网页◎！ <br /><br />呵呵。。。简单吧，下篇继续。。。。。：）</p><p> </p><p align="center"><br /><strong><a name="trackback"></a>引用地址：<a href="http://blog.programfan.com/trackback.asp?id=16965">http://blog.programfan.com/trackback.asp?id=16965</a></strong></p><img src ="http://www.blogjava.net/jelver/aggbug/73069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-09-30 16:21 <a href="http://www.blogjava.net/jelver/articles/73069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web表现层的Client端设计模式探讨 (zhuan)</title><link>http://www.blogjava.net/jelver/articles/67657.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 04 Sep 2006 11:25:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/67657.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/67657.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/67657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/67657.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/67657.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Verdana">
						<font size="2">
								<em>本文着重讨论的是具有RIA特征的Web应用。例如目前比较流行的的Ajax类Web应用。传统的基于纯HTML的Web应用不在本文讨论之列。</em>
								<br />
								<br />随着Ajax的升温，开发人员逐渐对Web应用中的各种UI控件和开发框架开始有了越来越浓厚的兴趣。目前所知的这方面的控件集或开发框架可以说是并不鲜见。笔者将这些产品大致分为两个大类：离散控件集型和数据模型驱动型。这两个词大家应该很陌生，因为他们都是鄙人自造的。<br /><br /><strong>离散控件集型</strong> － 此类产品以提供一系列相对独立的界面控件为主要目的。控件的类型比较全面，例如搭建Web应用常见的各种Grid、Tree、Menu、ToolBar、Window等。不过此类产品一般不会过多的考虑界面中的数据和操作逻辑的封装，至多只会提供相对简单的静态数据绑定*。我认为此类产品的主要出发点是改善Web应用的界面表现能力，同时借助自带的SDK提供一种更加规范的开发模式。<br />目前我所知的大部分产品似乎都属于这一类别。例如: backbase、qooxdoo、NetAdventage、bindows等。<br />Backbase实例中心: </font>
				</font>
				<a href="http://www.backbase.com/demos/explorer" target="_blank">
						<font face="Verdana" size="2">http://www.backbase.com/demos/explorer </font>
				</a>
				<br />
				<br />
				<font size="2">
						<font face="Verdana">
								<strong>数据模型驱动型</strong> － 此类产品除了要提供一组比较好用的UI控件集之外，更会提供对界面中数据模型的管理功能。其UI控件以数据敏感控件为主。数据敏感控件可以通过于数据模型的绑定来实现对表现层中数据的展示和控制。这种数据绑定可成为动态数据绑定*。可以说这一类产品的主要出发点除改善Web应用的界面表现能力外，也非常注重提供一种快速开发的模式。<br />好的数据模型驱动型的开发框架应该首先包含离散控件集中的各种功能，它事实上是一种相对于单纯的UI控件集而言更高层次的抽象。<br /><img height="173" alt="o_binding.png" src="http://www.blogjava.net/images/blogjava_net/bennybao/14638/o_binding.png" width="320" border="0" /><br />这种模式其实在以前CS下非常常见，例如VB、Delphi等RAD开发工具提交数据库应用开发模式都属于这种类型。不过到了BS下人们似乎都忘记这种开发模式。可能是因为不够见多识广，目前笔者所知的此类产品只有dorado。<br />dorado的示例中心：</font>
						<font face="Verdana">
								<a href="http://sample.bstek.com/" target="_blank">http://sample.bstek.com</a>
						</font>
				</font>
		</p>
		<p>
				<font face="Verdana" size="2">对于上面提到的两种数据绑定方式的解释如下：<br /><br /><strong>静态数据绑定</strong> – 是指在控件可以根据指派给他的数据源(往往是XML数据源或简单的数组)自动的提取并展示其中的数据。这种提取过程是主动完成的，当提取过程结束后控件无法继续感知数据源中数据的变化。这事实上是从控件到数据源的拉模式(Pull Mode)。<br /><br /><strong>动态数据绑定</strong> – 是指将控件以观察者的角色注册到数据源(往往是经过封装的私有对象)中。数据源成为被观察者。当数据源中的数据或状态发生改变时会主动通知所有观察者（即绑定的控件），然后再由控件自动提取数据完成展现的更新。这样一旦绑定建立以后控件就可以实时的体现数据源中的最新变化。如果用户利用这些控件对数据或状态做了改变，那么这种改变自然也会通过数据源再实时的通知给所有其它相关的控件。<br /> <br />回到关于离散控件集型和数据模型驱动型的讨论。这两种开发框架都有这自己的适用面。笔者认为离散控件集型的开发框架更加适合与一些像论坛这样更加注重展现的应用。而对于那些具有明显数据库应用特性的的Web应用(例如MIS类应用)，则数据模型驱动型的开发框架更能发挥它的优势。<br />得出以上结论的原因是我认为数据模型驱动型的开发框架能够使开发人员将更多的精力投入到界面所需要实现的更能当中，至少在制作页面的前期阶段不必太多的关注界面的表现形式。同时如果能够将更多的界面操作逻辑封装到数据模型对象中，就可以保证在后期当最终用户提出界面的修改要求时，开发人员可以用更小的代价来完成对界面的重构。<br /><br />让我们来具体分析两个场景:<br /><br /><strong>场景1</strong>：一个用惯了CS应用的用户要求开发一个界面来维护公司目前拥有的所有书籍。为了方便的完成对所有书籍的CRUD操作，用户希望以一个Grid控件来完成所有这些操作，同时用户希望能够在界面批量的完成一系列C、U、D操作之后一次性的对数据进行保存。每本书籍都有一个由系统自动分配的编码作为主键，因此用户不需要看到书籍的编码。<br />分析：如果我们现在只有一个离散的Grid控件。要完成上述功能我们还需要做以下一些工作:<br /><br /></font>
		</p>
		<li>
				<font face="Verdana" size="2">由于编码不在Grid中显示，因此找到一个办法能够管理每本书籍的编码。 </font>
		</li>
		<li>
				<font face="Verdana" size="2">由于客户端需要缓存用户的一系列C、U、D操作然后作批量的提交处理，因此必须做一些工作以便记录下哪些书被修改了、哪些是新增的、哪些被删除了。 </font>
		</li>
		<li>
				<font face="Verdana" size="2">在提交时将所有的数据修改信息抽取出来组装成可用于提交的格式。<br /><br />可见如果使用一个离散的Grid控件来制作这个界面，我们还必须要做不少工作。如果我们能够选择一个数据模型驱动型的开发框架，上面提到的很多功能框架中往往已经具备。开发人员要做的往往只是声明好一个数据模型然后把它跟Grid关联起来。如果您以前使用过VB或Delphi这一类开发功能，应该不难想像这个过程。<br /><br /><strong>场景2</strong>：想像一个用户信息的录入界面，如下图。使用者需要输入用户的身份证，由于什么证的号码中包含了很多信息，系统完全有可能从其中解析出出生日期和性别这样的信息。因此为了方便录入，我们可以让表单中的出生日期和性别这两个栏位支持自动填入缺省值的功能，只要用户录入了身份证号码，就可以马上自动填充上述两个栏位。</font>
				<p>
						<font face="Verdana" size="2">
								<img height="182" alt="o_user_form1.png" src="http://www.blogjava.net/images/blogjava_net/bennybao/14638/o_user_form1.png" width="284" border="0" />
								<br /> <br />在基于离散控件的编程方式中，我们需要知道身份证、出生日期、性别这三个编辑框的id，并针对他们进行编程。其代码形式可能如下:<br /><br /></font>
				</p>
				<p>
						<font face="Verdana" size="2">
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">
						</font>
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<font face="Verdana">
								<font size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
										<span style="COLOR: #000000">var id </span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> inputId.getValue(); </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 获得身份证号码</span>
								</font>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">
												<img src="http://www.blogjava.net/images/dot.gif" /> <img src="http://www.blogjava.net/images/dot.gif" /> </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 对身份证进行解析</span>
								</font>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">inputBrithday.setValue(brithday); </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 为出生日期设置缺省值</span>
								</font>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">radioGroupSex.setValue(sex); </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 为性别设置缺省值</span>
								</font>
						</font>
				</div>
				<p>
						<font face="Verdana" size="2">
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">在基于数据模型驱动型框架的编程方式中，我们并不需要关注界面上摆放了什么控件，只需要知道关注如何操作数据模型对象。其代码形式可能如下:</font>
				</p>
				<p>
						<font face="Verdana" size="2">
						</font>
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<font face="Verdana" size="2">
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #000000">var id </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> dmUser.getValue(</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">id</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">); </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 从数据模型(dmUser)中提取身份证号码</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">
												<img src="http://www.blogjava.net/images/dot.gif" /> <img src="http://www.blogjava.net/images/dot.gif" /> </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 对身份证进行解析</span>
								</font>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">dmUser.setValue(</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">birthday</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">, brithday); </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> 为出生日期设置缺省值</span>
								</font>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font face="Verdana" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</font>
						</span>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #000000">dmUser.setValue(</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">sex</span>
										<span style="COLOR: #000000">"</span>
										<span style="COLOR: #000000">, sex); </span>
										<span style="COLOR: #008000">//</span>
								</font>
						</font>
						<font face="Verdana">
								<font size="2">
										<span style="COLOR: #008000"> 为性别设置缺省值<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
								</font>
						</font>
				</div>
				<p>
						<font face="Verdana" size="2">可见在这种开发模式中我们的代码几乎完全针对数据模型展开，当我们为dmUser中的brithday和sex赋值后，相应的数据敏感控件会立刻自动显示出这些的数据。这样的编程模式可以让代码有高度的一致性，当我们制作复杂的用户界面时，可以不需要记住诸多的控件id。<br />进一步假设。如果用户有一天觉得这样的界面并不方便对多笔数据进行方便的维护，而要求对界面进行如下调整。在删除原先的表单，利用一个Grid控件来对用户信息进行维护。<br /><img height="329" alt="o_user_form2.png" src="http://www.blogjava.net/images/blogjava_net/bennybao/14638/o_user_form2.png" width="284" border="0" /><br />如果我们的编程方式是基于离散控件的，那么我们不可避免的要对先前编写那段代码做一些调整了。我需要将那段代码移植到表格当中。<br />但是如果我们的编程方式是基于数据模型驱动型框架的，那么我们要做的只是将界面上的表单删掉，然后在放置一个与现有数据模型绑定的Grid控件。至于那段代码，它完全不需要做任何变动。<br /><br />综上可见，在MIS类Web应用的表现层开发方面。数据模型驱动型的开发框架可以为开发人员带来更多的实惠。不知道随着时间的推移这一类的开发框架会不会丰富起来？<br /></font>
				</p>
		</li>都是理论性的东西，写个例子不太容易。看看这个现成的吧! <br /><a href="http://61.151.239.187/dorado5/new-feature/brich.jsp" target="_new">http://61.151.239.187/dorado5/new-feature/brich.jsp</a><br />这个界面上既有表格又有表单、还有一个工具条。本来都是不相关的控件，但是由于它们绑定了同一个数据模型，所以在操作时它们会时刻保持同步。
<p><font face="Verdana" size="2"></font> </p><img src ="http://www.blogjava.net/jelver/aggbug/67657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-09-04 19:25 <a href="http://www.blogjava.net/jelver/articles/67657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用cos进行文件上传</title><link>http://www.blogjava.net/jelver/articles/43449.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 27 Apr 2006 00:35:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43449.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43449.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43449.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43449.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43449.html</trackback:ping><description><![CDATA[ <font color="#333333"> 在jsp中实现文件上传，可用的类库很多，比如有著名的jspsmart公司SmartUpload,struts里面也有。我这里说说cos,它是O'Reilly公司的，O'Reilly的图书是很不错的，这个上传的组件也做得很棒，最重要的是，它是open source的。 <br /><br />下载最新的cos包(http://www.servlets.com/cos/index.html),加入到你的classpath中。 <br /><br /><br />    编写一个需要上传文件的jsp,为了方便，我就用一个简单的htm文件了，在这个页面中，我们让用户一次可以上传3个文件。  <br />/////////////////////upload.htm//////////////////////////////////// <br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <br />"http://www.w3.org/TR/html4/loose.dtd"&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;meta http-equiv="Content-Type" content="text/html;charset=gb2312"&gt; <br />&lt;title&gt;无标题文档&lt;/title&gt; <br />&lt;/head&gt; <br /><br />&lt;body&gt; <br />&lt;!-- enctype的值很重要,upload.jsp为处理上传的jsp--&gt; <br />&lt;form name="form1"  method="post" enctype="multipart/form-data"  <br />action="upload.jsp"&gt; <br />&lt;p&gt; <br />  &lt;input name="file1" type="file"&gt; <br />&lt;/p&gt; <br />&lt;p&gt; <br />  &lt;input name="file2" type="file"&gt; <br />&lt;/p&gt; <br />&lt;p&gt;  &lt;input name="file3" type="file"&gt; <br />&lt;/p&gt; <br />&lt;p&gt; <br />  &lt;input type="submit" name="Submit" value="上传"&gt; <br />&lt;/p&gt; <br />&lt;/form &gt; <br /><br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br />在c:\下建一个目录c:\upload，用来存放上传的文件。 <br /><br /><br />写一个jsp或者servlet来实现上传,我这里用一个叫upload.jsp,这样就不用配置web.xml，呵呵,比较懒的说。  <br />////////////////////////////upload.jsp//////////////////////// <br /><br />&lt;%@page import="java.io.*"%&gt; <br />&lt;%@page import="com.oreilly.servlet.MultipartRequest"%&gt; <br />&lt;%@page import="com.oreilly.servlet.multipart.CoverFileRenamePolicy"%&gt; <br />&lt;%@page contentType="text/html; charset=gb2312" %&gt; <br />&lt;% <br />//文件上传后，保存在c:\\upload <br />String saveDirectory ="c:\\upload"; <br />//每个文件最大5m,最多3个文件,所以... <br />int maxPostSize =3 * 5 * 1024 * 1024 ; <br />//response的编码为"gb2312",同时采用缺省的文件名冲突解决策略,实现上传 <br />MultipartRequest multi = <br />       new MultipartRequest(request, saveDirectory, maxPostSize, <br />                            "gb2312"); <br /><br />//输出反馈信息 <br /> Enumeration files = multi.getFileNames(); <br />     while (files.hasMoreElements()) { <br />        System.err.println("ccc"); <br />       String name = (String)files.nextElement(); <br />       File f = multi.getFile(name); <br />       if(f!=null){ <br />         String fileName = multi.getFilesystemName(name); <br />         String lastFileName= saveDirectory+"\\" + fileName; <br />         out.println("上传的文件:"+lastFileName); <br />         out.println("&lt;hr&gt;"); <br /><br />       } <br />     } <br /><br />%&gt; <br />&lt;meta http-equiv="Content-Type" content="text/html;charset=gb2312"&gt; <br />    最后把这2个文件发布到你的服务器就行了。上传文件就搞定啦，以后你想在你邮件系统里面嵌入发送附件的功能，用这个来做上传也不错啊。  <br />最后，希望这篇文章对你有所启发，如有错误，敬请批评指正!</font><img src ="http://www.blogjava.net/jelver/aggbug/43449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-27 08:35 <a href="http://www.blogjava.net/jelver/articles/43449.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用JSTL实现JSP应用程序快速开发</title><link>http://www.blogjava.net/jelver/articles/43448.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 27 Apr 2006 00:32:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43448.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43448.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43448.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43448.html</trackback:ping><description><![CDATA[ <font color="#333333">在这篇文章中，我将为大家介绍一种基于JSP且灵活有趣的技术，那就是JSTL.JSTL全称为Java Server Pages Standard Tag Library.虽然JSP已经变的非常流行，但JSTL在基于SQL数据库的简单、快速的前后台开发中还是没有被广泛的应用。一旦你了解了JSTL，你就会了解到它的优点,并发现在你作为程序员的日常工作中,它已经被应用到了很多方面。我这里假设你已经熟悉HTML，能理解基本的SQL语句,和Jsp的基础知识。因为下面的内容要涉及到这些知识。 <br />　　 JSTL是一个已经被标准化的标记库集合，她支持迭代、条件、XML文档的解析，国际化，和利用SQL与数据库交互的功能。起初，JSTL规范一直由JCP(Java Community process program)组织下的JSR #52 发展完善，"JCP肩负着Java 技术发展的重任"--官方网站这样评价。JCP作为一个开放性的组织，他同时吸收正式的会员和非正式会员.JCP对于Java技术规范的形成与发展发挥了重要的主导作用。JSTL主要包括四个基本部分的标记库：Core,XML,国际化,和对SQL的支持。由于这篇文章的主要是以其中的SQL部分的应用来快速了解JSTL，所以我们这篇文章只介绍了 Core和SQl标签库的一些基本功能。 <br />　　 这项技术简单而且功能强大,足以和PHP、ColdFusion一较高下.他在拓展Java的应用领域方面有足够的能力，这些领域不只包括大型的可再升级的Web应用程序，对于仅拥有简单主页的Web程序一样没问题。这允许你在建立站点的时候可以避免那些经常考虑的XML的集成和与数据库的连接。正如我刚才提到的一样，JSTL的关键点就是简单易用。还有,那就是JSTL是基于JSP构建的, 他允许我们使用所有的Java技术,这一点我们有必要记住。 <br />　　 开始之前，我们需要弄清楚怎样才能运行JSTL.由于是基于JSP技术的，所以我们运行它就需要一个能够编译JSP的容器，这里我们使用免费的JSP容器：TOMCAT(http://jakarta.apache.org/tomcat/index.html).至于如何安装这个产品已经超出了本文所讲述的范围。毫无疑问,这个软件产品现在已经很普及了，而且关于如何安装的文档资料也是很多。这里假设您已经安装并成功配置了这个容器，你只需再安装JSTL运行所需文件即可，它可以从这里下载http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html你不需要真正的安装它，只需要将其中的.JAR文件包含到你的应用程序的WEB-INF/lib目录下即可，稍后我会具体说到该怎么做. <br />　　 因为我们要在一个支持标准SQL的数据库上运行程序，你需要在你的电脑上安装有一个数据库。数据库的类型有许多种，这里我选择了MySql。我之所以选择他的原因在于首先,我们需要展示JSTL对于构造简单快速的应用程序领域所起的作用，同时能和一直在这个领域处于主导地位的PHP+MySql有所比较;第二点那就是MySql是可以免费下载并包含有一个针对JAVA的JDBC驱动.总之，为了使用下面的例子，你需要下载一个MYSQL服务器(http://www.mysql.com/products/mysql/index.html； MySql Connector/J JDBC驱动程序http://www.mysql.com/products/connector-j/index.html；还有就是MySql control center http://www.mysql.com/products/connector-j/index.html),这个产品可以让你非常容易的操作管理Mysql数据库文件。全部下载完成后，你需要安装mysql和mysql Control Center。另外还有就是mysql的JDBC驱动需要放到你的web应用程序中的/Web-INF/lib目录中。 <br /><br />　　 在创建程序代码之前，你需要创建并填写数据库表。关于这方面的主题文章也相当广泛，具体如何操作超出了本文的范围。这里我推荐给你我们上面提及的一个可视化的管理工具 MySQL Control Center.你可以用他来创建一个用来运行程序的测试用户，数据库以及创建一个测试表，并填写若干记录。关于登陆名及密码 数据库名称这些配置环境参数,你应该记住他们,稍后需要应用到我们的代码中。 <br /><br />　　 现在，你就可以准备创建自己的第一个JSTL应用程序了它需要我们做下面一些事情： <br />　　 整个实例程序代码包括两个文件Hello.jsp和 Continue.jsp <br />　　 Hello.jsp文件允许你输入数据库名称、登陆名称、登陆密码、数据库表名。Continue.jsp：接受Hello.jsp中的数据信息并且连接数据库，并对数据库中的表执行一个Select请求. <br /><br />　　 下面是这个系统所有的代码文件，我将逐一进行解释。这些代码相当简单，对于代码的结构,我相信你即使没有我的解释你也能理解的. <br /><br />1: ＜!-- Hello.jsp --＞ <br />2: ＜html＞ <br />3: ＜head＞ <br />4: ＜title＞Hello＜/title＞ <br />5: ＜/head＞ <br />6: ＜body bgcolor="#ffffff"＞ <br />7: ＜h1＞Please, enter all necessary information and click OK.＜/h1＞ <br />8: ＜form method="post" action="Continue.jsp"＞ <br />9: ＜br＞Your login to database: <br />＜input type="text" name="login" size="15"＞ <br />10: ＜br＞Your password to database:  <br />＜input type="password" name="password" size="15"＞ <br />11: ＜br＞Your database name: <br />＜input type="text" name="database" size="15"＞ <br />12: ＜br＞Your database table: <br />＜input type="text" name="table" size="15"＞ <br />13: ＜br＞＜br＞＜input type="submit" name="submit" value=" OK "＞ <br />14: ＜/form＞ <br />15: ＜/body＞ <br />16: ＜/html＞  <br /><br />　　 (请注意文本左侧的数字只是为你提供一些标记信息，你不需要将他们输入到你的代码文件中。) <br />　　 上面就是所有Hello.jsp的源代码，很惊奇吧，他仅仅是纯粹的HTML代码，就这么简单，我想应该没有注释的必要了.我之所以将这些代码片段包含进文章中就是为了展示一下JSTL集成到那些需要快速扩充额外功能的HTML站点中是多么的简单.让我再为你展示一下Continue.jsp的全部代码，看过之后，你就会对 JSTL有些了解了。 <br /><br />1: ＜!-- Continue.jsp --＞ <br />2: ＜%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %＞ <br />3: ＜@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %＞ <br />4: ＜c:set var="h" value="localhost"/＞ <br />5: ＜c:set var="l" value="${param.login}"/＞ <br />6: ＜c:set var="p" value="${param.password}"/＞ <br />7: ＜c:set var="d" value="${param.database}"/＞ <br />8: ＜c:set var="t" value="${param.table}"/＞ <br />9: ＜html＞ <br />10: ＜head＞ <br />11: ＜title＞Continue＜/title＞ <br />12: ＜/head＞ <br />13: ＜body bgcolor="#ffffff"＞ <br />14: ＜sql:setDataSource driver="com.mysql.jdbc.Driver" <br />url="jdbc:mysql://${l}/${d}?user=${u}&amp;password=${p}"/＞ <br />15: ＜sql:query var="result"＞ <br />16: SELECT * FROM ＜c:out value="${t}"/＞ <br />17: ＜/sql:query＞ <br />18: ＜c:forEach var="row" items="${result.rowsByIndex}"＞ <br />19: ＜c:out value="${row[0]}"/＞ ＜br＞ <br />20: ＜/c:forEach＞ <br />21: ＜/body＞ <br />22: ＜/html＞  <br /><br />(请注意文本左侧的数字只是为你提供一些标记信息，你不需要将他们输入到你的代码文件中。) <br /><br />　　 这就是我们所有的代码了，是不是非常不错？现在我门来解释一下上面这些代码的作用。 <br />　　 行1 是 HTML 的注释说明。 <br />　　 行2--3 这些 JSP 标签是为了引用外部的 标签库，更确切的说这里是引用了JSTL库中的 Core 和SQL标签库部分。我们为他们都设置了前缀名称，以便于我们通过这些前缀名称访问被引入的标签库中的功能方法。 <br />　　 行4---8正如 Hello.jsp 真正运行的样子，他将请求continue.jsp，Continue.jsp获得请求后就需要得到并解析来自Hello.jsp的若干变量，我们使用了这样的方式${param.YOUR_VAR}。在第4行＜c:set标签，将变量${h}设置为 "localhost",第五行变量${l}将获取我们在 Hello.jsp中的login文本域中输入的信息，第6，7，8行的变量将分别获得来自Hello.jsp中用户所输入的密码，数据库名称，数据表名称。 <br />　　 行9--13是一些我经常用来常见HTML网页头的简单的HTML标签，马上，重要的功能马上要到了。 <br />　　 行14，我们试图用我们先前获得的mysql驱动程序(com.mysql.jdbc.Driver)建立数据库连接，在URL中，我们指明数据库连接所需要的参数，象数据库名称，主机名称，登陆名及登陆密码。依此，我们可以用其它任何的JDBC驱动程序连接其相对的数据库。如果我们需要连接其他的SQL数据库，只需更改这个 URL就够了。 <br />　　 行15--17 这里我们执行了一个Select 查询，请特别注意第16行，我们使用了另一个JSTL功能函数＜c:out 用来输出我们所获取的数据表名称，这里我们同样可以使用其他的SQL命令，比如说 INSERT,DELETE,等等。要执行这些没有返回值的查询请求，你就需要使用＜sql:update JSTL功能函数了。他可以直接执行他们就象＜SQL:query一样，只是执行它是不需要特别指定结果变量来存储语句执行返回的结果。 <br />　　 行18--20 既然我们执行了上面的SELECT查询语句，我们就应该把他的返回结果显示出来。＜c:forEach 就是JSTL 中一个具有迭代功能的函数，执行它时，我们通过${result.rowsByIndex}将返回的每一个数据行信息返回给变量${row},紧接着在第19行， 我们通过＜c:out value="${row[0]}"/＞显示返回的每个数据行的第一个数据列中的值。只要你的数据表中包含的字段，你都可以通过改变变量 ${row}中的数字大小来对请求表中的任意一个字段中的值对他们进行访问。 <br />　　 行21--22是HTML 页脚 <br />　　 在你亲自创建JSTL应用程序过程中，可能你还没有发现它有多么的强大，但你应该能够意识到JSTL的功能函数的简单和高效性，试想有了JSTL,整合出一个基于SQL的新闻专栏是何等的快速，集成你现有的web站点是何等的容易。 <br />　　 很好，我们的代码很容易理解的，即使一个非专业程序员的话，打个比方就算是一个设计师也能够读懂它，理解它，还可能进行部分的修改，起码是页面布局上的修改。 <br />　　 正如我们开始的时候所提到的，为了使我们的JSTL代码正常的运行，我们需要安装Mysql Connector/J 中的JAR 文件，当然还有 JSTL。因为我们使用了Tomcat这个JSp 容器，你需要在Tomcat的文件目录Webapps下创建你自己的文件夹，将你的Hello.jsp 、Continue.jsp文件放在你创建的文件目录中，在你创建的目录中你还要创建一个叫做WEB-INF 的文件夹，将你的配置文件Web.xml放在里面，web.xml文件如下： <br /><br />＜?xml version="1.0" encoding="UTF-8"?＞ <br />＜!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"＞ <br />＜web-app /＞  <br /><br />　　 接下来我们还需要在WEB-INF下创建一个叫做lib的子目，并将下列文件放进去： <br /><br />jstl.jar  <br />saxpath.jar  <br />standard.jar  <br />mysql-connector-java-3.0.9-stable-bin.jar (注意，这个名称依据你的Mysql Connector/J版本不同可能会有所变化)  <br /><br />　　 所有的这些信息您能够在JSTL或Tomcat手册中查阅的到，如果你想理解他们具体是如何运行而又为什么这么运行你就应该研读一下这些手册。不过为了帮助你快速的掌握JSTL的基本操作，相关的知识我已经作了介绍。 <br />　　 如果你使用的是其他的Jsp 容器，那么就需要你阅读他们相关的手册资料。 <br />　　 罗罗索索这么多，我还想再说明一点,这篇文章只是对JSTL技术的基本的介绍，并不是完全手册。JSTL中包含有许多功能丰富的函数用法来帮助你以简捷快速的方式完成你的Jsp开发，我建议大家读一些有关JSTL功能以及它如何与JavaBeans协同!作的更详细的文档资料，到最终你可能会发现他就是你期待已久的开发平台。通过阅读本篇文章，你应该已经能够创建一些简单的基于SQL 数据库的前后台应用了。</font><img src ="http://www.blogjava.net/jelver/aggbug/43448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-27 08:32 <a href="http://www.blogjava.net/jelver/articles/43448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>发送带附件的邮件</title><link>http://www.blogjava.net/jelver/articles/43417.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 26 Apr 2006 13:35:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43417.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43417.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43417.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43417.html</trackback:ping><description><![CDATA[
		<font color="#333333">继续以新浪为例，发附件要用到上传的组件，O'Reilly公司的cos.jar。请将cos.jar、mail.jar和activation.jar,放到你的WEB应用程序的WEB-INF/lib目录下。 <br />测试用的JavaMail3.html <br />&lt;html&gt; <br />&lt;head&gt; <br />  &lt;title&gt;JavaMail3.html&lt;/title&gt; <br />&lt;meta http-equiv="Content-Type" content="text/html; charset=GB2312"&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br /><br />&lt;h2&gt;利用JavaMail来发送电子邮件 - 附件&lt;/h2&gt; <br />&lt;form name="SendMessage" Method="post" action="JavaMail3.jsp" enctype="multipart/form-data"&gt; <br />  &lt;p&gt;寄信人：&lt;input type="text" name="From" size="30" maxlength="30"&gt;&lt;/p&gt; <br />  &lt;p&gt;收信人：&lt;input type="text" name="To" size="30" maxlength="30"&gt;&lt;/p&gt; <br />  &lt;p&gt;主题：&lt;input type="text" name="Subject" size="30" maxlength="30"&gt;&lt;/p&gt; <br />  &lt;p&gt;格式：&lt;select name="Type" size="1"&gt; <br />&lt;option value="text/plain"&gt;Text&lt;/option&gt; <br />&lt;option value="text/html"&gt;HTML&lt;/option&gt; <br />           &lt;/select&gt;&lt;/p&gt; <br />  &lt;p&gt;附件：&lt;input type="file" name="FileName" size="20" maxlength="20"&gt;&lt;/p&gt;          <br />  &lt;p&gt;内容：&lt;/p&gt;&lt;p&gt;&lt;textarea name="Message" cols=40 rows=5&gt;&lt;/textarea&gt;&lt;/p&gt; <br />   <br />  &lt;input type="submit" value="发送"&gt; <br />  &lt;input type="reset" value="重填"&gt; <br />&lt;/form&gt; <br /><br />&lt;/body&gt; <br />&lt;/html&gt; <br />处理附件与邮件的JavaMail3.jsp <br />&lt;%@ page import="javax.mail.*" %&gt; <br />&lt;%@ page import="javax.mail.internet.*" %&gt; <br />&lt;%@ page import="javax.activation.*" %&gt; <br />&lt;%@ page import="java.util.*,java.io.*" %&gt; <br />&lt;%@ page import="com.oreilly.servlet.MultipartRequest" %&gt; <br />&lt;%@ page contentType="text/html;charset=GB2312" %&gt; <br /><br />&lt;html&gt; <br />&lt;head&gt; <br />  &lt;title&gt;CH17 - JavaMail2.jsp&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br /><br />&lt;h2&gt;利用JavaMail来发送电子邮件 - 附件&lt;/h2&gt; <br /><br />&lt;% <br />InternetAddress[] address = null; <br /><br />request.setCharacterEncoding("gb2312"); <br />MultipartRequest multi = new MultipartRequest(request , "." , 5*1024*1024 , "GB2312"); <br /><br />String mailserver   = "smtp.sina.com.cn"; <br />String From         = multi.getParameter("From"); <br />String to           = multi.getParameter("To"); <br />String Subject      = multi.getParameter("Subject"); <br />String type     = multi.getParameter("Type"); <br />String messageText  = multi.getParameter("Message"); <br />String FileName     = multi.getFilesystemName("FileName"); <br /><br />   boolean sessionDebug = false; <br /><br />try { <br /><br />   // 设定所要用的Mail 服务器和所使用的传输协议 <br />   java.util.Properties props = System.getProperties(); <br />  <br />   props.put("mail.host",mailserver); <br />   props.put("mail.transport.protocol","smtp"); <br />             props.put("mail.smtp.auth", "true");//指定是否需要SMTP验证 <br /><br />   // 产生新的Session 服务 <br />   javax.mail.Session mailSession = javax.mail.Session.getDefaultInstance(props,null); <br />  mailSession.setDebug(sessionDebug); <br />   Message msg = new MimeMessage(mailSession); <br />   // 设定发信人 <br />   msg.setFrom(new InternetAddress(From)); <br />     // 设定收信人 <br />   address = InternetAddress.parse(to,false); <br />   msg.setRecipients(Message.RecipientType.TO, address); <br />     // 设定信中的主题  <br />   msg.setSubject(Subject); <br />     // 设定送信的时间 <br />   msg.setSentDate(new Date()); <br /><br />   if (FileName != null) <br />   { <br />        File file = new File(FileName); <br />               <br />   // 如果有附件，先将邮件内容部分存起来 <br />           MimeBodyPart mbp1 = new MimeBodyPart(); <br />       <br />     // 设定邮件内容的类型为 text/plain 或 text/html <br />   mbp1.setContent(messageText, type + ";charset=GB2312"); <br /><br />           // 再来对附件作处理 <br />           MimeBodyPart mbp2 = new MimeBodyPart(); <br />           FileDataSource fds = new FileDataSource(FileName); <br />           mbp2.setDataHandler(new DataHandler(fds)); <br />           mbp2.setFileName(MimeUtility.encodeText(fds.getName(), "GB2312", "B")); <br /><br />           // 最后再将两者整合起来，当作一份邮件送出 <br />           Multipart mp = new MimeMultipart(); <br />           mp.addBodyPart(mbp1); <br />           mp.addBodyPart(mbp2); <br />           msg.setContent(mp); <br />    } <br />    else <br />    { <br />           // 若没有附件时，就直接存邮件内容 <br />           msg.setContent(messageText,type + ";charset=GB2312"); <br />    }              <br />              Transport transport = mailSession.getTransport("smtp"); <br />              //请填入你邮箱的用户名和密码，千万别用我的^_^。 <br />              transport.connect(mailserver, "zz3zcwb", "1234567"); <br />              transport.sendMessage(msg, msg.getAllRecipients()); <br />              transport.close(); <br />  out.println("邮件已顺利发送"); <br /><br />} <br />     catch (MessagingException mex)  <br />     { <br /> out.println(mex); <br />         mex.printStackTrace(); <br />} <br />%&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br />发个附件给我吧！</font>
<img src ="http://www.blogjava.net/jelver/aggbug/43417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-26 21:35 <a href="http://www.blogjava.net/jelver/articles/43417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP网站登录记忆跳转实现的一种方法</title><link>http://www.blogjava.net/jelver/articles/43413.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 26 Apr 2006 13:16:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43413.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43413.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43413.html</trackback:ping><description><![CDATA[记忆登录跳转可以大大方便用户，使用getHeader("Referer");方式简单，不过不能处理post的参数，本来这些代码都是用在struts,webwork里的，为了容易看明白改写成jsp方式的。<br /><br />&lt;!--此页面的内容受保护，必须登录才能访问--&gt;<br />&lt;%@ page contentType="text/html; charset=GBK" %&gt;<br />&lt;jsp:useBean id="rect" class="com.util.myRedirect" scope="page"/&gt;<br />&lt;%<br />String url = "";<br />if(session.getAttribute("userid")==null)//如果用户没有登录<br />{<br />   url =rect.dealurl(request);<br />//记忆进入此页面的地址和请求参数，dealurl将实际url进行处理,因为有&amp;字符<br />   response.sendRedirect("weblogin.jsp?url="+url) ;<br />//重定向到登录页面，记忆的url作为参数一起传入<br /><br />}else{<br />    out.println("你已经登录，可以下载了");<br />} %&gt;
<p>weblogin.jsp<br />&lt;%@ page contentType="text/html; charset=GBK" %&gt;<br />&lt;jsp:useBean id="myRedirect" class="com.util.myRedirect" scope="page"/&gt;</p><p>&lt;%<br />String url = request.getParameter("url");<br />String userid =request.getParameter("userid");<br />String password =request.getParameter("password");<br />if(userid!=null) //如果是登录提交执行下面代码<br />{<br /><br /> if(登录成功)<br />  {<br />   session.setAttribute("userid",userid); <br />   out.println("&lt;script&gt;alert('登录成功，谢谢光临');self.location.href='"+myRedirect.geturl(url)+"';&lt;/script&gt;");<br />//转向到首次请求的url，.geturl(url)是把转化过的地址转化回来变成真实url.<br />  }else{<br />   out.println("&lt;script&gt;alert('用户名或密码错误');history.back();&lt;/script&gt;");<br />  }<br />}else{//如果不是登录提交显示现面登录界面<br />%&gt;<br />&lt;table width="311" height="162" border="0" align="center" cellpadding="0" cellspacing="0"&gt;<br />  &lt;tr&gt;<br />      <br />    &lt;td width="311" height="162" align="center"&gt; 您还没有登录，请先登录&lt;br&gt;<br />        &lt;table width="155" border="0" cellpadding="0" cellspacing="5" class="font12"&gt;<br />  &lt;form  name="loginfrm" action="weblogin.jsp" method="post"  id="loginfrm" onSubmit="return checkfrm();"&gt;<br />          &lt;tr&gt; <br />            &lt;td width="41" height="33" valign="bottom"&gt;帐&amp;nbsp;号：&lt;/td&gt;<br />            &lt;td width="99" valign="bottom"&gt;&lt;input name="userid" type="text" class="textstyle" id="userid" size="12" style="height:20"&gt;&lt;/td&gt;<br />          &lt;/tr&gt;<br />          &lt;tr&gt; <br />            &lt;td&gt;密&amp;nbsp;码：&lt;/td&gt;<br />            &lt;td&gt;&lt;input name="password" type="password" class="textstyle" id="password" size="12" style="height:20;width:94"&gt;&lt;/td&gt;<br />          &lt;/tr&gt;<br />          &lt;tr align="center" valign="bottom"&gt; <br />            &lt;td height="21" colspan="2"&gt; &lt;input type="submit" name="Submit" value="登录"&gt;<br />              &amp;nbsp; &lt;a href="reg.jsp" target="_blank"&gt;没有注册&lt;/a&gt;&amp;nbsp; &lt;/td&gt;<br />          &lt;/tr&gt;<br />          &lt;tr align="center"&gt; <br />            &lt;td colspan="2" class="font14"&gt; &lt;strong&gt;<br />&lt;a href="#" onclick="MM_openBrWindow('requestpwd.jsp','pwd','width=300,height=200');return false;"&gt;找回密码&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;<br />          &lt;/tr&gt;<br />    &lt;input name="url" type="hidden" value="&lt;%=url%&gt;"&gt;&lt;!--这里要有个hidden来保存一下，不然提交就没了 --&gt; <br />    <br />    &lt;/form&gt;<br />        &lt;/table&gt;     <br />    &lt;/td&gt;<br />  &lt;/tr&gt;<br />&lt;/table&gt;<br />&lt;%<br />}<br />%&gt;<br /><br />---------------------------------------------------------------<br /></p><p>myRedirect.java<br /><br />package com.util;</p><p>import javax.servlet.http.HttpServletRequest;<br />import java.util.Enumeration;</p><p>public class myRedirect    //对url的转换类<br />{<br /> public static String dealurl(HttpServletRequest request)<br /> {<br />  String url = "";<br />  url = request.getRequestURL()+"?";<br />  url +=param(request);<br />  if(url.indexOf("&amp;")&gt;-1)<br />   url=url.replaceAll("&amp;","@#@");//实际上就是把有&amp;的字符转化成了@#@<br />  return url;<br /> }<br /> public static String geturl(String url)//这个是还原方法<br /> {<br />  if(url.indexOf("@#@")&gt;-1)<br />   url=url.replaceAll("@#@","&amp;");<br />  return url;     <br /> }<br /> public static String param(HttpServletRequest request)<br /> {<br />  String url = "";<br />  Enumeration param = request.getParameterNames();//得到所有参数名<br />  while(param.hasMoreElements())<br />  {<br />   String pname = param.nextElement().toString();<br />   url += pname+"="+request.getParameter(pname)+"&amp;";<br />  }<br />  if(url.endsWith("&amp;"))<br />  {<br />   url = url.substring(0,url.lastIndexOf("&amp;"));<br />  }<br />  return url;<br /> }<br />}</p><img src ="http://www.blogjava.net/jelver/aggbug/43413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-26 21:16 <a href="http://www.blogjava.net/jelver/articles/43413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>B/S系统权限控制的一种简单方法</title><link>http://www.blogjava.net/jelver/articles/43359.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Wed, 26 Apr 2006 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/43359.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/43359.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/43359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/43359.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/43359.html</trackback:ping><description><![CDATA[看了网上一些关于权限控制的帖子，越看越迷糊，什么用AOP(Aspect Oriented Programming,面向方面编程)，用容器，RBAC(基于角色的访问控制方法),SSO,Jive的Proxy模式等等等等，且又是role又是group，真是头都大了，先写个简单的实现方法，以后再研究高深的。 <br />此方法不依赖容器框架，适用于小系统(主要JSP页面要少于100,因为是硬编码到JSP)，适用于要精确控制页面field的情况较多的系统。
<p>(插句话：要分清权限控制与业务逻辑，业务逻辑就是情况由系统运行时的某些条件决定，如学生管理系统中，某一学生进入系统，只能看自己的记录，因为可看的记录是由学号来决定的，所以这是业务逻辑，而又如学生不能看老师的记录，这是有学生的身份来决定的，所以这是权限控制。)</p><p>好了，进入正题！<br />建表：<br /></p><p>user(user信息： userID userPassword 等)<br />role(role描述：roleID roleDesc)<br />permission(permission描述：permissionID permissionDesc)<br />user-role(user role对应关系表：userID roleID)<br />role-permission(role permission对应关系表：roleID permissionID)<br />user-permission(user permission对应关系表：userID permissionID)<br /></p><p>重要申明：</p><p>1 此处role没有继承关系,只是permission的集合</p><p>2 user-permission表只是为了方便，其数据是根据user-role role-permission两表得来，只有在user-role role-permission两表有更新的时候更新此表，并不能单独赋予user某个permission,只能赋予user一个或多个role。</p><p>3 permission的分配，这是一个难点，很多比较复杂的权限控制系统也是因为这个才发展出来，此处把它尽量想简单，不考虑业务逻辑，以页面为视角，分两层，首先是需要控制的jsp页面，然后是需要控制的页面field(包括link,text,textbox,button等等)，field这一层还有privilege之分(R和W，即可读和可写)</p><p>基本思路：进入JSP页面时，检查用户信息，查到用户有此permission就包含此代码，如果没有此permission就不包含此代码，此功能由Tag来完成(不会写Tag？不要紧，抄！)。看代码吧！</p><p>1 建表(如上)<br />2 建两个class(bean) (UserProfile是用户基本信息 UserPermission是permission )</p><p></p><pre>UserProfile.java:
package com.××.××.××;
import java.util.Collection;

public class UserProfile {
  private String userId;
  private String userType;
  private String companyNo;
  private String companyName;
  private String companyType;
  private Collection userPermissions;

 public String getUserId() {
       return userId;
  }
  public void setUserId(String userId) {
      this.userId = userId;
  }
 public String getUserType() {
       return userType;
 }
 
  public void setUserType(String userType) {
     this.userType = userType;
  }

  public String getCompanyNo() {
      return companyNo;
  }

  public void setCompanyNo(String companyNo) {
      this.companyNo = companyNo;
  }

  public String getCompanyName() {
    return companyName;
  }
   public void setCompanyName(String companyName) {
     this.companyName = companyName;
   }
   public String getCompanyType() {
     return companyType;
   }
  public void setCompanyType(String companyType) {
     this.companyType = companyType;
  }
  public Collection getUserPermissions() {
     return userPermissions;
  }
   public void setUserPermissions(Collection userPermissions) {
      this.userPermissions = userPermissions;
   }
}


UserPermission.java:
package com.××.××.××;

public class UserPermission {
  private int permissionId;
  private String privilege;
  public int getPermissionId() {
     return permissionId;
  }
  public void setPermissionId(int permissionId) {
     this.permissionId = permissionId;
  }
  public String getPrivilege() {
     return privilege;
  }
  public void setPrivilege(String privilege) {
    this.privilege = privilege;
 }
} 




3 加两个Tag(Page与Field)：


SecurityTagForPage.java：
package com.**.**.taglib;
import java.util.*;

public class SecurityTagForPage extends TagSupport{

 private int permissionID;

 public int doEndTag() throws JspException{
     HttpSession session = pageContext.getSession();

     //登陆时把该user的userProfile放到session里 

     UserProfile userProfile = (UserProfile)session.getAttribute("userProfile");
     Collection collection= userProfile.getUserPermissions();
     Iterator it = collection.iterator() ;
     while(it.hasNext()){
       UserPermission userPermission = (UserPermission)it.next();
       if ((permissionID == userPermission.getPermissionId())){
            return EVAL_PAGE;
       }
     }
     return SKIP_PAGE;
 }

 public int getPermissionID(){
     return permissionID;
 }

 public void setPermissionID(int permissionID){
     this.permissionID = permissionID;
 }
}

SecurityTagForField：
public class SecurityTagForField extends TagSupport{
  private int permissionID;
  private String privilege;

public int doStartTag() throws JspException{
  HttpSession session = pageContext.getSession();
  UserProfile userProfile = (UserProfile)session.getAttribute("userProfile");

  Collection collection= userProfile.getUserPermissions();
  Iterator it = collection.iterator() ;
  while(it.hasNext()){
     UserPermission userPermission = (UserPermission)it.next();
     if (privilege ==null){
            if ( (permissionID == userPermission.getPermissionId())){
                 return EVAL_BODY_INCLUDE;
            }
     }else{
        if ((permissionID == userPermission.getPermissionId())
&amp;&amp;(privilege.equals(userPermission.getPrivilege()))){
            return EVAL_BODY_INCLUDE;
        }
     }
   }
   return SKIP_BODY;
  }

 public int getPermissionID(){
  return permissionID;
 }

 public void setPermissionID(int permissionID){
   this.permissionID = permissionID;
 }

 public String getPrivilege(){
   return privilege;
 }

 public void setPrivilege(String privilege){
    this.privilege = privilege;
 }
} </pre><p></p>4 在web-inf目录下建个securityTag.tld文件，内容如下：(改一下class的目录)<br /><p>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;<br />&lt;!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"<br />"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"&gt;<br />&lt;!-- a tag library descriptor --&gt;<br />&lt;taglib&gt;<br />&lt;tlibversion&gt;1.0&lt;/tlibversion&gt;<br />&lt;jspversion&gt;1.1&lt;/jspversion&gt;<br />&lt;shortname&gt;security&lt;/shortname&gt;<br />&lt;uri/&gt;<br />&lt;info&gt;access control!&lt;/info&gt;<br />&lt;tag&gt;<br />&lt;name&gt;securityForField&lt;/name&gt;<br />&lt;tagclass&gt;com.companyname.prjname.taglib.SecurityTagForField&lt;/tagclass&gt;<br />&lt;attribute&gt;<br />&lt;name&gt;permissionID&lt;/name&gt;<br />&lt;required&gt;true&lt;/required&gt;<br />&lt;/attribute&gt;<br />&lt;attribute&gt;<br />&lt;name&gt;privilege&lt;/name&gt;<br />&lt;/attribute&gt;</p><p>&lt;/tag&gt;<br />&lt;tag&gt;</p><p>&lt;name&gt;securityForPage&lt;/name&gt;<br />&lt;tagclass&gt;com.companyname.prjname.taglib.SecurityTagForPage&lt;/tagclass&gt;<br />&lt;attribute&gt;<br />&lt;name&gt;permissionID&lt;/name&gt;<br />&lt;required&gt;true&lt;/required&gt;<br />&lt;/attribute&gt;</p><p>&lt;/tag&gt;<br />&lt;/taglib&gt;<br /></p><p>5 修改需要控制的jsp</p><p>在jsp页面这样写：<br /></p><p>&lt;%@ taglib uri="/WEB-INF/securityTag.tld" prefix="security" %&gt;<br />&lt;%@ page import="com.hp.elog2.util.Util" %&gt;<br />&lt;security:securityForPage permissionID="36" /&gt;<br />.......<br />&lt;security:securityForField permissionID="46" privilege="R"&gt;<br />&lt;td&gt;&lt;html:text name="formBean" property="property1" readonly="true" /&gt;&lt;/td&gt;<br />&lt;/security:securityForField&gt;<br />&lt;security:securityForField permissionID="46" privilege="W"&gt;<br />&lt;td&gt;&lt;html:text name="formBean" property="property1" /&gt;&lt;/td&gt;<br />&lt;/security:securityForField&gt;<br />......<br /></p><p>这样就大功告成了，建议在所有jsp页面完成后再做权限控制这一块(添加Tag)，主要都是些Copy＋C和Copy＋V的工作。</p><p>此方法最大的问题就是hardcode太多，但结构简单，思路清晰，适用范围广。</p><p>复杂的方法希望同道之士于我联系leon_sandy@tom.com，共同研究！</p><img src ="http://www.blogjava.net/jelver/aggbug/43359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-26 16:58 <a href="http://www.blogjava.net/jelver/articles/43359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在JSP中实现DES加密解密的例子</title><link>http://www.blogjava.net/jelver/articles/40945.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Apr 2006 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/40945.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/40945.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/40945.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/40945.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/40945.html</trackback:ping><description><![CDATA[
		<font color="#333333">DES.java <br /><br /><br />package Lion.Security.Cryptography; <br /><br />import javax.crypto.Cipher; <br />import javax.crypto.KeyGenerator; <br />import javax.crypto.NoSuchPaddingException; <br />import javax.crypto.SecretKey; <br />import java.security.NoSuchAlgorithmException; <br />import java.security.Security; <br />/** <br /> * DES加密的，文件中共有两个方法,加密、解密 <br /> * @author Lion <br /> * @author www.lionsky.net <br /> */ <br />public class DES { <br />    private String Algorithm = "DES";//加密算法的名称 <br />    private KeyGenerator keygen;//密钥生成器 <br />    private SecretKey deskey;//密钥 <br />    private Cipher c;//密码器 <br />    private byte[] cipherByte; <br /><br />    /** <br />     * 初始化 DES 实例 <br />     */ <br />    public DES() { <br />          init(); <br />    } <br /><br />    public void init() { <br />        Security.addProvider(new com.sun.crypto.provider.SunJCE()); <br />        try { <br />               keygen = KeyGenerator.getInstance(Algorithm); <br />               deskey = keygen.generateKey(); <br />               c = Cipher.getInstance(Algorithm); <br />         } <br />         catch(NoSuchAlgorithmException ex){ <br />            ex.printStackTrace(); <br />        } <br />         catch(NoSuchPaddingException ex){ <br />            ex.printStackTrace(); <br />        } <br />       } <br /><br />    /** <br />     * 对 String 进行加密 <br />     * @param str 要加密的数据 <br />     * @return 返回加密后的 byte 数组 <br />     */ <br />     public byte[] createEncryptor(String str) { <br />        try { <br />             c.init(Cipher.ENCRYPT_MODE, deskey);//初始化密码器，用密钥deskey,进入加密模式 <br />             cipherByte = c.doFinal(str.getBytes());//加密 <br />        } <br />        catch(java.security.InvalidKeyException ex){ <br />            ex.printStackTrace(); <br />        } <br />        catch(javax.crypto.BadPaddingException ex){ <br />            ex.printStackTrace(); <br />        } <br />        catch(javax.crypto.IllegalBlockSizeException ex){ <br />            ex.printStackTrace(); <br />        } <br />        return cipherByte; <br />     } <br /><br />    /** <br />     * 对 Byte 数组进行解密 <br />     * @param buff 要解密的数据 <br />     * @return 返回加密后的 String <br />     */ <br />     public String createDecryptor(byte[] buff) { <br />        try { <br />           c.init(Cipher.DECRYPT_MODE, deskey);//初始化密码器，用密钥deskey,进入解密模式 <br />           cipherByte = c.doFinal(buff); <br />        } <br />        catch(java.security.InvalidKeyException ex){ <br />            ex.printStackTrace(); <br />        } <br />        catch(javax.crypto.BadPaddingException ex){ <br />            ex.printStackTrace(); <br />        } <br />        catch(javax.crypto.IllegalBlockSizeException ex){ <br />            ex.printStackTrace(); <br />        } <br />        return (new String(cipherByte)); <br />     } <br />} <br /><br />  <br /><br />DES.jsp <br /><br /><br />&lt;%@ page contentType="text/html; charset=gb2312" %&gt; <br />&lt;jsp:useBean id="DES" scope="page" class="Lion.Security.Cryptography.DES" /&gt; <br />&lt;html&gt; <br />&lt;head&gt;&lt;title&gt;DES File&lt;/title&gt;&lt;/head&gt; <br /><br />&lt;body bgcolor="#FFFFFF"&gt; <br />&lt;div align="center"&gt;&lt;center&gt; <br />&lt;% <br />String Test = request.getParameter("Test"); <br />if(Test==null || Test.equals("")) { <br />%&gt; <br />    &lt;form name="form" method="post"&gt; <br />    &lt;input type="text" name="Test" size="25" value=""/&gt; <br />    &lt;input type="submit" name="button" value=" 确定 "/&gt; <br />    &lt;/form&gt; <br />    &lt;% <br />}else{ <br />            out.println("加密前的数据："+Test +"&lt;br/&gt;"); <br />            out.println("加密后的数据："+DES.createEncryptor(Test) +"&lt;br/&gt;"); <br />            out.println("解密后的数据："+DES.createDecryptor(DES.createEncryptor(Test)) +"&lt;br/&gt;"); <br />      } <br />    %&gt; <br />&lt;/center&gt;&lt;/div&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; </font>
		<br />
<img src ="http://www.blogjava.net/jelver/aggbug/40945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-13 17:40 <a href="http://www.blogjava.net/jelver/articles/40945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web的系统测试方法</title><link>http://www.blogjava.net/jelver/articles/40943.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Apr 2006 09:37:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/40943.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/40943.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/40943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/40943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/40943.html</trackback:ping><description><![CDATA[随着Internet和Intranet/Extranet的快速增长，Web已经对商业、工业、银行、财政、教育、政府和娱乐及我们的工作和生活产生了深远的影响。许多传统的信息和数据库系统正在被移植到互联网上，电子商务迅速增长，早已超过了国界。范围广泛的、复杂的分布式应用正在Web环境中出现。Web的流行和无所不在，是因为它能提供支持所有类型内容连接的信息发布，容易为最终用户存取。 <br /><br />　　 Yogesh Deshpande和Steve Hansen在1998年就提出了Web工程的概念。Web工程作为一门新兴的学科，提倡使用一个过程和系统的方法来开发高质量的基于Web的系统。它"使用合理的、科学的工程和管理原则，用严密的和系统的方法来开发、发布和维护基于Web的系统"。目前，对于web工程的研究主要是在国外开展的，国内还刚刚起步。 <br /><br />　　 在基于Web的系统开发中，如果缺乏严格的过程，我们在开发、发布、实施和维护Web的过程中，可能就会碰到一些严重的问题，失败的可能性很大。而且，随着基于Web的系统变得越来越复杂，一个项目的失败将可能导致很多问题。当这种情况发生时，我们对Web和Internet的信心可能会无法挽救地动摇，从而引起Web危机。并且，Web危机可能会比软件开发人员所面对的软件危机更加严重、更加广泛。 <br /><br />　　 在Web工程过程中，基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同，它不但需要检查和验证是否按照设计的要求运行，而且还要测试系统在不同用户的浏览器端的显示是否合适。重要的是，还要从最终用户的角度进行安全性和可用性测试。然而，Internet和Web媒体的不可预见性使测试基于Web的系统变得困难。因此，我们必须为测试和评估复杂的基于Web的系统研究新的方法和技术。 <br /><br />　　 一般软件的发布周期以月或以年计算，而Web应用的发布周期以天计算甚至以小时计算。Web测试人员必须处理更短的发布周期，测试人员和测试管理人员面临着从测试传统的C/S结构和框架环境到测试快速改变的Web应用系统的转变。 <br /><br />　　 一、功能测试 <br /><br />　　 1、链接测试 <br /><br />　　 链接是Web应用系统的一个主要特征，它是在页面之间切换和指导用户去一些不知道地址的页面的主要手段。链接测试可分为三个方面。首先，测试所有链接是否按指示的那样确实链接到了该链接的页面；其次，测试所链接的页面是否存在；最后，保证Web应用系统上没有孤立的页面，所谓孤立页面是指没有链接指向该页面，只有知道正确的URL地址才能访问。 <br /><br />　　 链接测试可以自动进行，现在已经有许多工具可以采用。链接测试必须在集成测试阶段完成，也就是说，在整个Web应用系统的所有页面开发完成之后进行链接测试。 <br /><br />　　 2、表单测试 <br /><br />　　 当用户给Web应用系统管理员提交信息时，就需要使用表单操作，例如用户注册、登陆、信息提交等。在这种情况下，我们必须测试提交操作的完整性，以校验提交给服务器的信息的正确性。例如：用户填写的出生日期与职业是否恰当，填写的所属省份与所在城市是否匹配等。如果使用了默认值，还要检验默认值的正确性。如果表单只能接受指定的某些值，则也要进行测试。例如：只能接受某些字符，测试时可以跳过这些字符，看系统是否会报错。 <br /><br />　　 3、Cookies测试 <br /><br />　　 Cookies通常用来存储用户信息和用户在某应用系统的操作，当一个用户使用Cookies访问了某一个应用系统时，Web服务器将发送关于用户的信息，把该信息以Cookies的形式存储在客户端计算机上，这可用来创建动态和自定义页面或者存储登陆等信息。 <br /><br />　　 如果Web应用系统使用了Cookies，就必须检查Cookies是否能正常工作。测试的内容可包括Cookies是否起作用，是否按预定的时间进行保存，刷新对Cookies有什么影响等。 <br /><br />　　 4、设计语言测试 <br /><br />　　 Web设计语言版本的差异可以引起客户端或服务器端严重的问题，例如使用哪种版本的HTML等。当在分布式环境中开发时，开发人员都不在一起，这个问题就显得尤为重要。除了HTML的版本问题外，不同的脚本语言，例如Java、JavaScript、 ActiveX、VBScript或Perl等也要进行验证。 <br /><br />　　 5、数据库测试 <br /><br />　　 在Web应用技术中，数据库起着重要的作用，数据库为Web应用系统的管理、运行、查询和实现用户对数据存储的请求等提供空间。在Web应用中，最常用的数据库类型是关系型数据库，可以使用SQL对信息进行处理。 <br /><br />　　 在使用了数据库的Web应用系统中，一般情况下，可能发生两种错误，分别是数据一致性错误和输出错误。数据一致性错误主要是由于用户提交的表单信息不正确而造成的，而输出错误主要是由于网络速度或程序设计问题等引起的，针对这两种情况，可分别进行测试。 <br /><br />　　 二、性能测试 <br /><br />　　 1、连接速度测试 <br /><br />　　 用户连接到Web应用系统的速度根据上网方式的变化而变化，他们或许是电话拨号，或是宽带上网。当下载一个程序时，用户可以等较长的时间，但如果仅仅访问一个页面就不会这样。如果Web系统响应时间太长（例如超过5秒钟），用户就会因没有耐心等待而离开。 <br /><br />　　 另外，有些页面有超时的限制，如果响应速度太慢，用户可能还没来得及浏览内容，就需要重新登陆了。而且，连接速度太慢，还可能引起数据丢失，使用户得不到真实的页面。 <br /><br />　　 2、负载测试 <br /><br />　　 负载测试是为了测量Web系统在某一负载级别上的性能，以保证Web系统在需求范围内能正常工作。负载级别可以是某个时刻同时访问Web系统的用户数量，也可以是在线数据处理的数量。例如：Web应用系统能允许多少个用户同时在线？如果超过了这个数量，会出现什么现象？Web应用系统能否处理大量用户对同一个页面的请求？ <br /><br />　　 3、压力测试 <br /><br />　　 负载测试应该安排在Web系统发布以后，在实际的网络环境中进行测试。因为一个企业内部员工，特别是项目组人员总是有限的，而一个Web系统能同时处理的请求数量将远远超出这个限度，所以，只有放在Internet上，接受负载测试，其结果才是正确可信的。 <br /><br />　　 进行压力测试是指实际破坏一个Web应用系统，测试系统的反映。压力测试是测试系统的限制和故障恢复能力，也就是测试Web应用系统会不会崩溃，在什么情况下会崩溃。黑客常常提供错误的数据负载，直到Web应用系统崩溃，接着当系统重新启动时获得存取权。 <br /><br />　　 压力测试的区域包括表单、登陆和其他信息传输页面等。 <br /><br />　　 三、可用性测试 <br /><br />　　 1、导航测试 <br /><br />　　 导航描述了用户在一个页面内操作的方式，在不同的用户接口控制之间，例如按钮、对话框、列表和窗口等；或在不同的连接页面之间。通过考虑下列问题，可以决定一个Web应用系统是否易于导航：导航是否直观？Web系统的主要部分是否可通过主页存取？Web系统是否需要站点地图、搜索引擎或其他的导航帮助？ <br /><br />　　 在一个页面上放太多的信息往往起到与预期相反的效果。Web应用系统的用户趋向于目的驱动，很快地扫描一个Web应用系统，看是否有满足自己需要的信息，如果没有，就会很快地离开。很少有用户愿意花时间去熟悉Web应用系统的结构，因此，Web应用系统导航帮助要尽可能地准确。 <br /><br />　　 导航的另一个重要方面是Web应用系统的页面结构、导航、菜单、连接的风格是否一致。确保用户凭直觉就知道Web应用系统里面是否还有内容，内容在什么地方。 <br /><br />　　 Web应用系统的层次一旦决定，就要着手测试用户导航功能，让最终用户参与这种测试，效果将更加明显。 <br /><br />　　 2、图形测试 <br /><br />　　 在Web应用系统中，适当的图片和动画既能起到广告宣传的作用，又能起到美化页面的功能。一个Web应用系统的图形可以包括图片、动画、边框、颜色、字体、背景、按钮等。图形测试的内容有： <br /><br />　　 （1）要确保图形有明确的用途，图片或动画不要胡乱地堆在一起，以免浪费传输时间。Web应用系统的图片尺寸要尽量地小，并且要能清楚地说明某件事情，一般都链接到某个具体的页面。 <br /><br />　　 （2）验证所有页面字体的风格是否一致。 <br /><br />　　 （3）背景颜色应该与字体颜色和前景颜色相搭配。 <br /><br />　　 （4）图片的大小和质量也是一个很重要的因素，一般采用JPG或GIF压缩。 <br /><br />　　 3、内容测试 <br /><br />　　 内容测试用来检验Web应用系统提供信息的正确性、准确性和相关性。 <br /><br />　　 信息的正确性是指信息是可靠的还是误传的。例如，在商品价格列表中，错误的价格可能引起财政问题甚至导致法律纠纷；信息的准确性是指是否有语法或拼写错误。这种测试通常使用一些文字处理软件来进行，例如使用Microsoft Word的"拼音与语法检查"功能；信息的相关性是指是否在当前页面可以找到与当前浏览信息相关的信息列表或入口，也就是一般Web站点中的所谓"相关文章列表"。 <br /><br />　　 4、整体界面测试 <br /><br />　　 整体界面是指整个Web应用系统的页面结构设计，是给用户的一个整体感。例如：当用户浏览Web应用系统时是否感到舒适，是否凭直觉就知道要找的信息在什么地方？整个Web应用系统的设计风格是否一致？ <br />对整体界面的测试过程，其实是一个对最终用户进行调查的过程。一般Web应用系统采取在主页上做一个调查问卷的形式，来得到最终用户的反馈信息。 <br /><br />　　 对所有的可用性测试来说，都需要有外部人员（与Web应用系统开发没有联系或联系很少的人员）的参与，最好是最终用户的参与。 <br /><br />　　 四、客户端兼容性测试 <br /><br />　　 1、平台测试 <br /><br />　　 市场上有很多不同的操作系统类型，最常见的有Windows、Unix、Macintosh、Linux等。Web应用系统的最终用户究竟使用哪一种操作系统，取决于用户系统的配置。这样，就可能会发生兼容性问题，同一个应用可能在某些操作系统下能正常运行，但在另外的操作系统下可能会运行失败。 <br /><br />　　 因此，在Web系统发布之前，需要在各种操作系统下对Web系统进行兼容性测试。 <br /><br />　　 2、浏览器测试 <br /><br />　　 浏览器是Web客户端最核心的构件，来自不同厂商的浏览器对Java，、JavaScript、 ActiveX、 plug-ins或不同的HTML规格有不同的支持。例如，ActiveX是Microsoft的产品，是为Internet Explorer而设计的，JavaScript是Netscape的产品，Java是Sun的产品等等。另外，框架和层次结构风格在不同的浏览器中也有不同的显示，甚至根本不显示。不同的浏览器对安全性和Java的设置也不一样。 <br /><br />　　 测试浏览器兼容性的一个方法是创建一个兼容性矩阵。在这个矩阵中，测试不同厂商、不同版本的浏览器对某些构件和设置的适应性。 <br /><br />　　 五、安全性测试 <br /><br />　　 Web应用系统的安全性测试区域主要有： <br /><br />　　 （1）现在的Web应用系统基本采用先注册，后登陆的方式。因此，必须测试有效和无效的用户名和密码，要注意到是否大小写敏感，可以试多少次的限制，是否可以不登陆而直接浏览某个页面等。 <br /><br />　　 （2）Web应用系统是否有超时的限制，也就是说，用户登陆后在一定时间内（例如15分钟）没有点击任何页面，是否需要重新登陆才能正常使用。 <br /><br />　　 （3）为了保证Web应用系统的安全性，日志文件是至关重要的。需要测试相关信息是否写进了日志文件、是否可追踪。 <br /><br />　　 （4）当使用了安全套接字时，还要测试加密是否正确，检查信息的完整性。 <br /><br />　　 （5）服务器端的脚本常常构成安全漏洞，这些漏洞又常常被黑客利用。所以，还要测试没有经过授权，就不能在服务器端放置和编辑脚本的问题。 <br /><br />　　 六、总结 <br /><br />　　 本文从功能、性能、可用性、客户端兼容性、安全性等方面讨论了基于Web的系统测试方法。 <br /><br />　　 基于Web的系统测试与传统的软件测试既有相同之处，也有不同的地方，对软件测试提出了新的挑战。基于Web的系统测试不但需要检查和验证是否按照设计的要求运行，而且还要评价系统在不同用户的浏览器端的显示是否合适。重要的是，还要从最终用户的角度进行安全性和可用性测试。 <img src ="http://www.blogjava.net/jelver/aggbug/40943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-13 17:37 <a href="http://www.blogjava.net/jelver/articles/40943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP页面查询显示常用模式</title><link>http://www.blogjava.net/jelver/articles/40942.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Apr 2006 09:34:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/40942.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/40942.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/40942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/40942.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/40942.html</trackback:ping><description><![CDATA[title: JSP页面查询显示常用模式 <br /><br />author: evan <br /><br />email: <a class="l2" href="maioto:evan_zhao@hotmail.com" target="_blank"><font color="#0000ff">evan_zhao@hotmail.com</font></a><br />     <br /><b>背景</b>： <br />1．    需要将数据库查询结果在JSP中以列表方式显示 <br />2．    在一个良好的J2EE模式中数据库查询一般用DAO实现（Data Access Object）， JSP仅用于显示数据 <br /><br /><b>问题</b>： <br />    通过JDBC ResultSet可获取查询结果（存在于数据库缓冲区内），但在Statement、Connection关闭后ResultSet即不可用。因此需要一种方式取出所有查询结果并传递至JSP页面。 <br /><br /><b>解决方法一</b>： <br />    使用Value Object。将每条记录均封装成JavaBean对象，把这些对象装入Collection传送给JSP显示。这种方法的缺点是每一种查询都需要定义一个java class，并且将记录数据封装成java对象时也需要很多额外的代码。 <br />示例代码： <br /><br /><div class="codeStyle"><ol><li></li><li><i><font color="#339900">//查询数据代码</font></i></li><li>  <font color="#ff0000">Connection</font> conn = DBUtil.getConnection(); 
</li><li>  <font color="#ff0000">PreparedStatement</font> pst = <b><font color="#0000ff">null</font></b>; 
</li><li>  <font color="#ff0000">ResultSet</font> rs = <b><font color="#0000ff">null</font></b>; 
</li><li>  <b><font color="#0000ff">try</font></b>{ 
</li><li>    <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> sql=“select emp_code, real_name from t_employee where organ_id=?”; 
</li><li>    pst = conn.preparedStatement(sql); 
</li><li>    pst.setString(1, “101”); 
</li><li>    <font color="#ff0000">ResultSet</font> rs = pst.executeQuery(); 
</li><li>    <font color="#ff0000">List</font> list = <b><font color="#0000ff">new</font></b> <font color="#ff0000">ArrayList</font>(); 
</li><li>    Employee emp; 
</li><li>    <b><font color="#0000ff">while</font></b> (rs.next()){ 
</li><li>      emp = <b><font color="#0000ff">new</font></b> Employee(); 
</li><li>      emp.setReakName(rs.getString(“real_name”)); 
</li><li>      emp.setEmpCode(rs.getString(“emp_code”)); 
</li><li>      … 
</li><li>      list.add(emp); 
</li><li>    } 
</li><li>    <b><font color="#0000ff">return</font></b> list; 
</li><li>  }<b><font color="#0000ff">finally</font></b>{ 
</li><li>    DBUtil.close(rs, pst ,conn); 
</li><li>  } 
</li><li></li><li></li><li><i><font color="#339900">//jsp显示部分代码</font></i></li><li>&lt;% 
</li><li>  <font color="#ff0000">List</font> empList = (<font color="#ff0000">List</font>)request.getAttribute(“empList”); 
</li><li>  <b><font color="#0000ff">if</font></b> (empList == <b><font color="#0000ff">null</font></b>) empList = <font color="#ff0000">Collections</font>.EMPTY_LIST; 
</li><li>%&gt; 
</li><li>… 
</li><li>&lt;table  cellspacing=<font color="#ff33ff">"0"</font> width=”90%”&gt; 
</li><li>    &lt;tr&gt;  &lt;td&gt;代码&lt;/td&gt; &lt;td&gt;姓名&lt;/td&gt;  &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  Employee emp; 
</li><li>  <b><font color="#0000ff">for</font></b> (<b><font color="#0000ff">int</font></b> i=0; i&lt; empList.size(); i++){ 
</li><li>    emp = (Employee) empList.get(i); 
</li><li>%&gt; 
</li><li>    &lt;tr&gt;   
</li><li>      &lt;td&gt;&lt;%= emp.getEmpCode()%&gt;&lt;/td&gt;  
</li><li>      &lt;td&gt;&lt;%= emp.getRealName()%&gt;&lt;/td&gt;   
</li><li>    &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  }<i><font color="#339900">// end for</font></i></li><li>%&gt; 
</li><li>&lt;/table&gt; </li></ol></div><br /><br /><b>解决方法二</b>： <br />    遍历ResultSet取出所有数据封装进Collection。 <br />具体做法： <br />1．    生成一个List对象(List list = new ArrayList() )。 <br />2．    生成一个Map对象(Map map = new HashMap() )。使用Map封装一行数据，key为各字段名，value为对应的值。(map.put(“USER_NAME”), rs.getString(“USER_NAME”)) <br />3．    将第2 步生成的Map对象装入第1步的list对象中(list.add(map) )。 <br />4．    重复2、3步直到ResultSet遍历完毕 <br />在DBUtil. resultSetToList(ResultSet rs)方法中实现了上述过程（所有列名均使用大写），可参考使用。 <br /><br /><b>示例代码</b>： <br /><br /><div class="codeStyle"><ol><li></li><li><i><font color="#339900">//查询数据部分代码：</font></i></li><li>  … 
</li><li>  <font color="#ff0000">Connection</font> conn = DBUtil.getConnection(); 
</li><li>  <font color="#ff0000">PreparedStatement</font> pst = <b><font color="#0000ff">null</font></b>; 
</li><li>  <font color="#ff0000">ResultSet</font> rs = <b><font color="#0000ff">null</font></b>; 
</li><li>  <b><font color="#0000ff">try</font></b>{ 
</li><li>    <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> sql=“select emp_code, real_name from t_employee where organ_id=?”; 
</li><li>    pst = conn.preparedStatement(sql); 
</li><li>    pst.setString(1, “101”); 
</li><li>    rs = pst.executeQuery(); 
</li><li>    <font color="#ff0000">List</font> list = DBUtil. resultSetToList(<font color="#ff0000">ResultSet</font> rs); 
</li><li>    <b><font color="#0000ff">return</font></b> list; 
</li><li>  }<b><font color="#0000ff">finally</font></b>{ 
</li><li>    DBUtil.close(rs, pst ,conn); 
</li><li>  } 
</li><li></li><li></li><li></li><li><i><font color="#339900">//JSP显示部分代码</font></i></li><li>&lt;% 
</li><li>  <font color="#ff0000">List</font> empList = (<font color="#ff0000">List</font>)request.getAttribute(“empList”); 
</li><li>  <b><font color="#0000ff">if</font></b> (empList == <b><font color="#0000ff">null</font></b>) empList = <font color="#ff0000">Collections</font>.EMPTY_LIST; 
</li><li>%&gt; 
</li><li>… 
</li><li>&lt;table  cellspacing=<font color="#ff33ff">"0"</font> width=”90%”&gt; 
</li><li>    &lt;tr&gt;  &lt;td&gt;代码&lt;/td&gt; &lt;td&gt;姓名&lt;/td&gt;  &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  <font color="#ff0000">Map</font> colMap; 
</li><li>  <b><font color="#0000ff">for</font></b> (<b><font color="#0000ff">int</font></b> i=0; i&lt; empList.size(); i++){ 
</li><li>    colMap = (<font color="#ff0000">Map</font>) empList.get(i); 
</li><li>%&gt; 
</li><li>  &lt;tr&gt;   
</li><li>    &lt;td&gt;&lt;%=colMap.get(“EMP_CODE”)%&gt;&lt;/td&gt;  
</li><li>    &lt;td&gt;&lt;%=colMap.get(“REAL_NAME”)%&gt;&lt;/td&gt;   
</li><li>  &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  }<i><font color="#339900">// end for</font></i></li><li>%&gt; 
</li><li>&lt;/table&gt; </li></ol></div><br /><br /><b>解决方法三</b>： <br />    使用RowSet。 <br />RowSet是JDBC2.0中提供的接口,Oracle对该接口有相应实现，其中很有用的是oracle.jdbc.rowset.OracleCachedRowSet。 OracleCachedRowSet实现了ResultSet中的所有方法，但与ResultSet不同的是，OracleCachedRowSet中的数据在Connection关闭后仍然有效。 <br /><br />oracle的rowset实现在<a href="http://otn.oracle.com/software/content.html"><font color="#0000ff">http://otn.oracle.com/software/content.html</font></a>的jdbc下载里有，名称是ocrs12.zip <br /><br /><b>示例代码</b>： <br /><br /><div class="codeStyle"><ol><li><i><font color="#339900">//查询数据部分代码：</font></i></li><li>  <b><font color="#0000ff">import</font></b> javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/RowSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>RowSet</u></font></a></b>; 
</li><li>  <b><font color="#0000ff">import</font></b> oracle.jdbc.rowset.OracleCachedRowSet; 
</li><li>  … 
</li><li>  <font color="#ff0000">Connection</font> conn = DBUtil.getConnection(); 
</li><li>  <font color="#ff0000">PreparedStatement</font> pst = <b><font color="#0000ff">null</font></b>; 
</li><li>  <font color="#ff0000">ResultSet</font> rs = <b><font color="#0000ff">null</font></b>; 
</li><li>  <b><font color="#0000ff">try</font></b>{…… 
</li><li>    <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> sql=“select emp_code, real_name from t_employee where organ_id=?”; 
</li><li>    pst = conn.preparedStatement(sql); 
</li><li>    pst.setString(1, “101”); 
</li><li>    rs = pst.executeQuery(); 
</li><li>    OracleCachedRowSet ors = newOracleCachedRowSet(); 
</li><li>    <i><font color="#339900">//将ResultSet中的数据封装到RowSet中</font></i></li><li>    ors.populate(rs); 
</li><li>    <b><font color="#0000ff">return</font></b> ors; 
</li><li>  }<b><font color="#0000ff">finally</font></b>{ 
</li><li>    DBUtil.close(rs, pst, conn); 
</li><li>  } 
</li><li></li><li></li><li><i><font color="#339900">//JSP显示部分代码</font></i></li><li>&lt;% 
</li><li>  javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/RowSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>RowSet</u></font></a></b> empRS = (javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/RowSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>RowSet</u></font></a></b>) request.getAttribute(“empRS”); 
</li><li>%&gt; 
</li><li>… 
</li><li>&lt;table  cellspacing=<font color="#ff33ff">"0"</font> width=”90%”&gt; 
</li><li>    &lt;tr&gt;  &lt;td&gt;代码&lt;/td&gt; &lt;td&gt;姓名&lt;/td&gt;  &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  <b><font color="#0000ff">if</font></b> (empRS != <b><font color="#0000ff">null</font></b>) <b><font color="#0000ff">while</font></b> (empRS.next() ) { 
</li><li>%&gt; 
</li><li>  &lt;tr&gt;   
</li><li>    &lt;td&gt;&lt;%= empRS.get(“EMP_CODE”)%&gt;&lt;/td&gt;  
</li><li>    &lt;td&gt;&lt;%= empRS.get(“REAL_NAME”)%&gt;&lt;/td&gt;   
</li><li>  &lt;/tr&gt; 
</li><li>&lt;% 
</li><li>  }<i><font color="#339900">// end while</font></i></li><li>%&gt; 
</li><li>&lt;/table&gt; </li></ol></div><br /><br /><b>适用场合</b>： <br />  方法一使用于定制的查询操作 <br />  方法二适用于多条查询语句或需要对查询结果进行处理的情况。 <br />  方法三适合于单条查询语句，适用于快速开发。 <br /><br /><br /><b>相关链接</b>： <br />    如果需要分页显示请参考：<a class="l2" href="http://www.javaresearch.org/article/showarticle.jsp?column=106&amp;thread=8893" target="_blank"><font color="#0000ff">JSP分页技术实现</font></a><br />    如果查询结果需要生成WORD或者EXCEL，请参考：<a class="l2" href="http://www.javaresearch.org/article/showarticle.jsp?column=106&amp;thread=8444" target="_blank"><font color="#0000ff">使用jsp实现word、excel格式报表打印</font></a><br /><br />附：<b>DBUtil代码</b>： <br /><div class="codeStyle"><ol><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/List.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>List</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/ArrayList.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ArrayList</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/Map.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Map</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/HashMap.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>HashMap</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/Properties.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Properties</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.util.<b><a href="http://www.cnblogs.com/source/jdk142/java/util/Collections.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Collections</u></font></a></b>; 
</li><li></li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Connection.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Connection</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/ResultSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ResultSet</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/ResultSetMetaData.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ResultSetMetaData</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Statement.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Statement</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/PreparedStatement.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>PreparedStatement</u></font></a></b>; 
</li><li></li><li><b><font color="#0000ff">import</font></b> javax.naming.<b><a href="http://www.cnblogs.com/source/jdk142/javax/naming/Context.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Context</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> javax.naming.<b><a href="http://www.cnblogs.com/source/jdk142/javax/naming/InitialContext.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>InitialContext</u></font></a></b>; 
</li><li><b><font color="#0000ff">import</font></b> javax.naming.<b><a href="http://www.cnblogs.com/source/jdk142/javax/naming/NamingException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>NamingException</u></font></a></b>; 
</li><li></li><li><b><font color="#0000ff">import</font></b> javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/DataSource.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>DataSource</u></font></a></b>; 
</li><li></li><li><b><font color="#0000ff">public</font></b> <b><font color="#0000ff">class</font></b> DBUtil{ 
</li><li></li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">final</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> JDBC_DATA_SOURCE = <font color="#ff33ff">"java:comp/env/jdbc/DataSource"</font>; 
</li><li></li><li>    <i><font color="#339900">/**</font></i></li><li><i><font color="#339900">     enableLocalDebug: 是否在本地调试。&lt;br&gt;</font></i></li><li><i><font color="#339900">     值为true时如果查找数据源失败则使用DriverManager与数据库建立连接；</font></i></li><li><i><font color="#339900">     如果为false则只查找数据源建立数据库连接。</font></i></li><li><i><font color="#339900">     默认为false。&lt;br&gt;</font></i></li><li><i><font color="#339900">     可通过系统属性jdbc.enable_local_debug=true设置enableLocalDebug为true，启用本地调试：&lt;br&gt;</font></i></li><li><i><font color="#339900">     增加JVM parameter： -Djdbc.enable_local_debug=true</font></i></li><li><i><font color="#339900">     */</font></i></li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">boolean</font></b> enableLocalDebug = <b><font color="#0000ff">false</font></b>; 
</li><li></li><li>    <b><font color="#0000ff">static</font></b>{ 
</li><li>        enableLocalDebug = <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/Boolean.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Boolean</u></font></a></b>.getBoolean (<font color="#ff33ff">"jdbc.enable_local_debug"</font>); 
</li><li>    } 
</li><li></li><li></li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/javax/naming/Context.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Context</u></font></a></b> ctx = <b><font color="#0000ff">null</font></b>; 
</li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/DataSource.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>DataSource</u></font></a></b> ds = <b><font color="#0000ff">null</font></b>; 
</li><li></li><li></li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">void</font></b> initDataSource() <b><font color="#0000ff">throws</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/Exception.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Exception</u></font></a></b>{ 
</li><li>        <i><font color="#339900">// Put connection properties in to a hashtable.</font></i></li><li></li><li></li><li>        <b><font color="#0000ff">if</font></b> (ctx == <b><font color="#0000ff">null</font></b>) { 
</li><li>            ctx = <b><font color="#0000ff">new</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/javax/naming/InitialContext.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>InitialContext</u></font></a></b>(); 
</li><li>        } 
</li><li>        <b><font color="#0000ff">if</font></b> (ds == <b><font color="#0000ff">null</font></b>) { 
</li><li>            ds = (javax.sql.<b><a href="http://www.cnblogs.com/source/jdk142/javax/sql/DataSource.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>DataSource</u></font></a></b>) ctx.lookup(JDBC_DATA_SOURCE); 
</li><li>        } 
</li><li>    }         
</li><li></li><li>    <i><font color="#339900">/**</font></i></li><li><i><font color="#339900">     * 查找应用服务器数据源，从数据源中获得数据库连接。&lt;br&gt;&lt;br&gt;</font></i></li><li><i><font color="#339900">     * 在本地调试时如果查找数据源失败并且enableLocalDebug==true</font></i></li><li><i><font color="#339900">     * 则根据系统属性使用java.sql.DriverManager建立连接。&lt;br&gt;</font></i></li><li><i><font color="#339900">     * 本地调试时可配置的系统属性如下：&lt;br&gt;</font></i></li><li><i><font color="#339900">     * &lt;p&gt;</font></i></li><li><i><font color="#339900">     *     #jdbc驱动程序名 &lt;br&gt;</font></i></li><li><i><font color="#339900">     *     jdbc.driver=&lt;i&gt;oracle.jdbc.driver.OracleDriver&lt;/i&gt; &lt;br&gt; &lt;br&gt;</font></i></li><li><i><font color="#339900">     *     #数据库连接串&lt;br&gt;</font></i></li><li><i><font color="#339900">     *     jdbc.url=&lt;i&gt;jdbc:oracle:thin:@10.1.1.1:1521:ocrl&lt;/i&gt; &lt;br&gt; &lt;br&gt;</font></i></li><li><i><font color="#339900">     *     #数据库用户名&lt;br&gt;</font></i></li><li><i><font color="#339900">     *     jdbc.username=&lt;i&gt;scott&lt;/i&gt; &lt;br&gt; &lt;br&gt;</font></i></li><li><i><font color="#339900">     *     #数据库用户密码&lt;br&gt;</font></i></li><li><i><font color="#339900">     *     jdbc.password=&lt;i&gt;tiger&lt;/i&gt; &lt;br&gt;</font></i></li><li><i><font color="#339900">     * &lt;/p&gt;</font></i></li><li><i><font color="#339900">     * 可通过JVM参数设置上述系统属性：&lt;br&gt;</font></i></li><li><i><font color="#339900">     * -Djdbc.driver=oracle.jdbc.driver.OracleDriver </font></i></li><li><i><font color="#339900">     *  -Djdbc.url=jdbc:oracle:thin:@10.1.1.1:1521:ocrl</font></i></li><li><i><font color="#339900">     *  -Djdbc.username=scott -Djdbc.password=tiger</font></i></li><li><i><font color="#339900">     * @return Connection</font></i></li><li><i><font color="#339900">     * @throws NamingException 如果数据源查找失败</font></i></li><li><i><font color="#339900">     * @throws SQLException 如果建立数据库连接失败</font></i></li><li><i><font color="#339900">     */</font></i></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Connection.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Connection</u></font></a></b> getConnection() <b><font color="#0000ff">throws</font></b>  <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b>{ 
</li><li>        <b><font color="#0000ff">try</font></b>{ 
</li><li>            initDataSource(); 
</li><li>            <b><font color="#0000ff">return</font></b> ds.getConnection(); 
</li><li>        }<b><font color="#0000ff">catch</font></b>(<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b> sqle){ 
</li><li>            <b><font color="#0000ff">throw</font></b> sqle; 
</li><li>        }<b><font color="#0000ff">catch</font></b>(<b><a href="http://www.cnblogs.com/source/jdk142/java/lang/Exception.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Exception</u></font></a></b> ne){ 
</li><li>            <b><font color="#0000ff">if</font></b> (enableLocalDebug){ 
</li><li>                <b><font color="#0000ff">return</font></b> getTestConn(); 
</li><li>            }<b><font color="#0000ff">else</font></b>{ 
</li><li>                <b><font color="#0000ff">throw</font></b> <b><font color="#0000ff">new</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/RuntimeException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>RuntimeException</u></font></a></b>(ne.toString()); 
</li><li>            } 
</li><li>        } 
</li><li>    } 
</li><li></li><li></li><li>    <i><font color="#339900">//通过DriverManager建立本地测试连接</font></i></li><li>    <b><font color="#0000ff">private</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Connection.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Connection</u></font></a></b> getTestConn(){ 
</li><li>      <b><font color="#0000ff">try</font></b> { 
</li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> driver = <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.getProperty(<font color="#ff33ff">"jdbc.driver"</font>); 
</li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.out.println(<font color="#ff33ff">"jdbc.driver="</font>+driver); 
</li><li></li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> url = <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.getProperty(<font color="#ff33ff">"jdbc.url"</font>); 
</li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.out.println(<font color="#ff33ff">"jdbc.url="</font>+url); 
</li><li></li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> userName = <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.getProperty(<font color="#ff33ff">"jdbc.username"</font>); 
</li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.out.println(<font color="#ff33ff">"jdbc.username="</font>+userName); 
</li><li></li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>String</u></font></a></b> password = <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.getProperty(<font color="#ff33ff">"jdbc.password"</font>); 
</li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>System</u></font></a></b>.out.println(<font color="#ff33ff">"jdbc.password="</font>+password); 
</li><li></li><li>          <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/Class.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Class</u></font></a></b>.forName(driver).newInstance(); 
</li><li>          <b><font color="#0000ff">return</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/DriverManager.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>DriverManager</u></font></a></b>.getConnection(url, userName, password); 
</li><li>      } 
</li><li>      <b><font color="#0000ff">catch</font></b> (<b><a href="http://www.cnblogs.com/source/jdk142/java/lang/Exception.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Exception</u></font></a></b> ex) { 
</li><li>        ex.printStackTrace(); 
</li><li>        <b><font color="#0000ff">throw</font></b> <b><font color="#0000ff">new</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/lang/RuntimeException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>RuntimeException</u></font></a></b>(ex.getMessage()); 
</li><li>      } 
</li><li>    } 
</li><li></li><li>    <i><font color="#339900">/**</font></i></li><li><i><font color="#339900">     * 将查询结果封装成List。&lt;br&gt;</font></i></li><li><i><font color="#339900">     * List中元素类型为封装一行数据的Map，Map key为字段名（大写），value为相应字段值</font></i></li><li><i><font color="#339900">     * @param rs ResultSet</font></i></li><li><i><font color="#339900">     * @return List</font></i></li><li><i><font color="#339900">     * @throws java.sql.SQLException</font></i></li><li><i><font color="#339900">     */</font></i></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">static</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/util/List.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>List</u></font></a></b> resultSetToList(<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/ResultSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ResultSet</u></font></a></b> rs) <b><font color="#0000ff">throws</font></b> java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b>{ 
</li><li>        <b><font color="#0000ff">if</font></b> (rs==<b><font color="#0000ff">null</font></b>) <b><font color="#0000ff">return</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/util/Collections.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Collections</u></font></a></b>.EMPTY_LIST; 
</li><li></li><li>        <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/ResultSetMetaData.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ResultSetMetaData</u></font></a></b> md = rs.getMetaData(); 
</li><li>        <b><font color="#0000ff">int</font></b> columnCount = md.getColumnCount(); 
</li><li></li><li>        <b><a href="http://www.cnblogs.com/source/jdk142/java/util/List.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>List</u></font></a></b> list = <b><font color="#0000ff">new</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/util/ArrayList.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ArrayList</u></font></a></b>(); 
</li><li>        <b><a href="http://www.cnblogs.com/source/jdk142/java/util/Map.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Map</u></font></a></b> rowData; 
</li><li>        <b><font color="#0000ff">while</font></b> (rs.next()){ 
</li><li>            rowData = <b><font color="#0000ff">new</font></b> <b><a href="http://www.cnblogs.com/source/jdk142/java/util/HashMap.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>HashMap</u></font></a></b>(columnCount); 
</li><li>            <b><font color="#0000ff">for</font></b> (<b><font color="#0000ff">int</font></b> i=1; i&lt;=columnCount; i++){ 
</li><li>                rowData.put(md.getColumnName(i),rs.getObject(i)); 
</li><li>            } 
</li><li>            list.add(rowData); 
</li><li>        } 
</li><li>        <b><font color="#0000ff">return</font></b> list; 
</li><li>    } 
</li><li></li><li>    <i><font color="#339900">/**</font></i></li><li><i><font color="#339900">     * 关闭ResultSet、Statement和Connection</font></i></li><li><i><font color="#339900">     * @param rs ResultSet to be closed</font></i></li><li><i><font color="#339900">     * @param stmt Statement or PreparedStatement  to be closed</font></i></li><li><i><font color="#339900">     * @param conn Connection  to be closed</font></i></li><li><i><font color="#339900">     */</font></i></li><li>    <b><font color="#0000ff">public</font></b> <b><font color="#0000ff">static</font></b> <b><font color="#0000ff">void</font></b> close(<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/ResultSet.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>ResultSet</u></font></a></b> rs, <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Statement.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Statement</u></font></a></b> stmt, <b><a href="http://www.cnblogs.com/source/jdk142/java/sql/Connection.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>Connection</u></font></a></b> conn){ 
</li><li>            <b><font color="#0000ff">if</font></b> (rs != <b><font color="#0000ff">null</font></b>) <b><font color="#0000ff">try</font></b>{ 
</li><li>                rs.close(); 
</li><li>            }<b><font color="#0000ff">catch</font></b>(java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b> ex){ 
</li><li>                ex.printStackTrace(); 
</li><li>            } 
</li><li>            <b><font color="#0000ff">if</font></b> (stmt != <b><font color="#0000ff">null</font></b>) <b><font color="#0000ff">try</font></b>{ 
</li><li>                 stmt.close(); 
</li><li>            }<b><font color="#0000ff">catch</font></b>(java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b> ex){ 
</li><li>                ex.printStackTrace(); 
</li><li>            } 
</li><li>            <b><font color="#0000ff">if</font></b> (conn != <b><font color="#0000ff">null</font></b>) <b><font color="#0000ff">try</font></b>{ 
</li><li>                conn.close(); 
</li><li>            }<b><font color="#0000ff">catch</font></b>(java.sql.<b><a href="http://www.cnblogs.com/source/jdk142/java/sql/SQLException.java.html" target="_blank"><font class="classLink" color="#0000ff"><u>SQLException</u></font></a></b> ex){ 
</li><li>                ex.printStackTrace(); 
</li><li>            } 
</li><li>    } 
</li><li></li><li>}<i><font color="#339900">// end of DBUtil</font></i></li></ol></div><br /><img src ="http://www.blogjava.net/jelver/aggbug/40942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-13 17:34 <a href="http://www.blogjava.net/jelver/articles/40942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何在Web应用中启动后台任务的实例讲解(zhuan)</title><link>http://www.blogjava.net/jelver/articles/40941.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Thu, 13 Apr 2006 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/40941.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/40941.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/40941.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/40941.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/40941.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#333333">
				</font>我们常常在Web应用中需要启动一个自己写的服务，本文的目的是给你提供一个解决方案。<br /><br />原理<br /><br />本方案的原理是写一个实现了ServletContextListener接口的类，该类中有<span id="tech_art_center"></span>两个方法：</p>
		<p>public void contextInitialized(ServletContextEvent sce)</p>
		<p>它是在应用启动时调用；另一个方法是：</p>
		<p>public void contextDestroyed(ServletContextEvent sce)</p>
		<p>该方法是在应用结束时调用。<br /><br />    把我们要启动的后台应用逻辑放在contextInitialized方法中实现；把释放后台应用占用资源的工作放在contextDestroyed来处理。但我们启动的后台任务常常是有要求的，比如时间，频率等，我在这里使用了一个开源组件：quartz。<br /><br />步骤<br /><br />1、写业务调用类：<br /><br /></p>
		<center>
				<ccid_nobr>
						<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
								<tbody>
										<tr>
												<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
														<pre>
																<ccid_code>// DumbJob.java
import org.quartz.*;
import java.util.*;
  public class DumbJob implements Job 
  {
    public DumbJob()
	{
    }
    public void execute
	(JobExecutionContext context)
      throws JobExecutionException
    {
     //在这里写业务处理代码。
    }
  }</ccid_code>
														</pre>
												</td>
										</tr>
								</tbody>
						</table>
				</ccid_nobr>
		</center>
		<br />
		<br />本类的主要功能是由quartz中调度类按照指定的规则进行调用执行必要的业务逻辑。 <br /><br />2、写调度类 <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>// TestShedule.java
import org.quartz.*;
import java.util.*;

public class TestShedule
{
    static SchedulerFactory 
	schedFact = new org.quartz.
	impl.StdSchedulerFactory();
    static Scheduler sched;
    
    public static void run()throws Exception
	{        
        sched = schedFact.getScheduler();
		//获取调度管理器
          JobDetail jobDetail =
		  new JobDetail("myJob",
      sched.DEFAULT_GROUP,
   DumbJob.class);
   //创建工作
        CronTrigger trigger = 
		new CronTrigger
		("myTrigger","test","0/10 * * * * ?");
		//创建触发器
        sched.scheduleJob(jobDetail, trigger);
		//添加到调度管理器中
        sched.start();//启动调度管理器
    }
    
    public static void     
	stop()throws Exception
	{
        sched.shutdown();
    }
}</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />本类的目的是设置调用规则，在这里我用了“0/10 * * * * ?”表示每10秒钟就执行一次。 <br /><br />3、编写服务启动类： <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>//ServiceLoader.java
import javax.servlet.
ServletContextEvent;
import javax.servlet.
ServletContextListener;

public class ServiceLoader 
implements ServletContextListener
{
    public void 
	contextInitialized
	(ServletContextEvent sce)
	{
        try{
            TestShedule.run();
        }catch(Exception ex)
		{
System.out.println(ex.getMessage());
        }
    }
    
    public void contextDestroyed
	(ServletContextEvent sce) 
	{
        try{
            TestShedule.stop();
        }catch(Exception ex)
		{
 System.out.println(ex.getMessage());
        }
    }
}</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />在contextInitialized中调用TestShedule.run()启动后台任务；在contextDestroyed中调用TestShedule.stop()停止后台任务。 <br /><br />4、部署服务启动类 <br /><br />在web.xml文件中增加如下一行配置： <br /><br /><center><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;?xml version="1.0" 
encoding="UTF-8"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-
//Sun Microsystems, Inc.
//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
&lt;web-app id="WebApp"&gt;
    &lt;display-name&gt;root&lt;/display-name&gt;
&lt;!--下边的listener部分就是配置信息--&gt;
    &lt;listener&gt;
        &lt;listener-class&gt;ServiceLoader
		&lt;/listener-class&gt;
    &lt;/listener&gt;
    &lt;welcome-file-list&gt;
        &lt;welcome-file&gt;index.html
		&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;
&lt;/web-app&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr></center><br /><br />5、启动web服务即可。 <br /><br />总结 <br /><br />其实实现这个功能的方法很多，我在这里是应用了ServletContextListener接口和开源api quartz，希望能对你的开发有所帮助。<img src ="http://www.blogjava.net/jelver/aggbug/40941.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-04-13 17:32 <a href="http://www.blogjava.net/jelver/articles/40941.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WEB编程开发常用的代码 (zhuan)</title><link>http://www.blogjava.net/jelver/articles/35035.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 13 Mar 2006 06:50:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/35035.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/35035.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/35035.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/35035.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/35035.html</trackback:ping><description><![CDATA[<P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2><SPAN class=style6>
<H1 class=ContentTitle><STRONG>WEB编程开发常用的代码</STRONG></H1>
<DIV class=Content-Info>
<DIV class=InfoOther>字体大小: </DIV>
<DIV class=InfoAuthor><IMG style="MARGIN: 0px 2px -6px 0px" alt="" src="http://www.renzhiyuan.com/images/weather/hn2_sunny.gif"><IMG alt="" src="http://www.renzhiyuan.com/images/weather/hn2_t_sunny.gif"> <IMG style="MARGIN: 0px 2px -1px 0px" alt="" src="http://www.renzhiyuan.com/images/level3.gif"> </DIV></DIV>
<DIV class=Content-body id=logPanel>1. ASP与Access数据库连接： <BR>dim conn,mdbfile <BR>mdbfile=server.mappath("数据库名称.mdb") <BR>set conn=server.createobject("adodb.connection") <BR>'conn.open "driver={microsoft access driver (*.mdb)};uid=admin;pwd=数据库密码;dbq="&amp;mdbfile<BR>conn.open "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = " &amp; mdbfile <BR><BR><BR>2. ASP与SQL数据库连接： dim conn <BR>set conn=server.createobject("ADODB.connection") <BR>con.open "PROVIDER=SQLOLEDB;DATA SOURCE=SQL服务器名称或IP地址;UID=sa;PWD=数据库密码;DATABASE=数据库名称;" <BR><BR><BR>建立记录集对象： set rs=server.createobject("adodb.recordset") <BR>rs.open SQL语句,conn,3,2 <BR><BR><BR>SQL常用命令使用方法： <BR><BR>数据记录筛选： sql="select * from 数据表 where 字段名=字段值 order by 字段名 " <BR>sql="select * from 数据表 where 字段名 like ‘%字段值%‘ order by 字段名 " <BR>sql="select top 10 * from 数据表 where 字段名 order by 字段名 " <BR>sql="select * from 数据表 where 字段名 in (‘值1‘,‘值2‘,‘值3‘)" <BR>sql="select * from 数据表 where 字段名 between 值1 and 值2" <BR>更新数据记录： sql="update 数据表 set 字段名=字段值 where 条件表达式" <BR>sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表达式" <BR><BR><BR>删除数据记录： sql="delete from 数据表 where 条件表达式" <BR>sql="delete from 数据表" (将数据表所有记录删除) <BR><BR><BR>添加数据记录： sql="insert into 数据表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)" <BR>sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到目标数据表) <BR>数据记录统计函数： <BR>AVG(字段名) 得出一个表格栏平均值 <BR>COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计 <BR>MAX(字段名) 取得一个表格栏最大的值 <BR>MIN(字段名) 取得一个表格栏最小的值 <BR>SUM(字段名) 把数据栏的值相加 <BR><BR>引用以上函数的方法： sql="select sum(字段名) as 别名 from 数据表 where 条件表达式" <BR>set rs=conn.excute(sql) <BR>用 rs("别名") 获取统的计值，其它函数运用同上。 <BR><BR><BR>数据表的建立和删除： Create TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… ) <BR>例：Create TABLE tab01(name varchar(50),datetime default now()) <BR>Drop TABLE 数据表名称 (永久性删除一个数据表) <BR><BR><BR>记录集对象的方法： <BR>rs.movenext 将记录指针从当前的位置向下移一行 <BR>rs.moveprevious 将记录指针从当前的位置向上移一行 <BR>rs.movefirst 将记录指针移到数据表第一行 <BR>rs.movelast 将记录指针移到数据表最后一行 <BR>rs.absoluteposition=N 将记录指针移到数据表第N行 <BR>rs.absolutepage=N 将记录指针移到第N页的第一行 <BR>rs.pagesize=N 设置每页为N条记录 <BR>rs.pagecount 根据 pagesize 的设置返回总页数 <BR>rs.recordcount 返回记录总数 <BR>rs.bof 返回记录指针是否超出数据表首端，true表示是，false为否 <BR>rs.eof 返回记录指针是否超出数据表末端，true表示是，false为否 <BR>rs.delete 删除当前记录，但记录指针不会向下移动 <BR>rs.addnew 添加记录到数据表末端 <BR>rs.update 更新数据表记录 <BR><BR>判断所填数据是数字型 <BR>if not isNumeric(request("字段名称")) then <BR>response.write "不是数字" <BR>else <BR>response.write "数字" <BR>end if <BR>页面执行时间：<BR><BR><BR>&lt;%startime = Timer()%&gt; <BR>.... .... <BR>内容 <BR>... ... <BR>结尾 <BR>&lt;% <BR>Dim Endtime <BR>Endtime = Timer() <BR>response.write "页面执行时间：&lt;font color=red&gt;"&amp;FormatNumber((Endtime-Startime)*1000,5)&amp;"&lt;/font&gt; 毫秒" <BR>%&gt; <BR>定义打开网页时起始窗口的大小<BR>&lt;script for="window" event="onload"&gt; <BR>window.resizeTo(500,300) <BR>&lt;/script&gt; <BR>随机数:<BR>&lt;%randomize%&gt; <BR>&lt;%=(int(rnd()*n)+1)%&gt; <BR><BR><BR>查询数据时得到的记录关键字用红色显示：<BR>replace(RS("字段X"),searchname,"&lt;font color=#FF0000&gt;" &amp; searchname &amp; "&lt;/font&gt;") <BR><BR><BR>通过asp的手段来检查来访者是否用了代理<BR>&lt;% if Request.ServerVariables("HTTP_X_FORWARDED_FOR")&lt;&gt;"" then <BR>response.write "&lt;font color=#FF0000&gt;您通过了代理服务器，"&amp; _ <BR>"真实的IP为"&amp;Request.ServerVariables("HTTP_X_FORWARDED_FOR") <BR>end if <BR>%&gt; <BR><BR>判断上一页的来源<BR>request.servervariables("HTTP_REFERER") <BR>javascript: document.referrer <BR><BR><BR>清除缓存，重新加载页面<BR>&lt;%response.expires = 0 <BR>response.expiresabsolute = now() - 1 <BR>response.addHeader "pragma","no-cache" <BR>response.addHeader "cache-control","private" <BR>Response.cachecontrol = "no-cache" <BR>%&gt; <BR><BR><BR>检索并删除数据库里的重复记录<BR>conn.execute("delete from table where id not in (select distinct from table)") <BR><BR>文件删除函数 &lt;% <BR>'文件删除函数 <BR>function deletefile(filename) <BR>if filename&lt;&gt;"" then <BR>set fso=server.CreateObject("scripting.filesystemobject") <BR>if fso.FileExists(filename) then <BR>fso.DeleteFile filename <BR>else <BR>Response.Write "&lt;script&gt;alert(’该文件不存在’);&lt;/script&gt;" <BR>end if <BR>end if <BR>end function <BR><BR>strfile=server.MapPath("fileName") <BR>deletefile(strfile) <BR>%&gt; <BR><BR>ASP字数计算函数 &lt;% <BR>Function WordCount(strInput) <BR>Dim strTemp <BR>strTemp = Replace(strInput, vbTab, " ") <BR>strTemp = Replace(strTemp, vbCr, " ") <BR>strTemp = Replace(strTemp, vbLf, " ") <BR><BR>' 删除字首字尾空格 <BR>strTemp = Trim(strTemp) <BR><BR>' 替换为一个空格 <BR>Do While InStr(1, strTemp, " ", 1) &lt;&gt; 0 <BR>strTemp = Replace(strTemp, " ", " ") <BR>Loop <BR>WordCount = UBound(Split(strTemp, " ", -1, 1)) +1 <BR>End Function <BR>%&gt; <BR>全正则的检测IP是否合法的函数 function checkIP2(sIPAddress)<BR>{<BR>var exp=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;<BR>var reg = sIPAddress.match(exp);<BR>var ErrMsg="你输入的是一个非法的IP地址段！\nIP段为：:xxx.xxx.xxx.xxx（xxx为0-255)！" <BR>var Msg="你输入的是一个合法的IP地址段！" <BR>if(reg==null)<BR>{<BR>alert(ErrMsg);<BR>}<BR>else<BR>{<BR>alert(reg);<BR>}<BR>}<BR><BR><BR>关闭子窗口时刷新父窗口 在子窗口<BR>&lt;script language="javascript"&gt;<BR>window.opener.location="父窗口页面"<BR>window.close()<BR>&lt;/script&gt; <BR><BR><BR>文本框输入限制：<BR>&lt;script&gt;<BR>function regInput(obj, reg, inputStr)<BR>{<BR>var docSel = document.selection.createRange()<BR>if (docSel.parentElement().tagName != "INPUT") return false<BR>oSel = docSel.duplicate()<BR>oSel.text = ""<BR>var srcRange = obj.createTextRange()<BR>oSel.setEndPoint("StartToStart", srcRange)<BR>var str = oSel.text + inputStr + srcRange.text.substr(oSel.text.length)<BR>return reg.test(str)<BR>}<BR>&lt;/script&gt;<BR><BR>小写英文：&lt;xmp style= "display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^[a-z]*$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^[a-z]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[a-z]*$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"<BR>&gt;&lt;br&gt;<BR><BR>大写英文：&lt;xmp style= "display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^[A-Z]*$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^[A-Z]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[A-Z]*$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"&gt;<BR>&lt;br&gt;<BR><BR>任意数字：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^[0-9]*$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^[0-9]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[0-9]*$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"<BR>&gt;&lt;br&gt;<BR><BR>限2位小数：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^\d*\.?\d{0,2}$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^\d*\.?\d{0,2}$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^\d*\.?\d{0,2}$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"<BR>&gt; 如: 123.12&lt;br&gt;<BR><BR><BR>日　 期：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^\d{1,4}([-\/](\d{1,2}([-\/](\d{1,2})?)?)?)?$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^\d{1,4}([-\/](\d{1,2}([-\/](\d{1,2})?)?)?)?$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^\d{1,4}([-\/](\d{1,2}([-\/](\d{1,2})?)?)?)?$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"<BR>&gt; 如: 2002-9-29&lt;br&gt;<BR><BR>任意中文：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^[\u4E00-\u9FA5]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[\u4E00-\u9FA5]*$/, event.dataTransfer.getData('Text'))"<BR>&gt;&lt;br&gt;<BR><BR>部分英文：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR>&lt;input onkeypress = "return regInput(this, /^[a-e]*$/, String.fromCharCode(event.keyCode))"<BR>onpaste = "return regInput(this, /^[a-e]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[a-e]*$/, event.dataTransfer.getData('Text'))"<BR>style="ime-mode:Disabled"<BR>&gt; 范围: a,b,c,d,e&lt;br&gt;<BR><BR>部分中文：&lt;xmp style="display:inline"&gt; &lt;/xmp&gt;<BR><BR>&lt;script language=javascript&gt;<BR>function checkChinese(oldLength, obj)<BR>{<BR>var oTR = window.document.selection.createRange()<BR>var reg = /[^一二三四五六七***十]/g<BR>oTR.moveStart("character", -1*(obj.value.length-oldLength))<BR>oTR.text = oTR.text.replace(reg, "")<BR>}<BR>&lt;/script&gt;<BR>&lt;input onkeypress="return false" onkeydown="setTimeout('checkChinese('+this.value.length+','+this.uniqueID+')', 1)"<BR>onpaste = "return regInput(this, /^[一二三四五六七***十]*$/, window.clipboardData.getData('Text'))"<BR>ondrop = "return regInput(this, /^[一二三四五六七***十]*$/, event.dataTransfer.getData('Text'))"<BR>&gt; 范围: 一二三四五六七***十&lt;br&gt; <BR><BR>[Ctrl+A 全选 Ctrl+C 复制]<BR><BR>不能点右键，不用CTRL+A，不能复制作!<BR>&lt;body oncontextmenu="window.event.returnValue=false" <BR>onkeypress="window.event.returnValue=false" <BR>onkeydown="window.event.returnValue=false" <BR>onkeyup="window.event.returnValue=false" <BR>ondragstart="window.event.returnValue=false" <BR>onselectstart="event.returnValue=false"&gt; <BR>&lt;/body&gt;<BR><BR>显示状态拦固定文字：<BR>放在body前 <BR>&lt;base onmouseover="window.status='这里是Goaler的Blog系统，欢迎访问';return true"&gt; <BR><BR><BR>用键盘打开网页 &lt;script language=javascript&gt;<BR>document.onkeydown=gopage<BR>var add="Admin/AddArticle.asp"<BR>var logon="Admin/Logon.asp"<BR>function gopage() {<BR>if (event.keyCode==13) location=add<BR>if (event.keyCode==38) location=logon<BR>}<BR>&lt;/script&gt; <BR><BR><BR>根据内容自动调整iframe高度 有时为了方便使用Iframe，但被潜入的页面长度不是固定的，显示滚动条不仅影响美观还对用户操作带来不便，自动调整高度可以解决这个问题。^_^<BR><BR>function f_frameStyleResize(targObj)<BR>{<BR>var targWin = targObj.parent.document.all[targObj.name];<BR>if(targWin != null)<BR>{<BR>var HeightValue = targObj.document.body.scrollHeight<BR>if(HeightValue &lt; 600){HeightValue = 600} //不小于600<BR>targWin.style.pixelHeight = HeightValue;<BR>}<BR>}<BR>function f_iframeResize()<BR>{<BR>bLoadComplete = true;<BR>f_frameStyleResize(self);<BR>}<BR><BR>var bLoadComplete = false;<BR>window.onload = f_iframeResize;<BR><BR><BR>禁止页面正文内容被选取 <BR><BR><BR>&lt;body oncontextmenu="return false" ondragstart="return false" onselectstart ="return false" onselect="document.selection.empty()" oncopy="document.selection.empty()" onbeforecopy="return <BR>false"onmouseup="document.selection.empty()"&gt; <BR><BR><BR>消除ie6自动出现的图像工具栏，设置 GALLERYIMG属性为false或no . <BR><BR><BR>&lt;IMG SRC="mypicture.jpg" HEIGHT="100px" WIDTH="100px" GALLERYIMG="no"&gt; <BR><BR><BR>防止点击空链接时，页面往往重置到页首端。 <BR><BR><BR>代码“javascript:void(null)”代替原来的“#”标记 <BR><BR><BR>如何避免别人把你的网页放在框架中 <BR><BR><BR>&lt;script language=“javascript”&gt;&lt;!--if (self!=top){top.location=self.location;} --&gt;&lt; /script&gt; <BR><BR><BR>页面定时刷新 <BR><BR><BR>&lt;meta http-equiv="Refresh" content="秒" &gt; <BR><BR><BR>页面定时转向新的地址 <BR><BR><BR>&lt;meta http-equiv="refresh" content="秒;URL=url"&gt; <BR><BR><BR>关闭窗口，这个是不会弹出提示直接关的： <BR>把如下代码加入&lt;body&gt;区域中 <BR><BR><BR>&lt;OBJECT id=closes type="application/x-oleobject" classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"&gt; <BR>&lt;param name="Command" value="Close"&gt; <BR>&lt;/object&gt; <BR>&lt;script language="JavaScript"&gt;function shutwin(){closes.Click();return;}&lt;/script&gt; <BR>&lt;a href="javascript:shutwin();"&gt;关闭本窗口&lt;/a&gt; <BR><BR><BR>有时候好不容易写出来的程序代码被别人抄去，心里一定不好受。这还是小事，但如果在我们的源代码中有一些不希望让别人知道的内容，比如密码、Action的指向等，这些一旦被人利用，那后果有时是不堪设想的。而网页加密就是我们现在需要解决的问题。下面就我在网页制作中的一些经验向大家介绍一些简单的防范方法。 <BR>禁止右键 <BR>看到这里大家一定会想，这招有很多人介绍过了，而且破解的方法也有很多。但我这里要说的是另一种方法，而且我试了很多方法都没有能破解。具体如下： <BR><BR><BR>&lt;html&gt; <BR>&lt;head&gt; <BR>&lt;script&gt; <BR>function stop(){ <BR>alert("试试能破解吗？"); <BR>return false; <BR>} <BR>document.oncontextmenu=stop; <BR>&lt;/script&gt; <BR>&lt;boyd&gt;你可以按右键、shift+F10和右ctrl左边的那个键试试！看能不能解。^_^&lt;/body&gt; <BR><BR><BR>大家试试，看能不能破解！你可以将alert("试试能破解吗？");这句去掉，这样当按右键时就什么反应也没有了，就好像没有右键功能一样。 <BR><BR>禁示查看源代码 <BR>我们已经禁了右键，但从"查看"菜单下的"源文件"中同样可以看到源代码，下面我们就来解决这个问题： <BR>其实这只要使用一个含有&lt;frame&gt;&lt;/frame&gt;标记的网页便可以达到目的。 <BR><BR><BR>&lt;frameset&gt; <BR>&lt;frame src="你要保密的文件的URL"&gt; <BR>&lt;/frameset&gt; <BR><BR><BR>这样当有人使用"查看"下的"源文件"的时候，看到的将是上面的那段代码，而你真正的文件又躲过一劫。 <BR><BR>禁示另存为 <BR>通过上面的两步好像你的源代码已经安全了，但别忘了，别人还可以将你的页面保存下来，再慢慢分析。不过别担心，下面我们来解决这个问题。 <BR>在你要保密的网页中加入以下代码： <BR><BR><BR>&lt;noscript&gt;&lt;iframe src="/*.htm"&gt;&lt;/iframe&gt;&lt;/noscript&gt; <BR><BR><BR>彻底屏蔽右键方法。<BR><BR><BR>&lt;body oncontextmenu="return false"&gt; <BR><BR><BR>双击页面后自动滚屏，单击后停止。<BR><BR><BR>&lt;SCRIPT language=JavaScript&gt; <BR>var currentpos,timer; <BR>function initialize() <BR>{ timer=setInterval("scrollwindow()",16); } <BR>function sc(){ <BR>clearInterval(timer); <BR>} <BR>function scrollwindow() <BR>{currentpos=document.body.scrollTop; <BR>window.scroll(0,++currentpos); <BR>if (currentpos != document.body.scrollTop) <BR>sc(); <BR>} <BR>document.onmousedown=sc <BR>document.ondblclick=initialize <BR>&lt;/script&gt; <BR><BR><BR>设定脚本出错能继续运行<BR><BR><BR>&lt;script language="javascript"&gt; <BR>function KillError() <BR>{ <BR>return false; <BR>} <BR>window.onerror=KillError; <BR>&lt;/script&gt;<BR>将彻底屏蔽鼠标右键<BR><BR>oncontextmenu="window.event.returnvalue=false" <BR><BR><BR>可用于Table <BR><BR>&lt;table border oncontextmenu=return(false)&gt;&lt;td&gt;no&lt;/table&gt; <BR><BR><BR>取消选取、防止复制<BR><BR>&lt;body onselectstart="return false"&gt; <BR><BR><BR>不准粘贴 <BR><BR><BR>onpaste="return false" <BR><BR><BR>防止复制<BR><BR><BR>oncopy="return false;" oncut="return false;" <BR><BR><BR>IE地址栏前换成自己的图标 <BR><BR>&lt;link rel="Shortcut Icon" href="favicon.ico"&gt; <BR><BR><BR>可以在收藏夹中显示出你的图标 <BR><BR><BR>&lt;link rel="Bookmark" href="favicon.ico"&gt; <BR><BR><BR>关闭输入法<BR><BR>&lt;input style="ime-mode:disabled"&gt; <BR><BR><BR>永远都会带着框架 <BR><BR><BR>&lt;script language="javascript"&gt;&lt;!-- <BR>if (window == top)top.location.href = "frames.htm"; <BR>//frames.htm为框架网页 <BR>// --&gt; <BR>&lt;/script&gt; <BR><BR><BR>防止被人frame <BR><BR><BR>&lt;SCRIPT LANGUAGE=javascript&gt;&lt;!-- <BR>if (top.location != self.location) <BR>top.location=self.location; <BR>// --&gt; <BR>&lt;/SCRIPT&gt; <BR><BR><BR>怎样通过asp的手段来检查来访者是否用了代理 <BR><BR><BR>&lt;% if Request.ServerVariables("HTTP_X_FORWARDED_FOR")&lt;&gt;"" then <BR>response.write "&lt;font color=#FF0000&gt;您通过了代理服务器，" &amp; "真实的IP为 "&amp;Request.ServerVariables("HTTP_X_FORWARDED_FOR") <BR>end if <BR>%&gt; <BR><BR><BR>取得控件的绝对位置 <BR><BR><BR>//javascript <BR>&lt;script language="javascript"&gt; <BR>function getIE(e){ <BR>var t=e.offsetTop; <BR>var l=e.offsetLeft; <BR>while(e=e.offsetParent){ <BR>t+=e.offsetTop; <BR>l+=e.offsetLeft; <BR>} <BR>alert("top="+t+"nleft="+l); <BR>} <BR>&lt;/script&gt; <BR><BR>//VBScript <BR>&lt;script language="VBScript"&gt;<BR>&lt;!-- <BR>function getIE() <BR>dim t,l,a,b <BR>set a=document.all.img1 <BR>t=document.all.img1.offsetTop <BR>l=document.all.img1.offsetLeft <BR>while a.tagName&lt;&gt;"BODY" <BR>set a = a.offsetParent <BR>t=t+a.offsetTop <BR>l=l+a.offsetLeft <BR>wend <BR>msgbox "top="&amp;t&amp;chr(13)&amp;"left="&amp;l,64,"得到控件的位置" <BR>end function <BR>--&gt; <BR>&lt;/script&gt; <BR><BR><BR>光标是停在文本框文字的最后 <BR><BR><BR>&lt;script language="javascript"&gt; <BR>function cc() <BR>{ <BR>var e = event.srcElement; <BR>var r =e.createTextRange(); <BR>r.moveStart('character',e.value.length); <BR>r.collapse(true); <BR>r.select(); <BR>} <BR>&lt;/script&gt; <BR>&lt;input type=text name=text1 value="123" onfocus="cc()"&gt; <BR><BR><BR>判断上一页的来源 <BR><BR><BR>asp: <BR>request.servervariables("HTTP_REFERER") <BR><BR>javascript: <BR>document.referrer <BR><BR><BR>最小化、最大化、关闭窗口 <BR><BR><BR>&lt;object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"&gt; <BR>&lt;param name="Command" value="Minimize"&gt;&lt;/object&gt; <BR>&lt;object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"&gt; <BR>&lt;param name="Command" value="Maximize"&gt;&lt;/object&gt; <BR>&lt;OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"&gt; <BR>&lt;PARAM NAME="Command" value="Close"&gt;&lt;/OBJECT&gt; <BR><BR>&lt;input type=button value=最小化 onclick=hh1.Click()&gt; <BR>&lt;input type=button value=最大化 onclick=hh2.Click()&gt; <BR>&lt;input type=button value=关闭 onclick=hh3.Click()&gt; <BR>本例适用于IE <BR><BR>记录并显示网页的最后修改时间 <BR><BR><BR>&lt;script language=JavaScript&gt; <BR>document.write("最后更新时间: " + document.lastModified + "") <BR>&lt;/script&gt; <BR><BR><BR>2秒后关闭当前页<BR><BR>&lt;script language="JavaScript"&gt; <BR>&lt;!-- <BR>setTimeout('window.close();',2000); <BR>--&gt; <BR>&lt;/script&gt; <BR><BR><BR>2秒后载入指定网页<BR><BR>&lt;head&gt; <BR>&lt;meta http-equiv="refresh" content="2;URL=http://你的网址"&gt; <BR>&lt;/head&gt; <BR><BR><BR>添加到收藏夹<BR><BR>&lt;Script Language="JavaScript"&gt; <BR>function bookmarkit() <BR>{ <BR>　window.external.addFavorite('<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>你的网址','你的网站名称') <BR>} <BR>　if (document.all)document.write('&lt;a href="#" onClick="bookmarkit()"&gt;加入收藏夹&lt;/a&gt;') <BR>&lt;/Script&gt; <BR><BR><BR>禁止鼠标右键的动作<BR><BR>&lt;Script Language = "JavaScript"&gt; <BR>function click() { if (event.button==2||event.button==3) <BR>{ <BR>　alert('禁止鼠标右键'); <BR>} <BR>document.onmousedown=click // --&gt; <BR>&lt;/Script&gt; <BR><BR><BR>或<BR><BR>&lt;script language="JavaScript"&gt; <BR>function click() { if (event.button==2) <BR>{alert('*^_^*'); } } document.onmousedown=click // --&gt; <BR>&lt;/script&gt; <BR><BR><BR>设置该页为首页<BR><BR>&lt;body bgcolor="#FFFFFF" text="#000000"&gt; <BR>&lt;a class="chlnk" style="cursor:hand" HREF onClick="this.style.behavior='url(#default#homepage)'; this.setHomePage('你的网站名称);"&gt;&lt;font color="000000" size="2" face="宋体"&gt;设为首页&lt;/font&gt;&lt;/a&gt; <BR>&lt;/body&gt; <BR><BR><BR>节日倒计时<BR><BR>&lt;Script Language="JavaScript"&gt; <BR>　　var timedate= new Date("October 1,2002"); <BR>　　var times="国庆节"; <BR>　　var now = new Date(); <BR>　　var date = timedate.getTime() - now.getTime(); <BR>　　var time = Math.floor(date / (1000 * 60 * 60 * 24)); <BR>　　if (time &gt;= 0) <BR>　　document.write("现在离"+times+"还有: "+time +"天")<BR>&lt;/Script&gt; <BR><BR><BR>单击按钮打印出当前页<BR><BR>&lt;Script Language="JavaScript"&gt; <BR>　　if (window.print) { <BR>　　document.write('&lt;form&gt;' <BR>　　+ '&lt;input type=button name=print value="打印本页" ' <BR>　　+ 'onClick="javascript:window.print()"&gt;&lt;/form&gt;'); <BR>　　} <BR>&lt;/Script&gt; <BR><BR><BR>单击按钮‘另存为’当前页<BR><BR>&lt;input type="button" name="Button" value="保存本页" onClick="document.all.button.ExecWB(4,1)"&gt; <BR>&lt;object id="button" width=0 height=0 classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"&gt; <BR>&lt;embed width="0" height="0"&gt;&lt;/embed&gt; <BR>&lt;/object&gt; <BR><BR><BR>显示系统当前日期<BR><BR>&lt;script language=JavaScript&gt; <BR>　　today=new Date(); <BR>　　function date(){ <BR>　　this.length=date.arguments.length <BR>　　for(var i=0;i&lt;this.length;i++) <BR>　　this[i+1]=date.arguments } <BR>　　var d=new date("星期日","星期一","星期二","星期三","星期四","星期五","星期六"); <BR>　　document.write( <BR>　　"&lt;font color=##000000 style='font-size:9pt;font-family: 宋?&gt; ", <BR>　　today.getYear(),"年",today.getMonth()+1,"月",today.getDate(),"日", <BR>　　d[today.getDay()+1],"&lt;/font&gt;" ); <BR>&lt;/script&gt; <BR><BR><BR>不同时间段显示不同问候语 &lt;Script Language="JavaScript"&gt; <BR>var text=""; day = new Date( ); time = day.getHours( ); <BR>　　if (( time&gt;=0) &amp;&amp; (time &lt; 7 )) <BR>　　　　text="夜猫子，要注意身体哦！ " <BR>　　if (( time &gt;= 7 ) &amp;&amp; (time &lt; 12)) <BR>　　　　text="今天的阳光真灿烂啊，你那个朋友呢？" <BR>　　if (( time &gt;= 12) &amp;&amp; (time &lt; 14)) <BR>　　　　text="午休时间。您要保持睡眠哦！" <BR>　　if (( time &gt;=14) &amp;&amp; (time &lt; 18)) <BR>　　　　text="祝您下午工作愉快！ " <BR>　　if ((time &gt;= 18) &amp;&amp; (time &lt;= 22)) <BR>　　　　text="您又来了，可别和MM聊太久哦！" <BR>　　if ((time &gt;= 22) &amp;&amp; (time &lt; 24)) <BR>　　　　text="您应该休息了！" <BR>　　document.write(text) <BR>&lt;/Script&gt;<BR>水中倒影效果 &lt;img id="reflect" src="你自己的图片文件名" width="175" height="59"&gt; <BR>　　&lt;script language="JavaScript"&gt; <BR>　　function f1() <BR>　　{ <BR>　　　　setInterval("mdiv.filters.wave.phase+=10",100); <BR>　　} <BR>　　if (document.all) <BR>　　{ <BR>　　　　document.write('&lt;img id=mdiv src="'+document.all.reflect.src+'" <BR>　　　　style="filter:wave(strength=3,freq=3,phase=0,lightstrength=30) blur() flipv()"&gt;') <BR>　　　　window.onload=f1 <BR>　　} <BR>&lt;/script&gt; <BR><BR>慢慢变大的窗口 &lt;Script Language="JavaScript"&gt; <BR>　　&lt;!-- <BR>　　var Windowsheight=100 <BR>　　var Windowswidth=100 <BR>　　var numx=5 <BR>　　function openwindow(thelocation){ <BR>　　temploc=thelocation&amp;, amp;, nbsp; <BR>　　if <BR>　　(!(window.resizeTo&amp;&amp;document.all)&amp;&amp;!(window.resizeTo&amp;&amp;document.getElementById)) <BR>　　{ <BR>　　　　window.open(thelocation) <BR>　　　　return <BR>　　} <BR>　　windowsize=window.open("","","scrollbars") <BR>　　windowsize.moveTo(0,0) <BR>　　windowsize.resizeTo(100,100) <BR>　　tenumxt() <BR>　　} <BR>　　function tenumxt(){ <BR>　　if (Windowsheight&gt;=screen.availHeight-3) <BR>　　　　numx=0 <BR>　　windowsize.resizeBy(5,numx) <BR>　　Windowsheight+=5 <BR>　　Windowswidth+=5 <BR>　　if (Windowswidth&gt;=screen.width-5) <BR>　　{ <BR>　　　　windowsize.location=temploc <BR>　　　　Windowsheight=100 <BR>　　　　Windowswidth=100 <BR>　　　　numx=5 <BR>　　　　return <BR>　　} <BR>　　setTimeout("tenumxt()",50) <BR>　　} <BR>　　//--&gt; <BR>&lt;/script&gt; <BR>&lt;a href="javascript:openwindow('<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>www.31u.net')"&gt;进入&lt;/a&gt; <BR><BR><BR>鼠标指向时弹出信息框 <BR>在&lt;body&gt;&lt;/body&gt;之间加上如下代码： &lt;a href onmouseover="alert('弹出信息！')"&gt;显示的链接文字&lt;/a&gt; <BR><BR><BR>随机变换背景图象（一个可以刷新心情的特效） <BR>在&lt;head&gt;&lt;/head&gt;之间加上如下代码： <BR>&lt;Script Language="JavaScript"&gt; <BR>　　image = new Array(4); //定义image为图片数量的数组 <BR>　　image [0] = 'tu0.gif' //背景图象的路径 <BR>　　image [1] = 'tu1.gif' <BR>　　image [2] = 'tu2.gif' <BR>　　image [3] = 'tu3.gif' <BR>　　image [4] = 'tu4.gif' <BR>　　number = Math.floor(Math.random() * image.length); <BR>　　document.write("&lt;BODY background="/+image[number]+"&gt;"); <BR>&lt;/Script&gt; <BR><BR>鼠标一碰就给颜色看的链接 在&lt;body&gt;&lt;/body&gt;之间加上如下代码： <BR>&lt;p onMouseMove="anniu()"&gt;你敢碰我，我就给点颜色你看！&lt;/p&gt; <BR>&lt;Script Language = "VBScript"&gt; <BR>　　sub anniu <BR>　　document.fgColor=int(256*256*256*rnd) <BR>　　end sub <BR>&lt;/Script&gt; <BR><BR>从天而降并有幻影效果的窗口 <BR><BR>　　&lt;head&gt; <BR>　　&lt;Script language="JavaScript"&gt; <BR>　　function move(x) { <BR>　　if(self.moveBy){ <BR>　　self.moveBy (0,-800); <BR>　　for(i = x; i &gt; 0; i--) <BR>　　{ <BR>　　self.moveBy(0,3); <BR>　　} <BR>　　for(j = 200; j &gt; 0; j--){ //如果你认为窗口抖动厉害，就200换成个位数 <BR>　　self.moveBy(0,j); <BR>　　self.moveBy(j,0); <BR>　　self.moveBy(0,-j); <BR>　　self.moveBy(-j,0); <BR>　　} <BR>　　} <BR>　　} <BR>　　&lt;/Scrip&gt; <BR>　　&lt;body bgColor=#ffffff onload=move(280)&gt; <BR>　　&lt;/body&gt; <BR>　　&lt;/head&gt; <BR><BR>表格的半透明显示效果 在&lt;head&gt;&lt;/head&gt;之间加上如下代码： <BR>&lt;style&gt; <BR>.alpha{filter: Alpha(Opacity=50)} //50表示50%的透明度 <BR>&lt;/style&gt; <BR><BR>在&lt;body&gt;&lt;/body&gt;之间加上如下代码： <BR>&lt;table border="1" width="100" height="62" class="alpha" bgcolor="#F2A664" &gt; <BR>　&lt;tr&gt; <BR>　　&lt;td width="100%" height="62"&gt; <BR>　　&lt;div align="center"&gt;很酷吧!&lt;/div&gt; <BR>　　&lt;/td&gt; <BR>　&lt;/tr&gt; <BR>&lt;/table&gt; <BR><BR><BR>锁定状态栏文字防止显示地址<BR>&lt;body onmouseover="self.status='文字';return true"&gt; <BR>禁止图片下载<BR>在&lt;body......&gt;这里的最后加入： <BR>oncontextmenu="return false" ondragstart="return false" onselectstart="return false" scroll="auto" <BR><BR>禁止缓存<BR>&lt;meta http-equiv="Expires" CONTENT="0"&gt; <BR>&lt;meta http-equiv="Cache-Control" CONTENT="no-cache"&gt; <BR>&lt;meta http-equiv="Pragma" CONTENT="no-cache"&gt; <BR>加在HEAD里 <BR><BR>使用包含页面<BR>加密所包含页面地址，使用工具 htmlguardian5.3.5<BR>目前功能最强的html代码加密软件,可以保护连接和html代码被盗。1.锁右键。2.禁鼠标圈选。3.不允许离线使用。4.密码保护。5.不显示状态栏url地址。6.全代码 或 局部代码保护。7.链接跟踪。8.禁止打印(IE5+)。9.压缩代码( 未加密前)。10.可加密*.html *.js *.asp *.vbs。11.两种不同加密算法。12.加密 frameset 结构。13.某些功能支持几个不同版本的浏览器。 <BR>　<BR><BR><BR>下载flash我的三种方法：<BR>--查看源文件，找出flash的绝对路径，复制，在flashget（或蚂蚁）中点任务<BR>，然后点新建下载任务即可。<BR>--在IE的临时文件夹Temporary Internet Files里把所有的东西都删掉，然后<BR><BR>刷新你想要下载flash的网页，即可得到你所要的flash<BR>--使用外部软件，推荐使用Flash Catcher,安装后只需在你所要下载的flash上右键，save即可。<BR><BR><BR>让IFRAME框架内的文档的背景透明<BR>&lt;iframe src="about:&lt;body style='background:transparent'&gt;" allowtransparency&gt;&lt;/iframe&gt; <BR><BR><BR>进入页面后立即自动刷新？<BR>&lt;meta http-equiv="refresh" content="120;url=http://www.31u.net"&gt;<BR><BR><BR>打开窗口即最大化<BR>&lt;script language="JavaScript"&gt; <BR>&lt;!-- Begin <BR>self.moveTo(0,0) <BR>self.resizeTo(screen.availWidth,screen.availHeight) <BR>// End --&gt; <BR>&lt;/script&gt; <BR><BR>能隐藏IFRAME的滚动条吗？我知道的三种方法:<BR>1. 设置iframe scrolling="no"<BR>2. 被包含页body应用overflow:hidden<BR>3. 被包含页的body标签加scroll="no"<BR><BR>加入背景音乐<BR><BR><BR>&lt;bgsound src="mid/windblue[1].mid" loop="-1"&gt; 只适用于IE <BR><BR>&lt;embed src="music.mid" autostart="true" loop="true" hidden="true"&gt; <BR>对Netscape ,IE 都适用 <BR><BR><BR>嵌入网页<BR>&lt;iframe name="tt" src="/01a.html" width="450" height="287" scrolling="Auto" frameborder="0"&gt;&lt;/iframe&gt; <BR><BR><BR>跳转<BR>&lt;meta http-equiv="refresh" content="3;URL=list.htm"&gt; <BR><BR><BR>滚动<BR>&lt;MARQUEE direction=up height=146 onmouseout=start() onmouseover=stop() scrollAmount=4&gt; <BR>&lt;/marquee&gt; <BR><BR><BR>细线分隔线<BR>&lt;hr noshade size=0 color=#C0C0C0&gt;<BR><BR><BR>过度方式<BR><BR><BR>&lt;meta http-equiv="Page-Exit" content="revealTrans(Duration=3,Transition=5)"&gt; <BR>Duration的值为网页动态过渡的时间，单位为秒。 <BR>Transition是过渡方式，它的值为0到23，分别对应24种过渡方式。如下表： <BR>0 盒状收缩 1 盒状放射 <BR>2 圆形收缩 3 圆形放射 <BR>4 由下往上 5 由上往下 <BR>6 从左至右 7 从右至左 <BR>8 垂直百叶窗 9 水平百叶窗 <BR>10 水平格状百叶窗 11垂直格状百叶窗 <BR>12 随意溶解 13从左右两端向中间展开 <BR>14从中间向左右两端展开 15从上下两端向中间展开 <BR>16从中间向上下两端展开 17 从右上角向左下角展开 <BR>18 从右下角向左上角展开 19 从左上角向右下角展开 <BR>20 从左下角向右上角展开 21 水平线状展开 <BR>22 垂直线状展开 23 随机产生一种过渡方式 <BR><BR><BR>如何控制横向和纵向滚动条的显隐？<BR><BR><BR>&lt;body style="overflow-y:hidden"&gt; 去掉x轴 <BR>&lt;body style="overflow-x:hidden"&gt; 去掉y轴 <BR>&lt;body scroll="no"&gt;不显 <BR><BR><BR>定义本网页关键字，可以在&lt;Head&gt;&lt;/Head&gt;中加入如下代码： &lt;meta name="Keywords" content="china,enterprise,business,net"&gt; 　　 <BR>Content 中所包含的就是关键字,你可以自行设置。 　　 <BR>这里有个技巧,你可以重复某一个单词,这样可以提高自己网站的排行位置,如：<BR><BR>&lt;meta name="Keywords" content="china,china,china,china"&gt; <BR><BR>IE5.0 的部分快捷键： <BR><BR><BR>A:打开查找功能：Ctrl+F <BR>关闭浏览器窗口：Ctrl+W <BR>打开地址栏下拉列表框：F4 <BR>刷 新：F5 <BR>将当前Web页保存到收藏夹列表：Ctrl+D <BR>打开当前 IE 窗口的一个拷贝：Ctrl+N <BR>停止下载当前网页：Esc <BR>光标迅速移动到网页的开头：Home <BR>光标迅速移动到网页的尾部：End <BR>打开新的地址键入窗口：Ctrl+O <BR>打开收藏夹：Ctrl+I <BR>打开历史记录文件夹：Ctrl+H <BR>打开浏览器设定的默认主页：Alt+HOME <BR><BR><BR>添加到收藏夹：<BR><BR><BR>&lt;a href="javascript:window.external.addFavorite('<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>链接','说明');"&gt;添加到收藏夹&lt;/a&gt; <BR><BR><BR>设为首页：<BR><BR><BR>&lt;a href=# onclick=this.style.behavior='url(#default#homepage)';this.setHomePage ('<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>链接');&gt;设为首页&lt;/a&gt; <BR><BR><BR>定制浏览器地址栏前的小图标：<BR>A:在网页的&lt;head&gt;&lt;/head&gt;间加入以下语句<BR><BR>&lt;link rel="shortcuticon" href="<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>…/icon.ico"&gt; <BR><BR><BR>即可。其中 icon.ico 为 16x16 的图标文件，<BR><BR>颜色不要超过 16 色。 <BR><BR>把滚动条放在浏览器窗口的左边<BR>A:在 &lt;body&gt; 中加 dir=RTL，即 &lt;body dir=RTL&gt;。<BR><BR>让背景图不滚动<BR>IE浏览器支持一个 Body 属性 bgproperties，它可以让背景不滚动: <BR><BR><BR>&lt;Body Background="图片文件" bgproperties="fixed"&gt; <BR><BR><BR>删除确认：<BR><BR><BR>&lt;input type="button" name="DEL" onclick="{if(confirm('确认删除么?')){location.href="/xxx.asp";}return false;}" value="ON" &gt; <BR><BR><BR>隐藏状态栏中的链接地址：<BR><BR><BR>&lt;script language="javascript"&gt; <BR>kstatus(); <BR>function kstatus(){ <BR>self.status="GBlog () "; <BR>setTimeout("kstatus()",0); <BR>} <BR>&lt;/script&gt; <BR>自定义指定区域的文字大小：<BR>&lt;div id=zoom&gt;sdrrrrrrrrrrrrrrrrrrrrrrrrrrrrr&lt;/div&gt; <BR>【&lt;A href="javascript:doZoom(16)"&gt;大&lt;/A&gt; &lt;A href="javascript:doZoom(14)"&gt;中&lt;/A&gt; &lt;A href="javascript:doZoom(12)"&gt;小&lt;/A&gt;】 <BR>&lt;SCRIPT language=JavaScript&gt; <BR>function doZoom(size){ <BR>document.getElementById('zoom').style.fontSize=size+'px' <BR>} <BR>&lt;/script&gt; <BR><BR>Input输入框文字效果：<BR><BR><BR>&lt;input type="text" value="123456" style="FONT-size:38px;color:red;font-family:arial black"&gt; <BR>通过层来实现渐淡淡出<BR>&lt;script language="JavaScript1.2"&gt; <BR>function makevisible(cur,which){ <BR>if (which==0) <BR>cur.filters.alpha.opacity=100 <BR>else <BR>cur.filters.alpha.opacity=50 <BR>} <BR>&lt;/script&gt; <BR>&lt;div style="width:200px;height:200px;filter:alpha(opacity=50);border:1px solid #000;background:#efefef" onMouseOver="makevisible(this,0)" onMouseOut="makevisible(this,1)"&gt; <BR>ywicc.com <BR>&lt;/div&gt; <BR><BR><BR>网页屏保<BR>&lt;script language="JavaScript"&gt; <BR>function screensave(){ <BR>test.value++; <BR>if(test.value==5){ <BR>test.style.display='none'; <BR>document.all[4].bgColor='black'; <BR>} <BR>} <BR>function screenopen(){ <BR>test.value=0; <BR>test.style.display=''; <BR>document.all[4].bgColor=''; <BR>} <BR>&lt;/script&gt; <BR>&lt;body onkeydown="screenopen()" onmousemove="screenopen()" onload="setInterval('screensave()',1000)"&gt; <BR>5 秒屏保&lt;input id="test"&gt; <BR><BR><BR>让标题动态<BR>&lt;script&gt; <BR>&lt;!-- <BR>var tx = new Array ( <BR>"◇:::::::网页制作学习园地:::::::◇欢迎您!◇", <BR>"◆欢迎大家光临网页制作学习园地网站!◆", <BR>"◆大量供应网页制作教材,资料,源代码,网页制作软件,相关插件光盘!◆", <BR>"◆最可怕的敌人，就是没有坚强的信念!◆", <BR>"◆应该让别人的生活因为有了你的生存而更加美好!◆" <BR>); <BR>var txcount=5; <BR>var i=1; <BR>var wo=0; <BR>var ud=1; <BR>function animatetitle() <BR>{ <BR>window.document.title=tx[wo].substr(0, i)+"_"; <BR>if (ud==0) i--; <BR>if (ud==1) i++; <BR>if (i==-1) {ud=1;i=0;wo++;wo=wo%txcount;} <BR>if (i==tx[wo].length+10) {ud=0;i=tx[wo].length;} <BR>// if (window.document.title.length &lt; 20 ) window.document.title=window.document.title+"-"; <BR>// if (window.document.title.length == 20 ) window.document.title=window.document.title+"]"; <BR>// if (window.document.title.length == 21 ) setTimeout("window.document.title='Animierte Seitentitel '; ",1000); <BR><BR>parent.window.document.title=tx[wo].substr(0, i)+"_"; <BR>setTimeout("animatetitle()",100); <BR>} <BR>animatetitle(); <BR>// --&gt;&lt;/script&gt;&lt;script language="JavaScript"&gt; <BR>&lt;!-- <BR>function MM_openBrWindow(theURL,winName,features) { //v2.0 <BR>window.open(theURL,winName,features); <BR>} <BR>//--&gt; <BR>&lt;/script&gt; <BR><BR><BR>隐去浏览器中当鼠标移到图片上跳出的工具栏<BR>&lt;img galleryimg="no"&gt; <BR><BR>或者<BR>&lt;head&gt; <BR>&lt;meta http-equiv="imagetoolbar" content="no"&gt; <BR>&lt;/head&gt; <BR><BR><BR>在form中只有input输入框的情况下...在这个input输入框中按enter进行提交表单<BR>&lt;form onsubmit="if(event.srcElement.name=='bb'){this.submit()}else{return false}"&gt; <BR>&lt;input name=a size=20&gt; <BR>&lt;input type=button name=bb onclick="submit();"&gt; <BR>&lt;/form&gt; <BR><BR>删除确认<BR>&lt;input type="button" value="删除" onclick="{if(confirm('确认删除么？')){location.href="/aa.asp";}return false;}"&gt; <BR>或<BR>&lt;a href="<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>www.31u.net/search.asp" onclick="{if(confirm('确定删除吗?')){return true;}return false;}"&gt;删除&lt;/a&gt; <BR>或<BR>&lt;a href="<A href="http:///" target=_blank><FONT color=#002c99>http://</FONT></A>www.31u.net/search.asp" onclick="return confirm('该删除操作将无法恢复！是否继续？')"&gt;删除&lt;/a&gt; <BR><BR>返回页面顶部：<BR>javascript:window.scroll(0,0) <BR><BR><BR>离开页面时弹出警告：<BR>&lt;BODY onbeforeunload="checkclose()"&gt;<BR><BR>&lt;SCRIPT&gt;<BR>function checkclose(){<BR>event.returnValue = "测试啊" //XXX可以改为任何文本信息也可以是空<BR>}<BR>&lt;/SCRIPT&gt;<BR><BR>&lt;a href="http://www.31u.net/search.asp"&gt;aa&lt;/a&gt; </DIV></SPAN></TD></TR>
<TR>
<TD colSpan=2>
<TABLE cellSpacing=0 cellPadding=0 width="95%" background=/skin/teach/bg_line.gif border=0>
<TBODY>
<TR>
<TD><IMG height=2 src="http://blog.chinaitlab.com/skin/bg_line.gif" width=6></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD align=right width="92%"><SPAN class=artfooter><BR></SPAN></TD></TR></TBODY></TABLE></P><img src ="http://www.blogjava.net/jelver/aggbug/35035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-03-13 14:50 <a href="http://www.blogjava.net/jelver/articles/35035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>采用简化原型法进行需求分析-转载并分析</title><link>http://www.blogjava.net/jelver/articles/33927.html</link><dc:creator>都市淘沙者</dc:creator><author>都市淘沙者</author><pubDate>Mon, 06 Mar 2006 13:13:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/33927.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/33927.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/33927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/33927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/33927.html</trackback:ping><description><![CDATA[<H2 class=diaryTitle>采用简化原型法进行需求分析-转载并分析- -</H2>
<P>&nbsp;</P>
<P>采用简化原型法进行需求分析 <BR><A href="http://www.chinaunix.net/">http://www.chinaunix.net</A> 作者:一无所有&nbsp; 发表于：2003-11-03 09:21:18 </P>
<P>1 前言 </P>
<P>　　需求分析阶段是管理信息系统（MIS）开发最重要的阶段。MIS开发的需求阶段首先是了解和澄清用户的需求，然后严格地定义被开发的软件系统的需求规格说明书[1]。常用的软件需求分析方法有面向数据流的结构化分析方法、面向数据结构的Jackson方法、面向对象的方法和原型法等。原型法由于改变了系统的分析、设计和实现三个顺序阶段的观点[2]，改变了传统的自顶向下的开发模式，降低了软件需求的风险，因此得到了广泛的应用，特别是在致力于某一领域MIS开发的软件公司，如致力于电力MIS开发的公司。但作者在长期的MIS需求分析过程中，发现原型法有以下缺陷：　　 </P>
<P>　　1）原型的设计和修改工作量大，增加了系统的开发成本； </P>
<P>　　2）由于用户不关心或不理解原型的概念和实现，而且存在较大期望，使得与实际系统差别较大的原型增加了需求分析人员与用户的交流难度；无论是水平原型，还是垂直原型都不能反映实际系统的全貌； </P>
<P>　　3）软件需求主要包括：功能需求、界面需求、性能需求、环境需求、可靠性需求、安全保密需求、资源使用需求、软件成本消耗与开发进度需求和目标需求[3]。原型法中的原型难以表达软件的后七项需求； </P>
<P>　　4）原型法强调用户和开发人员不断对原型进行不断修改和补充，直到用户感到满意为止。在时间紧和任务重的大型MIS项目中，这种情况实际难以保证，特别是在用户单位和开发单位距离较远时。 </P>
<P>　　本文结合管理信息系统项目实施的实践，提出一种新的需求分析方法-简化原型法。这种方法根据数据库应用的特点，将需求分析分为两个阶段，并简化了作为需求分析工具的系统原型。 </P>
<P>2 简化原型法需求分析的第一个阶段 </P>
<P>　　管理信息系统属于数据库应用。数据库应用需求分析应该围绕数据，而不是功能展开，因此应该首先解决"有什么"，然后再明确"做什么"[4]。第一个阶段就是要解决"有什么"，即由项目经理与用户进行协商，确定系统的技术协议，因此可以称为技术协议阶段。技术协议需要开发方的项目经理与用户单位的技术主管签字并盖章，并以合同附件的形式存在。技术协议的主要内容有：系统的边界、系统处理的业务、与其它系统的接口、工程的进度控制、培训安排和技术服务承诺。 </P>
<P>2.1 系统的边界 </P>
<P>　　系统的边界规定系统覆盖的作业范围，主要有地理边界（规定系统运行的部门、分支单位等）、操作员范围（规定操作系统的所有操作员身份、分布和大致权限）和业务范围（规定系统处理的业务，对于不处理的边沿业务特别明确指出）。 </P>
<P>2.2 系统处理的业务 </P>
<P>　　系统处理的业务涵盖系统处理的所有业务，包括各种业务的描述、数据来源、实现要求。但是业务规定不要求过细，可以对应实际系统中的一个模块。如：电力MIS中输电设施管理子系统中的线路设备管理，不详细描述线路设备管理中的所有功能。 </P>
<P>2.3 与其它系统的接口 </P>
<P>　　与其它系统的接口明确规定接口的系统、功能和实施单位。在接口的实施单位中明确是由开发方完成，还是由开发方协助第三方完成。 </P>
<P>2.4 工程的进度控制 </P>
<P>　　工程的进度控制规定工程的开始、结束日期和具体工程项目的名称、完成时间、地点、完成标志及责任分工。具体项目一般包括：采购设备到达现场、采购设备安装调试、完成网络布线、开发准备阶段、业务需求调查、系统分析和设计、软件编制、现场调试、数据准备及录入、功能确认、试运行和系统验收。责任分工规定双方对于具体项目的工作内容和配合方式。在配合方式中规定人员组织方式、人员素质要求、提供的设备和场所。完成标志规定具体项目完成提供的文件名称和要求，如：网络布线验收报告和硬件设备验收报告等。&nbsp; </P>
<P>2.5 培训安排 </P>
<P>　　训包括操作员和系统维护人员的培训。培训安排包括每种培训的人员数量、培训内容、培训时间、地点、组织方式和教材，并规定教员和学员的素质要求，及培训后学员达到的水平。&nbsp; </P>
<P>3 简化原型法需求分析的第二个阶段 </P>
<P>　　如果说第一个阶段解决"有什么"的问题，那么第二个阶段解决"做什么"的问题。主要工作有需求调查准备、到用户单位进行需求调查分析和进行需求评审。 </P>
<P>3.1 需求调查准备 </P>
<P>　　需求调查准备工作，在系统的技术协议签订后，严格依照技术协议进行，主要有向用户单位发放业务调查表、建立需求分析文档原型和建立系统简化原型。业务调查表在系统的技术协议签订后，立即通过传真发送到用户单位，要求用户单位在需求调查人员到达现场之前完成。业务调查表内容包括：具体业务的名称、上级业务、下级业务、发生条件、处理的数据和详细流程（处理岗位、处理方式和审核细节等）。需求分析文档原型是根据技术协议编写的需求分析说明书原型，它的格式与标准的需求分析说明书相同。其中的状态迁移图和各种表证单书等不明确的内容，采用相似系统的或由系统分析人员根据技术协议和以往经验设计。&nbsp; </P>
<P>　　系统的简化模型根据技术协议的要求，仿照相似系统设计。简化模型采用可视化的数据库编程语言设计，一般采用数据库应用开发人员熟悉的PowerBuilder(PB)或Delphi。简化模型的主要设计要求有：1）充分考虑系统的设计与实现，不得与实际系统脱节；2）尽量仿真实际系统的操作界面，与实际系统的操作过程完全相同；3）可以单机安装运行，不与实际数据库连接；4）演示数据的存储可以通过文本文件、单机的数据库或PB外部数据源的数据窗口；5）对于界面中容易误解或难以理解的操作，在功能帮助按钮中给出说明；6）界面中难以实现或工作量很大的功能，以标注方式详细说明；7）运行稳定，并比实际系统对硬件要求低。 </P>
<P>3.2 需求调查分析 </P>
<P>　　需求调查分析在确认需求调查准备的三项工作完成后，由开发单位的系统分析人员到用户单位进行。系统分析人员与用户单位安排的业务主管共同讨论业务调查表和系统简化原型，并不断修改完善系统简化原型和文档原型，最终形成共识，并要求业务主管在需求分析说明书上签字。最终系统简化原型和源代码留在用户现场，便于系统的操作员进一步理解分析，直到最终掌握；而且有利于提出进一步的改进意见。改进意见可以随时通过邮件或传真直接发到开发单位，或由用户单位的系统维护人员修改简化原型后，随时发到开发单位，从而便于开发人员及时修改系统的设计和编码。 </P>
<P>3.3 进行需求评审 </P>
<P>　　需求评审一般由用户单位组织，评审团成员由同行专家、系统分析、设计和测试人员组成。评审的依据不仅有需求分析说明书，还有系统简化原型；同时在评审过程中，系统简化原型不断进行优化。评审的目标是要求需求分析说明书具有正确性、可行性、必要性、具有优先级属性、可验证性和无二义性[5]。需求评审报告作为对需求分析的补充和修正，由双方负责人签字，以需求分析说明书附件的形式存在，同样指导下一步的系统设计工作。 </P>
<P>4 几点说明 </P>
<P>1、此方法适合各种MIS工程的需求分析，特别适合致力于某一领域MIS开发的软件公司。采用此方法，开发同类项目越多，需求分析工作的效率越高。 </P>
<P>2、在需求分析过程中，由于需要设计系统简化原型和文档原型，并充分考虑到系统的设计与实现，因此与其它需求分析方法向比，提高了对需求分析人员的要求。在实际工作中，一般由资深的软件分析和设计人员进行。&nbsp; </P>
<P>3、此方法不仅适合MIS软件工程，同样适合其它大型软件工程。 </P>
<P>4、由于需求分析工作本身的难度和重要性，此方法同样要求用户单位和需求分析人员对需求分析所有工作内容，引起足够重视；科学安排需求分析工作步骤，某些步骤可以同时进行；所有工作步骤不得应负或疏忽。 </P>
<P>5 结束语 <BR>　　目前简化原型法已经在多个电力MIS工程中应用，大大提高了需求分析的工作效率。实践证明，简化原型法具有以下特点：1）简化的系统原型开发工作量大大降低，修改和补充方便；2）简化原型大大缩短了需求分析人员与业务主管之间的距离，便于交流；并大大加强了需求分析人员与业务主管对系统的认识，有利于发现和解决问题；3）简化原型的设计提前考虑了系统的设计与实现，大大降低了软件工程的风险；4）简化原型增加了系统操作员对实际系统的认识，大大简化了工程实施后系统的操作培训；5）简化原型可以直接指导工程的设计和编码，便于系统开发的组织。这种方法也可以用于其它软件工程，对于其它需求分析方法的改革也具有指导意义.</P><img src ="http://www.blogjava.net/jelver/aggbug/33927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">都市淘沙者</a> 2006-03-06 21:13 <a href="http://www.blogjava.net/jelver/articles/33927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>