<?xml version="1.0" encoding="GBK" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
  	  <title><![CDATA[没有博客]]></title>
	  <link>http://zjuoliver.blog.163.com</link>
	  <description><![CDATA[没有博客就是有博客。。简单的人想的简单的名字 ]]></description>
	  <language>zh-CN</language>
	  <pubDate>Sun, 10 Aug 2008 13:14:25 +0800</pubDate>
	  <lastBuildDate>Sun, 10 Aug 2008 13:14:25 +0800</lastBuildDate>
	  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
	  <generator><![CDATA[NetEase Space]]></generator>
	  <managingEditor><![CDATA[zjuoliver]]></managingEditor>
	  <webMaster><![CDATA[Shawn]]></webMaster>
		  <ttl>120</ttl>
	  <image>
	  	<title><![CDATA[没有博客]]></title>
	  	<url>http://ava.blog.163.com/photo/qKs0CwA4rKwte-yIFAyMIQ==/169729410956697601.jpg</url>
	  	<link>http://zjuoliver.blog.163.com</link>
	  </image>
  <item>
  	<title><![CDATA[元素“UpdatePanel”不是已知元素。原因可能是网站中存在编译错误。]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200871011411714</link>
    <description><![CDATA[<div>在web.config中把 AJAX的标签改成别的就行了.<BR>如:<BR>&lt;add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Ver.....<BR>改成<BR>&lt;add tagPrefix="ajax" namespace="System.Web.UI" assembly="System.Web.Extensions, Ver.....</div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200871011411714</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200871011411714</guid>
    <pubDate>Sun, 10 Aug 2008 13:14:11 +0800</pubDate>
    <dcterms:modified>2008-08-10T13:14:11+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[在ASP.NET程序中集成更好的下载体验 ]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200862010513113</link>
    <description><![CDATA[<div><P>原帖地址：</P>
<P><A href="http://www.cnblogs.com/evanescenceX/archive/2008/06/16/1222883.html">http://www.cnblogs.com/evanescenceX/archive/2008/06/16/1222883.html</A></P>
<P>最近在写一个Web版本的文件管理器，正好又有朋友问起web页面上面可以让图片也变成下载模式的那种链接方式在ASP.NET里面怎么实现，我给他写了一个大概，觉得也应该当作笔记贴出来，帮他写的时候，突然发现很多问题自己也不是明白，所以逐一查找了一番，贴出来和大家分享！</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp; 应用场景，很多时候都有盗链等各种各样的原因，用ASP.NET呢，最基本的一个问题，我的所有数据文件都保存在App_Data，这个文件夹和配置文件Web.Config一样，直接是无法访问其中内容的，所以如果里面上传了文件，无论是图片，还是压缩包，想下载就要通过某个点Response.WriteFile出去，不过在讨论的时候又发现了一些新的内容，如下：</P>
<P>首先，是下载的基础，Http Header 的做两个设置：</P>
<OL>
<LI>Content-Type ： (这个~很无语的东西，每次都记不住，现查！<A href="http://en.wikipedia.org/wiki/Internet_media_type" target=_blank><FONT color=#1d58d1>Wiki</FONT></A>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG>application/octet-stream</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 万金油型，什么文件都适合！<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG>application/x-zip-compressed</STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 专门针对Zip文件的，但是在某些情况下有奇效，这个后面讲 
</LI><LI>Content-Disposition : 此属性设置内容输出的方式和属性，不大会使，常用就两种操作方式，一个是<STRONG>inline</STRONG>，另一个就是<STRONG>attachment</STRONG>；在输出类型之后可以跟着一些参数，在操作下载的时候如果我们不希望我们输出的文件编程abc.aspx的名字，就要设置filename的参数项，其他的参数项有：creation-date,modification-date,read-date,size。这些内容在后面讲高级的下载输出时会用得到哦。 </LI></OL>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只要对上述的两个设置项进行设置以后就可以正常输出问题了，还需要服务器段的代码，以下我列出了三个实现，第一个是最简单的原型，然后再它的基础上有一个备选，最后一个是一个来自MSDN的高级解决方案，没研究明白到底是否该用~</P>
<P><SPAN style="FONT-SIZE: 16px"><STRONG>最简单的实现：</STRONG></SPAN><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新建一个WebForm页面，然后在Page_load里面添加内容：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
</P><DIV style="BORDER-RIGHT: #ccc 1px solid; BORDER-TOP: #ccc 1px solid; BORDER-LEFT: #ccc 1px solid; BORDER-BOTTOM: #ccc 1px solid; BACKGROUND-COLOR: #ffc"><PRE ><SPAN style="COLOR: blue">protected void </SPAN>Page_Load(<SPAN style="COLOR: blue">object </SPAN>sender, <SPAN style="COLOR: #2b91af">EventArgs </SPAN>e)
{
<SPAN style="COLOR: blue">if </SPAN>(<SPAN style="COLOR: blue">null </SPAN>!= Request.QueryString[<SPAN style="COLOR: #a31515">"key"</SPAN>])
{
<SPAN style="COLOR: blue">string </SPAN>path = Request.PhysicalApplicationPath + <SPAN style="COLOR: #a31515">@"App_Data\" <BR>
</SPAN>+ Request.QueryString[<SPAN style="COLOR: #a31515">"key"</SPAN>].Replace(<SPAN style="COLOR: #a31515">'/'</SPAN>, <SPAN style="COLOR: #2b91af">Path</SPAN>.DirectorySeparatorChar);
<SPAN style="COLOR: blue">if </SPAN>(<SPAN style="COLOR: #2b91af">File</SPAN>.Exists(path))
{
<SPAN style="COLOR: #2b91af">FileInfo </SPAN>fi = <SPAN style="COLOR: blue">new </SPAN><SPAN style="COLOR: #2b91af">FileInfo</SPAN>(path);
Response.Clear();
Response.ContentType = <SPAN style="COLOR: #a31515">"application/octet-stream"</SPAN>;
<SPAN style="COLOR: green">// <SPAN style="COLOR: red">注意!</SPAN>这个地方一定要用AppendHeader。MSDN上很多地方指导使用
// Response.Headers.Add 或 Response.AddHeader
// 但是在MSDN中明确写出，这些都是为了兼容ASP，在.NET 3.5要求使用下面这种方式。
// 如果使用了上述两种方式可能会产生“此操作要求使用 IIS 集成管线模式。 ”的异常。</SPAN>
Response.<SPAN style="COLOR: red">AppendHeader</SPAN>(<SPAN style="COLOR: #a31515">"Content-Disposition"</SPAN>, <SPAN style="COLOR: blue">string</SPAN>.Format<BR>
(<SPAN style="COLOR: #a31515">"attachment;filename=\"{0}\""</SPAN>,<SPAN style="COLOR: #2b91af">HttpUtility<BR>
</SPAN>                                      .UrlEncode(fi.Name, System.Text.<SPAN style="COLOR: #2b91af">Encoding</SPAN>.UTF8)));
Response.<SPAN style="COLOR: red">AppendHeader</SPAN>(<SPAN style="COLOR: #a31515">"Content-Length"</SPAN>, fi.Length.ToString());
Response.WriteFile(fi.FullName);
}
<SPAN style="COLOR: blue">else
</SPAN>Response.Write(<SPAN style="COLOR: blue">string</SPAN>.Format(<SPAN style="COLOR: #a31515">"access is error.{0} is no exist."</SPAN>, path));
}
<SPAN style="COLOR: blue">else
</SPAN>{
Response.Write(<SPAN style="COLOR: #a31515">"i need key!"</SPAN>);
}
}</PRE></DIV>代码如上所示很简单，但是注释部分，我搞了小半个小时~感觉最近手艺有点潮。 <BR>上面对代码访问<STRONG>http://localhost:60534/WebForm1.aspx?key=[(目录)/](文件名)<BR></STRONG>就可以访问的到了，这里面的实例都是通过Asp.NET WebForm来完成的，我在后面会附一个由IHttpHandler实现的代码实例，这样结合URL Rewriter可以做出来很好的访问方式。<BR>
<P><SPAN style="FONT-SIZE: 16px"><STRONG>升级版本:</STRONG></SPAN></P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.WriteFile使用起来很方便，但是当网站为浏览者提供大块头文件的下载服务时就会发现WriterFile简直就是恶梦，它会非常占用资源（<SPAN style="COLOR: red">以下是本人猜测，如果有不对的地方，请指正！</SPAN>） ，当你的快餐店来了一个胃口很大的客人，要了一百包薯条准备整个上午都在店里面看表格，恰好碰上一个死心眼的大厨，他总觉得自己应该在最快的时候内把所有的东西都做好，然后把它们完整的呈现在顾客的面前，结果呢！可想而知，那个顾客因为饥饿而晕倒在了自己的座位上！这就是我们今天要讲的内容，你的Server也许只有2G的内容，当然IIS的限制也正好在这个位置，但是如果同时有人发起了两个以上大文件的请求的时候，你的内存就会忙于装填那些将要发包出去的字节码，而这个动作可能会和其他千万个Action一起哄抢本来就不多的资源，有没有什么办法可以解决呢？我们来看看下面的方案（声明这个方案也不是我想出来的，出自MSDN Magazine，就是忘记哪一期了！）：<BR></P>
<DIV style="BORDER-RIGHT: #ccc 1px solid; BORDER-TOP: #ccc 1px solid; BORDER-LEFT: #ccc 1px solid; BORDER-BOTTOM: #ccc 1px solid; BACKGROUND-COLOR: #ffc"><PRE ><SPAN style="COLOR: blue">                    int </SPAN>chunkSize = 1000;
<SPAN style="COLOR: blue">byte</SPAN>[] buffer = <SPAN style="COLOR: blue">new byte</SPAN>[chunkSize];
<SPAN style="COLOR: blue">using </SPAN>(<SPAN style="COLOR: #2b91af">FileStream </SPAN>fs = fi.Open(<SPAN style="COLOR: #2b91af">FileMode</SPAN>.Open))
{
<SPAN style="COLOR: blue">while </SPAN>(fs.Position &gt;= 0 &amp;&amp; Response.IsClientConnected)
{
<SPAN style="COLOR: blue">int </SPAN>tmp = fs.Read(buffer, 0, chunkSize);
Response.OutputStream.Write(buffer, 0, tmp);
Response.Flush();
}
}</PRE><A href="http://11011.net/software/vspaste"></A></DIV>
<P>代码很简单，就是用上面的代码替换掉Response.WriteFile方法，这样在内存中建立一个buffer的缓冲区（如果我的想法没有错的话，原理先放在一边，事实上这些代码确实起作用了！），然后去轮循字节信息，这样处理较第一种方式快很多输出1G的内容很快，但是没有进行具体测试，不知道会不会给CPU或是其他方面带来新的负载。而Response.IsClientConnected可以判断连接状态是否激活，就好比上面那个顾客只吃了50包，就撑倒了，那我们就需要把手头的事情放下，帮忙打个120。<BR>下面的压缩包是一个IHttpHandler实现的App_Data目录内容浏览和文件下载的示例，还有很多缺陷，比如说没有针对权限作出甄别监测，当然需要只是简单的管理权限，那就在&lt;location&gt;节点里面配置一下也好，Web.config的配置代码如下：<BR></P><PRE ><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: #a31515">httpHandlers</SPAN><SPAN style="COLOR: blue">&gt;
</SPAN><SPAN style="COLOR: blue">    &lt;</SPAN><SPAN style="COLOR: #a31515">add </SPAN><SPAN style="COLOR: red">verb</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">GET</SPAN>" <SPAN style="COLOR: red">path</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">adbrowser.o</SPAN>" <SPAN style="COLOR: red">type</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">I.HttpHandler.AppDataBrowser,I.Controls</SPAN>" <SPAN style="COLOR: blue">/&gt;
&lt;</SPAN><SPAN style="COLOR: #a31515">add </SPAN><SPAN style="COLOR: red">verb</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">*</SPAN>" <SPAN style="COLOR: red">path</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">download.o</SPAN>" <SPAN style="COLOR: red">type</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">I.HttpHandler.Download,I.Controls</SPAN>" <SPAN style="COLOR: blue">/&gt;
&lt;/</SPAN><SPAN style="COLOR: #a31515">httpHandlers</SPAN><SPAN style="COLOR: blue">&gt;
</SPAN></PRE><A href="http://11011.net/software/vspaste"></A>
<P><A title=I.Controls.rar href="http://www.dotags.com/files/I.Controls.rar"><STRONG><FONT color=#1d58d1>点击下载I.Controls.rar</FONT></STRONG></A> 
</P><P><SPAN style="FONT-SIZE: 16px"><STRONG>备选版本：</STRONG></SPAN></P>
<P>所谓高级版，其实又算是一个微软的私有定义了，使用<A href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://System.Web:2.0.0.0:b03f5f7f11d50a3a/System.Web.HttpResponse/TransmitFile(String,Int64,Int64)"><STRONG><FONT color=#1d58d1>TransmitFile</FONT></STRONG></A>可以分段输出，大家都知道IE支持断点续传的，但是有时候当我们下载一半中断之后，我们再去请求的时候，突然IE的普通下载就变成续传型了，很神奇，能碰到机会和出去逛街捡了一万块钱的几率相当。传说中在IE请求的时候会传入时会附加一个Header，叫做Range用来框定目前下载文件的长度，和已下载的字节位置，然后结合creation-date,modification-date去判断是否可以续连上一次下载的内容接着下载，但是这个又有一个新的麻烦的点，首先我用Reflector拆开TransmitFile看了一下，与WriteFile一样的实现机制，依然会有资源占有的问题，然后就是只针对IE，用Fiddler抓了一上午都没有发现FF或Opera之流，但是没有对迅雷或者是快车进行监测，不知道这个会不会再下载工具中有什么实际用途，最好的解决方案就是把range信息自己摘出来解析，然后自己去附加日期信息，用第二种方式缓冲输出。设想是这样的，因为我对HTTP请求不是很了解，请了解的站出来，指点一下。这个版本没有写，就是思考而已，有朋友感兴趣可以实现以下，记得告诉我什么感觉~</P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200862010513113</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200862010513113</guid>
    <pubDate>Sun, 20 Jul 2008 10:51:31 +0800</pubDate>
    <dcterms:modified>2008-07-20T10:51:31+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Bug分析之画蛇添足的htmlEncode]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/510192008620104357474</link>
    <description><![CDATA[<div><P>在html中，有些字符是用于做特殊标记的，比如“＜”。当需要在界面上显示这些字符时，就需要用另外一种方法来表示，比如“＜”要表示为“&lt; ”。只要知道了html中各个符号替代字符串，写一个这样的函数算不上什么难事，可是有人却偏偏画蛇添足，并把添了足的代码放到了网上，结果使很多网站出错。<BR><BR>这段代码被放在一个名为《一些非常有用的Java常用方法》的帖子中。这个帖子被广泛转载，可以在很多技术网站找到它。不过因为很多网站自身可能也使用了帖子中的代码，所以这些网站都无法把这个帖子正确地表现出来。在我找了很久之后，终于找到了这帖子的本来面目。我现在把这帖子的原始内容贴出来，再把那些出错了的网站的中，该帖子的内贴出来，做个对比。希望CSDN没使用这个画蛇添足的htmlEncode，否则就对比出不来原始内容了。<BR><BR>原帖中的htmlEncode函数如下（代码1，Java语言，下同）：<BR><BR>String htmlEncode(String txt){ txt = replace(txt,"&amp;","&amp; "); txt = replace(txt,"&amp; amp; ","&amp; "); txt = replace(txt,"&amp; quot; ","" "); txt = replace(txt,"\"","" "); txt = replace(txt,"&amp; lt; ","&lt; "); txt = replace(txt,"＜","&lt; "); txt = replace(txt,"&amp; gt; ","&gt; "); txt = replace(txt,"＞","&gt; "); txt = replace(txt,"&amp; nbsp; ","&nbsp; "); txt = replace(txt," ","&nbsp; "); return txt; }<BR><BR>使用Google搜到的大多网站上的帖子中，该函数的内容如下（代码2）：<BR><BR>String htmlEncode(String txt){ txt = replace(txt,"&amp;","&amp;"); txt = replace(txt,"&amp; ","&amp;"); txt = replace(txt,"" ","\""); txt = replace(txt,"\"","""); txt = replace(txt,"&lt; ","＜"); txt = replace(txt,"＜","＜"); txt = replace(txt,"&gt; ","＞"); txt = replace(txt,"＞","＞"); txt = replace(txt,"&nbsp; "," "); txt = replace(txt," "," "); return txt; }<BR><BR>在这两段代码中replace是自定义的字符串内替换函数，这个我们先不管它。且看第二段代码中，有很多第2个参数和第3个参数相同的replace调用，不觉得很奇怪么？<BR><BR>在读过了很多这样奇怪代码的帖子之后，终于在一个网站上找到了正确的原始帖子，看到了这个htmlEncode函数的真面目，也就是代码1中的内容。<BR><BR>其实看代码1也有奇怪之处。按一般的想法，只要把“&amp; ＜ ＞ \ ”等这几个字符逐一替换成相应的替代字符串就可以了，怎么会有如txt = replace(txt,"&amp; amp; ","&amp; "); 这样的语句呢？<BR><BR>后来一想，我明白了，作者是想让编码过的字符串不被重复编码。可能作者在程序的很多地方对字符串进行htmlEncode编码操作，他希望第一次编码后，其它的编码操作不再起作用，这样他只进行一次解码就可以还原原来的内容。<BR><BR>比如对字符串中的“&amp;”，在进行第一次编码后，它将变为“&amp; ”。在第二次编码时，在对“&amp;”进行替换后，将把“&amp; ”中的“&amp;”再次换成“&amp; ”，于是得到“&amp; amp; ”。作者为了不重复编码，就在txt = replace(txt,"&amp;","&amp; "); 语句之后，又加了一句txt = replace(txt,"&amp; amp; ","&amp; "); 把内容再替换回来。<BR><BR>同理，后面的txt = replace(txt,"&amp; quot; ","" "); 等类似语句也是为了达到这个目的加上去的。<BR><BR>作者写完这个程序之后一定很得意：看我这个程序多好，不会重复编码，调用100次htmlEncode也没关系，总能得到同一个结果！<BR><BR>可惜，这个结果并非总是正确的！试想，如果我想在网页上输出字符串"&amp; "，正如要显示作者的这个帖子所需要的那样，在内容中直接显示"&amp; "，问题来了：我对字符串"&amp; "调用htmlEncode之后，得到的还是"&amp; "，我把"&amp; "放到html中时，页面上只会显示一个”&amp;”，而不是"&amp; "。对于其它内容也一样，“&lt; ”、“&amp;lg; ”、“&gt; ”等这样的字符串都无法显示正确显示。<BR><BR>呵呵，这也正解释了为什么这么多网站会把作者的代码显示成代码２所示那样，因为他们都用了作者的程序。就拿作者帖子中的代码的第一句为例：<BR><BR>原文为：txt = replace(txt,"&amp;","&amp; "); <BR><BR>使用作者的算法对这段内容进行htmlEncode，得到：<BR><BR>txt = replace(txt, " &amp; " , " &amp; " ); <BR><BR>前一个“&amp;”被替换为“&amp; ”，而第二个参数&amp; 不变。把这段代码放在html中送到浏览器，正好显示为：<BR><BR>txt = replace(txt,"&amp;","&amp;"); <BR><BR>代码中其它的那些第２、３参数相同的replace调用也都是因为这个原因。 <BR><BR>一句话，作者想优化html编码的功能，结果画蛇添足。 <BR><BR>把代码改成如下的形式，去掉那些“足”，就可以正确编码了： <BR><BR>String htmlEncode(String txt){ txt = replace(txt,"&amp;","&amp; "); txt = replace(txt,"\"","" "); txt = replace(txt,"＜","&lt; "); <BR><BR>txt = replace(txt,"＞","&gt; "); <BR><BR>txt = replace(txt," ","&nbsp; "); return txt; } <BR><BR>从编程的角度看，这只是个画蛇添足的问题。如果换个角度，还有一些有意思的事情： <BR><BR>一、很多网站都使用了这段代码，并因此而无法正确显示作者的帖子，可见网络上错误信息的危害，并提醒大家在使用网络上的代码时，一定加倍小心。 <BR><BR>二、这段代码自己的错误导致了网站无法正确显示这段代码本身，这也限制了这段代码的使用。这算是网络自然法则么：正确的事物得以发展，不正确的自取灭亡？</P>
<P>&nbsp;</P>
<P>原帖地址：（加入网易本身也用了这段代码，可能也会显示不正确，可参看原帖）</P>
<P><A href="http://webdev.csdn.net/page/c60fe8ed-3a4a-4254-96b9-c1c9be7feb3a">http://webdev.csdn.net/page/c60fe8ed-3a4a-4254-96b9-c1c9be7feb3a</A></P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/510192008620104357474</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/510192008620104357474</guid>
    <pubDate>Sun, 20 Jul 2008 10:43:57 +0800</pubDate>
    <dcterms:modified>2008-07-20T10:43:57+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[NHibernate 网址]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/510192008617102338655</link>
    <description><![CDATA[<div><P><A href="http://www.cnblogs.com/guushuuse/tag/NHibernate/">http://www.cnblogs.com/guushuuse/tag/NHibernate/</A></P>
<P>&nbsp;<A href="http://www.cnblogs.com/renrenqq/archive/2006/08/09/471788.html">http://www.cnblogs.com/renrenqq/archive/2006/08/09/471788.html</A></P>
<P><A href="http://devlicio.us/blogs/billy_mccafferty/">http://devlicio.us/blogs/billy_mccafferty/</A></P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/510192008617102338655</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/510192008617102338655</guid>
    <pubDate>Thu, 17 Jul 2008 10:23:38 +0800</pubDate>
    <dcterms:modified>2008-07-17T10:31:06+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[微软发布3款SQL Injection攻击检测工具]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/510192008618371758</link>
    <description><![CDATA[<div><H3>&nbsp;</H3>
<DIV >
<DIV style="WIDTH: 99%">随着 SQL INJECTION 攻击的明显增多，微软近日发布了三个免费工具，帮助网站管理员和检测存在的风险并对可能的攻击进行拦截。<BR><B>Scrawlr </B><BR>下载地址：<A href="https://download.spidynamics.com/Products/scrawlr/" target=_blank>https://download.spidynamics.com/Products/scrawlr/</A> 这个微软和 HP合作开发的工具，会在网站中爬行，对所有网页的查询字符串进行分析并发现其中的 SQL INJECTION 风险。Scrawlr 使用了部分 HP WebInspect&nbsp; 相同的技术，但只检测 SQL INJECTION 风险。Scrawlr 从一个起始 URL 入口，爬遍整个网站，并对站点中所有网页进行分析以找到可能存在的漏洞。 <BR><BR><B>Microsoft Source Code Analyzer for SQL Injection</B> <BR>下载地址：<A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=58A7C46E-A599-4FCB-9AB4-A4334146B6BA&amp;displaylang=en" target=_blank>http://www.microsoft.com/downloads/details.aspx?FamilyId=58A7C46E-A599-4FCB-9AB4-A4334146B6BA&amp;displaylang=en</A> 这款被称作 MSCASI 的工具可以检测 ASP 代码并发现其中的 SQL INJECTION 漏洞（ASP 代码以 SQL INJECTION 漏洞著称），你需要向 MSCASI 提供原始代码，MSCASI 会帮你找到存在风险的代码位置。 <BR><BR><B>URLScan 3.0</B> <BR>下载地址： <A href="http://www.iis.net/downloads/default.aspx?tabid=34&amp;g=6&amp;i=1697" target=_blank>http://www.iis.net/downloads/default.aspx?tabid=34&amp;g=6&amp;i=1697</A> 该工具会让 IIS 限制某些类型的 HTTP 请求，通过对特定 HTTP 请求进行限制，可以防止某些有害的请求在服务器端执行。UrlScan 通过一系列关键词发现恶意请求，并阻止恶意请求的执行</DIV></DIV></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/510192008618371758</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/510192008618371758</guid>
    <pubDate>Tue, 1 Jul 2008 20:37:01 +0800</pubDate>
    <dcterms:modified>2008-07-01T20:37:01+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[毕业自曝]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/5101920086103016419</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">在学校一直懒得整理照片，没有曝成，今天刚回家，就在这里曝一下吧。</P>
<P style="TEXT-INDENT: 2em">周六，爸爸妈妈最后一次来玉泉了。和爸爸妈妈一起在校园了走走。</P>
<P style="TEXT-INDENT: 2em">据说，我们三个的鼻子是一模一样的噢：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/9yJ-VqofXJIMPfYZoHxQ1w==/2265873562521496784.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/9yJ-VqofXJIMPfYZoHxQ1w==/2265873562521496784.jpg"></A></P>
<P style="TEXT-INDENT: 2em">我和妈妈：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/ypAmItaioBlnbbZsHH_i0Q==/907193849938969850.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/ypAmItaioBlnbbZsHH_i0Q==/907193849938969850.jpg"></A></P>
<P style="TEXT-INDENT: 2em">我和爸爸：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/evXiicr62j3Y3lW0rPPibA==/4517110426253339045.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/evXiicr62j3Y3lW0rPPibA==/4517110426253339045.jpg"></A></P>
<P style="TEXT-INDENT: 2em">很遗憾~雯雯要上班，没能来与我一起拍毕业照。补上一张另外的吧，这张好可爱：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/7Q7HWTEqsHq_1TX8v9dyAA==/3958101122506018839.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/7Q7HWTEqsHq_1TX8v9dyAA==/3958101122506018839.jpg"></A></P>
<P style="TEXT-INDENT: 2em">穿上学位服，与主席合影：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/moJAMFjX-Hu7l1lufsi_Zg==/1735574706398708729.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/moJAMFjX-Hu7l1lufsi_Zg==/1735574706398708729.jpg"></A></P>
<P style="TEXT-INDENT: 2em">在学位授予仪式上占个好坑留念：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/JstiV6ogG6G4Uk0Q7QoqXw==/4576220171362546839.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/JstiV6ogG6G4Uk0Q7QoqXw==/4576220171362546839.jpg"></A></P>
<P style="TEXT-INDENT: 2em">毕业前与我尊敬的导师，刘旭教授的合影：</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/b8K9HCho9mNiwQbXRfbHUA==/3111142917583190367.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/b8K9HCho9mNiwQbXRfbHUA==/3111142917583190367.jpg"></A></P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">毕业了，读书的时候每天都想什么时候才能穿上学位服，走出校门，真的要走了，又有太多太多不舍。昨天晚上，本科同学聚在一起喝酒，酒真的是个好东西，喝起来就是痛快，从来没这么痛快过。</P>
<P style="TEXT-INDENT: 2em">别了，浙大，我的母校。</P>
<P style="TEXT-INDENT: 2em">别了，杭州，我的第二故乡。</P>
<P style="TEXT-INDENT: 2em">别了，亲爱的朋友们，最珍贵的记忆都是大家带给我的，小勇这辈子铭记在心，不敢忘怀。</P>
<P style="TEXT-INDENT: 2em">希望大家的明天都会更加美好，在新的岗位上发挥自己的才能；希望每一个朋友都能一帆风顺、幸福美满；希望下次相聚的时候，都能见到大家的家庭~</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/5101920086103016419</comments>
    <slash:comments>5</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/5101920086103016419</guid>
    <pubDate>Tue, 1 Jul 2008 00:30:16 +0800</pubDate>
    <dcterms:modified>2008-07-01T00:59:42+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[写在离别前]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200852514850995</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">毕业典礼的日子随着天气逐渐变热而一天天的临近，我离开母校的日子也不远了。作为毕业生的生活可以说是“颓废”的，天天睡到自然醒，这一点，与两年前的那段日子是一样的。可是，这一次，与两年前的那次毕业相比，却又有另外一番滋味。</P>
<P style="TEXT-INDENT: 2em">真的要走了，还记得，考上大学那年，我注册了一系列网络ID都叫nb886，也就是宁波886，看来，这一次，呆了六年的杭州，呆了六年的浙大，真的要说再见了。去年，送别陆骏的时候，在车站，我可以感受到他的不舍，感受到他的留恋，过几天，该轮到我了。也许是在实验室的朝夕相对，读完研究生，又比本科的时候多了一层对母校的感情，对老师的感情，对实验室兄弟姐妹的感情。</P>
<P style="TEXT-INDENT: 2em">两个室友都是本科时候的同学，这一次是真的要天南地北了，光要去上海，我要回宁波，而宋博，继续留在浙大搞学问，还能在学校多赖几年。其实，真的到了离别的时候，我还真是有点留恋学生生活。自由支配的时间相当丰富，工作了就再也没有这种权力。</P>
<P style="TEXT-INDENT: 2em">走之前，心里很乱。先写这么多吧。。。最后，秀个学位照，鼓励一下自己。</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/srQ7aFC07bCoJqeUc4i3qQ==/3736861790811232932.jpg" target=_blank><IMG style="DISPLAY: block; TEXT-ALIGN: center" src="http://img.blog.163.com/photo/srQ7aFC07bCoJqeUc4i3qQ==/3736861790811232932.jpg"></A></P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200852514850995</comments>
    <slash:comments>10</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200852514850995</guid>
    <pubDate>Wed, 25 Jun 2008 01:48:50 +0800</pubDate>
    <dcterms:modified>2008-06-25T01:48:50+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[下一代的WEB开发框架(转)]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200851243153227</link>
    <description><![CDATA[<div><P align=left>&nbsp;&nbsp;&nbsp; JSP曾经以编译的Servlet在速度上打败了asp, php. 但是JSP很久以来没有多大的革新. 代码和页面的混合, 使IDE很难兼顾. 在处理一些复杂的连动时, 更是手忙脚乱. 在结构上和JSP类似的ASP.net凭借其服务器端控件编程和数据绑定的概念, 让开发者就象用VB一样编程. 原来可以这样编写WEB程序! </P>其实这只是从编程观念上的一个转变, 把浏览器上的事件告诉在Server上驻留在Session中的控件. 那么用Java怎样实现呢? 我曾经构想过两种方案来实现: 
<BLOCKQUOTE>
<P>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 跟Asp.net一样, 采用Tag替换的方式工作.</P>
<P>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发展JSP, 用TagLib实现服务器端控件.</P></BLOCKQUOTE>
<P>方案1需要很好的解析html. 优点是灵活, 可以利用现有的HTML编辑工具.</P>
<P>方案2要求TagLib能允许任意属性, 这要期待jsp2.0. 优点是兼容目前的JSP, 而且可以利用Taglib的嵌套, 循环.</P>
<P>我曾经试着写一些原型来实现方案1, 发现效果不错, 但是离实用还需要相当的工作量. 那么internet上的Java爱好者们也不甘寂寞吧? 让我们来看看:</P>
<H3>JSF(JavaServer Faces) &nbsp;<A href="http://sourceforge.net/projects/tapestry/"><FONT color=#000000 size=-1>http://sourceforge.net/projects/tapestry/</FONT></A></H3>
<P>原来Sun的专家们早就忙活开了, 不过天才们仅仅又订出一个伟大的规范, 丢给厂商们去五花八门的实现. 不用猜了, 是利用JSP+TagLib. 以Sun的影响力, 应该有机会看到IDE, 希望不要太晚.</P>
<H3>Tapestry <FONT color=#000000 size=-1><A href="http://sourceforge.net/projects/tapestry/">http://sourceforge.net/projects/tapestry/</A></FONT></H3>
<P>这个SourceForge上的开源项目看起来很活跃, 2.3beta1版 配置相对烦琐. 2.4alpha1简化了配置, 但目前还不算稳定, 看demo建议用2.3版. 从实现方式上看类似方案1, 不喜欢jsp和xsl的美工可能要兴高采烈. SourceForge上有很多它的辅助项目, 其中一个是Eclipse插件, 看来离实用不远了. 下面是一个显示当前时间的简单例子:</P>
<P><B><U>Home.html:</U></B></P>
<P>==========================================<B></B></P>
<BLOCKQUOTE>
<P><FONT size=-1>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;</FONT></P>
<P><FONT size=-1>&lt;html&gt;</FONT></P>
<P><FONT size=-1>&lt;head&gt;</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Simple&lt;/title&gt;</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>&lt;/head&gt;</FONT></P>
<P><FONT size=-1>&lt;body&gt;</FONT></P>
<P><FONT size=-1>This application demonstrates some dynamic behavior using Tapestry components.</FONT></P>
<P><FONT size=-1>&lt;p&gt;The current date and time is: &lt;b&gt;&lt;span<B> jwcid="@Insert" value="[[ currentDate ]]</B>"&gt;Current Date&lt;/span&gt;&lt;/b&gt;</FONT></P>
<P><FONT size=-1>&lt;p&gt;Click &lt;a <B>jwcid="@PageLink" page="Home" sometag=”test”</B>&gt;here&lt;/a&gt; to refresh.</FONT></P>
<P><FONT size=-1>&lt;/body&gt;</FONT></P>
<P><FONT size=-1>&lt;/html&gt;</FONT></P></BLOCKQUOTE>
<P><B><U>Home.java:</U></B></P>
<P>==========================================<B></B><B></B></P>
<BLOCKQUOTE>
<P><FONT size=-1>package tutorial.simple;</FONT></P>
<P><FONT size=-1>import java.util.Date;</FONT></P>
<P><FONT size=-1>import net.sf.tapestry.html.BasePage;</FONT></P>
<P><FONT size=-1>/**</FONT></P>
<P><FONT size=-1>&nbsp;*&nbsp; @version $Id: Home.java,v 1.9 2002/11/27 17:58:58 hship Exp $</FONT></P>
<P><FONT size=-1>&nbsp;*&nbsp; @author Howard Lewis Ship</FONT></P>
<P><FONT size=-1>&nbsp;*</FONT></P>
<P><FONT size=-1>&nbsp;**/</FONT></P>
<P><FONT size=-1>public class Home extends BasePage</FONT></P>
<P><FONT size=-1>{</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Date <B>getCurrentDate()</B></FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Date();</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>}</FONT></P></BLOCKQUOTE>
<P>==========================================<B></B></P>
<H3>Echo <A href="http://www.nextapp.com/products/echo/"><FONT color=#000000>http://www.nextapp.com/products/echo/</FONT></A></H3>
<P style="TEXT-ALIGN: left" align=left>这个小东西才1.0Beta3版, 但是它的Demo让我流了一地口水. 操作浏览器上的窗口居然和写普通程序swing程序没什么两样, 而且能同时刷新. 如果前面两个框架里面还多少残留Struts的味道, 那么Echo让我们彻底回到了OO: 用swing的概念去写servlet. 目前还没看到IDE支持, 如果Borland如果愿意, 让Jbuilder支持它是易如反掌. SourceForge里面还有两个echo相关项目EchoPoint和Marsh提供了更多的让你馋涎欲滴的echo控件, 有兴趣的朋友可以去看看. 下面是一个HelloWorld的例子</P>
<P><B><U>HelloWorldServlet:</U></B></P>
<P>==========================================</P>
<BLOCKQUOTE>
<P><FONT size=-1>import nextapp.echo.ContentPane;</FONT></P>
<P><FONT size=-1>import nextapp.echo.EchoInstance;</FONT></P>
<P><FONT size=-1>import nextapp.echo.Label;</FONT></P>
<P><FONT size=-1>import nextapp.echo.Window;</FONT></P>
<P><FONT size=-1>import nextapp.echoservlet.EchoServer;</FONT></P>
<P><FONT size=-1>public class <B>HelloWorldServlet extends EchoServer</B> {</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; // 为用户返回一个新的实例</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; public EchoInstance newInstance() {</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new HelloWorld();</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; }</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>}</FONT></P>
<P><FONT size=-1>class <B>HelloWorld extends EchoInstance</B> {</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; // 在用户首次访问时调用init方法. 返回的Window即用户浏览器看到的内容</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; public <B>Window init() </B>{</FONT></P>
<BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Window window = new Window();</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Components 不能直接放到Window下, 必须加到content中</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ContentPane content = new ContentPane();</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; window.setContent(content);</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label label = new Label("Hello, World!");</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; content.add(label);</FONT></P>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return window;</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>&nbsp;&nbsp;&nbsp; }</FONT></P></BLOCKQUOTE>
<P><FONT size=-1>}</FONT></P></BLOCKQUOTE>
<P>==========================================</P>
<P>不搜不知道, 世界真奇妙. 想想以前在WEB上完成一些复杂功能有多辛苦, 后台的程序, 前台的脚本, 一个都不能少. Web Componets的出现让我们看到了希望, 复杂的操作都交给框架去完成, 让我们回到面向对象的OO世界. 但是要看到, 由于过分依赖Session和浏览器脚本, 过多的事件将导致服务器性能下降. 不过因为都是基于Servlet, 我们可以和传统的开发方式并用. 并且随着网络性能的提高和IDE的支持, 以后WEB开发也会变成高效, 愉快的事情. </P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200851243153227</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200851243153227</guid>
    <pubDate>Thu, 12 Jun 2008 16:31:53 +0800</pubDate>
    <dcterms:modified>2008-06-12T16:31:53+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[log4net使用实例]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/5101920084299524443</link>
    <description><![CDATA[<div><P align=left>log4net是一个优秀的开源日志项目，现将本人使用写成一个demo，如下 </P>
<P>0:准备 <BR>去http://logging.apache.org/，可下载log4net，最新为1.2版本， <BR>建立一个asp.net web 项目，并将log4net.dll添加到引用 </P>
<P>1：建立数据表 <BR>CREATE TABLE [dbo].[Log] ( <BR>[Id] [int] IDENTITY (1, 1) NOT NULL, <BR>[Date] [datetime] NOT NULL, <BR>[Thread] [varchar] (255) NOT NULL, <BR>[Level] [varchar] (50) NOT NULL, <BR>[Logger] [varchar] (255) NOT NULL, <BR>[Message] [varchar] (4000) NOT NULL, <BR>[Exception] [varchar] (2000) NULL <BR>) <BR></P>
<P>2：编写配置文件 <BR>&lt;configuration&gt; <BR>&lt;configSections&gt; <BR>&lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /&gt; <BR>&lt;/configSections&gt; </P>
<P>&lt;system.web&gt; <BR>&lt;!-- <BR>...... <BR>--&gt; <BR>&lt;/system.web&gt; </P>
<P>&lt;log4net&gt; </P>
<P>&lt;root&gt; <BR>&lt;level value="ALL" /&gt; <BR>&lt;appender-ref ref="ADONetAppender" /&gt; <BR>&lt;/root&gt; </P>
<P>&lt;!-- <BR>&lt;logger name="testApp.Logging"&gt; <BR>&lt;level value="ALL"/&gt; <BR>&lt;appender-ref ref="ADONetAppender" /&gt; </P>
<P>&lt;/logger&gt; <BR>--&gt; </P>
<P>&lt;appender name="ADONetAppender" type="log4net.Appender.ADONetAppender"&gt; <BR>&lt;bufferSize value="10" /&gt; <BR>&lt;connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /&gt; <BR>&lt;connectionString value="server=localhost;database=demo;user id=sa;password=123456" /&gt; <BR>&lt;commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@log_date" /&gt; <BR>&lt;dbType value="DateTime" /&gt; <BR>&lt;layout type="log4net.Layout.RawTimeStampLayout" /&gt; <BR>&lt;/parameter&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@thread" /&gt; <BR>&lt;dbType value="String" /&gt; <BR>&lt;size value="255" /&gt; <BR>&lt;layout type="log4net.Layout.PatternLayout"&gt; <BR>&lt;conversionPattern value="%thread" /&gt; <BR>&lt;/layout&gt; <BR>&lt;/parameter&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@log_level" /&gt; <BR>&lt;dbType value="String" /&gt; <BR>&lt;size value="50" /&gt; <BR>&lt;layout type="log4net.Layout.PatternLayout"&gt; <BR>&lt;conversionPattern value="%level" /&gt; <BR>&lt;/layout&gt; <BR>&lt;/parameter&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@logger" /&gt; <BR>&lt;dbType value="String" /&gt; <BR>&lt;size value="255" /&gt; <BR>&lt;layout type="log4net.Layout.PatternLayout"&gt; <BR>&lt;conversionPattern value="%logger" /&gt; <BR>&lt;/layout&gt; <BR>&lt;/parameter&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@message" /&gt; <BR>&lt;dbType value="String" /&gt; <BR>&lt;size value="4000" /&gt; <BR>&lt;layout type="log4net.Layout.PatternLayout"&gt; <BR>&lt;conversionPattern value="%message" /&gt; <BR>&lt;/layout&gt; <BR>&lt;/parameter&gt; <BR>&lt;parameter&gt; <BR>&lt;parameterName value="@exception" /&gt; <BR>&lt;dbType value="String" /&gt; <BR>&lt;size value="2000" /&gt; <BR>&lt;layout type="log4net.Layout.ExceptionLayout" /&gt; <BR>&lt;/parameter&gt; <BR>&lt;/appender&gt; </P>
<P>&lt;/log4net&gt; </P>
<P>&lt;/configuration&gt; </P>
<P>特别说明&lt;bufferSize value="10" /&gt;，这是log信息记录的缓冲大小，(比如只有log信息记录达到10， <BR>才会将log信息记录写入数据库) </P>
<P>3：在Global.asax.cs中 <BR>protected void Application_Start(Object sender, EventArgs e) <BR>{ <BR>//读取配置信息 <BR>log4net.Config.DOMConfigurator.Configure(); <BR>} <BR>4：一个使用log的demo类 <BR>using System; </P>
<P>namespace Log <BR>{ <BR>/// &lt;summary&gt; <BR>/// MyLog 的摘要说明。 <BR>/// &lt;/summary&gt; <BR>public class MyLog <BR>{ <BR>private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(MyLog)); <BR>public static void LogInfo() <BR>{ <BR>log.Info("log日志"); <BR>} </P>
<P>public static void LogError() <BR>{ <BR>log.Info("log错误"); <BR>} <BR>} <BR>}</P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/5101920084299524443</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/5101920084299524443</guid>
    <pubDate>Thu, 29 May 2008 09:52:04 +0800</pubDate>
    <dcterms:modified>2008-05-29T09:52:48+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[如何使用log4net]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200842913159477</link>
    <description><![CDATA[<div>介绍<BR><BR>Log4net是一个开源的组件.可以使.net程序记录日志并输出成各种格式.<BR><BR>使用代码<BR><BR>Log4net可以提供简便的方式去使用强大的日志功能.步骤如下:<BR><SPAN style="COLOR: rgb(255,0,255)">1.</SPAN>获取最新版本的Log4net组件并添加引用到程序<BR><SPAN style="COLOR: rgb(255,0,255)">2.</SPAN>增加以后行到你的AssemblyInfo.cs文件<BR><BR>[assembly: log4net.Config.XmlConfigurator(ConfigFile=<SPAN style="COLOR: rgb(255,0,255)">"Web.config"</SPAN>,Watch=<SPAN style="COLOR: rgb(255,0,255)">true</SPAN>)] <SPAN style="COLOR: rgb(0,0,255)">//For log4net 1.2.10.0</SPAN><BR>上面的语句提供了配置log4net参数的配置文件<BR><BR><SPAN style="COLOR: rgb(255,0,255)">3.</SPAN>添加以下节点到web.config<BR><BR>&lt;configSections&gt;<BR>&lt;section name=<SPAN style="COLOR: rgb(255,0,255)">"log4net"</SPAN> type=<SPAN style="COLOR: rgb(255,0,255)">"log4net.Config.Log4NetConfigurationSectionHandler, log4net"</SPAN> /&gt;<BR>&lt;/configSections&gt;<BR>&lt;log4net debug=<SPAN style="COLOR: rgb(255,0,255)">"true"</SPAN>&gt;<BR>&lt;appender name=<SPAN style="COLOR: rgb(255,0,255)">"RollingLogFileAppender"</SPAN> type=<SPAN style="COLOR: rgb(255,0,255)">"log4net.Appender.RollingFileAppender"</SPAN>&gt;<BR>&lt;file <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"C:</SPAN><SPAN style="COLOR: rgb(106,90,205)">\\</SPAN><SPAN style="COLOR: rgb(255,0,255)">TestProj</SPAN><SPAN style="COLOR: rgb(106,90,205)">\\</SPAN><SPAN style="COLOR: rgb(255,0,255)">TestLog.txt"</SPAN> /&gt;<BR>&lt;appendToFile <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"true"</SPAN> /&gt;<BR>&lt;rollingStyle <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"Size"</SPAN> /&gt;<BR>&lt;maxSizeRollBackups <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"10"</SPAN> /&gt;<BR>&lt;maximumFileSize <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"10MB"</SPAN> /&gt;<BR>&lt;staticLogFileName <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"true"</SPAN> /&gt;<BR>&lt;layout type=<SPAN style="COLOR: rgb(255,0,255)">"log4net.Layout.PatternLayout"</SPAN>&gt;<BR>&lt;conversionPattern <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n"</SPAN> /&gt;<BR>&lt;/layout&gt;<BR>&lt;/appender&gt;<BR>&lt;root&gt;<BR>&lt;level <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"DEBUG"</SPAN> /&gt;<BR>&lt;appender-<SPAN style="COLOR: rgb(128,64,64)"><STRONG>ref</STRONG></SPAN> <SPAN style="COLOR: rgb(128,64,64)"><STRONG>ref</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"RollingLogFileAppender"</SPAN> /&gt;<BR>&lt;/root&gt;<BR>&lt;/log4net&gt;<BR><BR>上面的节点定义了配置记录日志的参数<BR><BR>RollingLogFileAppender描述记录日志的方式,这代表日志将被写在一个文件,该文件当满的话会自动增加.这里有其他可用的途径来保存日志.<BR><BR>layout负责格式化日志请求,然而保存日志途径的定义和日志输出的格式有关.上边layout输出的格式如下:<BR><BR><SPAN style="COLOR: rgb(255,0,255)">2006</SPAN>-<SPAN style="COLOR: rgb(255,0,255)">07</SPAN>-<SPAN style="COLOR: rgb(255,0,255)">14</SPAN> <SPAN style="COLOR: rgb(255,0,255)">20</SPAN>:<SPAN style="COLOR: rgb(255,0,255)">26</SPAN>:<SPAN style="COLOR: rgb(255,0,255)">04</SPAN>,<SPAN style="COLOR: rgb(255,0,255)">033</SPAN> [<SPAN style="COLOR: rgb(255,0,255)">1736</SPAN>] ERROR Utility [PayStub] - Could not find a part of the path<BR><SPAN style="COLOR: rgb(255,0,255)">"c:</SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255)">\i</SPAN></SPAN><SPAN style="COLOR: rgb(255,0,255)">netpub</SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255)">\w</SPAN></SPAN><SPAN style="COLOR: rgb(255,0,255)">wwroot</SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255)">\T</SPAN></SPAN><SPAN style="COLOR: rgb(255,0,255)">estProj</SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255)">\T</SPAN></SPAN><SPAN style="COLOR: rgb(255,0,255)">emplate</SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,0,0)"><SPAN style="COLOR: rgb(255,255,255)">\P</SPAN></SPAN><SPAN style="COLOR: rgb(255,0,255)">ayStub.xml"</SPAN><BR><BR><SPAN style="COLOR: rgb(255,0,255)">4.</SPAN>如果你想要log4net增加自己的诊断信息,须在web.config文件中加入以下代码:<BR><BR>&lt;appSettings&gt;<BR>&lt;<SPAN style="COLOR: rgb(128,64,64)"><STRONG>add</STRONG></SPAN> key=<SPAN style="COLOR: rgb(255,0,255)">"log4net.Internal.Debug"</SPAN> <SPAN style="COLOR: rgb(128,64,64)"><STRONG>value</STRONG></SPAN>=<SPAN style="COLOR: rgb(255,0,255)">"true"</SPAN> /&gt;<BR>&lt;/appSettings&gt;<BR><BR>在system.web节点下如以下代码:<BR><BR>&lt;system.diagnostics&gt;<BR>&lt;trace autoflush=<SPAN style="COLOR: rgb(255,0,255)">"true"</SPAN>&gt;<BR>&lt;listeners&gt;<BR>&lt;<SPAN style="COLOR: rgb(128,64,64)"><STRONG>add</STRONG></SPAN> name=<SPAN style="COLOR: rgb(255,0,255)">"textWriterTraceListener"</SPAN><BR>type=<SPAN style="COLOR: rgb(255,0,255)">"System.Diagnostics.TextWriterTraceListener"</SPAN><BR>initializeData=<SPAN style="COLOR: rgb(255,0,255)">"C:</SPAN><SPAN style="COLOR: rgb(106,90,205)">\\</SPAN><SPAN style="COLOR: rgb(255,0,255)">TestProj</SPAN><SPAN style="COLOR: rgb(106,90,205)">\\</SPAN><SPAN style="COLOR: rgb(255,0,255)">TestProjlog4net.txt"</SPAN> /&gt;<BR>&lt;/listeners&gt;<BR>&lt;/trace&gt;<BR>&lt;/system.diagnostics&gt;<BR><BR><SPAN style="COLOR: rgb(255,0,255)">5.</SPAN>在代码页面进行以下步骤:<BR><BR>a.添加名字空间<BR><SPAN style="COLOR: rgb(128,64,64)"><STRONG>using</STRONG></SPAN> log4net;<BR><BR>b.添加有类定义的声明<BR><SPAN style="COLOR: rgb(46,139,87)"><STRONG>private</STRONG></SPAN> <SPAN style="COLOR: rgb(46,139,87)"><STRONG>static</STRONG></SPAN> <SPAN style="COLOR: rgb(46,139,87)"><STRONG>readonly</STRONG></SPAN> ILog log = LogManager.GetLogger(<SPAN style="COLOR: rgb(128,64,64)"><STRONG>typeof</STRONG></SPAN>(TestPage1).Name);<BR>或<BR><SPAN style="COLOR: rgb(46,139,87)"><STRONG>private</STRONG></SPAN> <SPAN style="COLOR: rgb(46,139,87)"><STRONG>static</STRONG></SPAN> <SPAN style="COLOR: rgb(46,139,87)"><STRONG>readonly</STRONG></SPAN> ILog log = LogManager.GetLogger(<BR>System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);<BR><BR><SPAN style="COLOR: rgb(255,0,255)">6.</SPAN>现在你可以用下面的语句记录日志了:<BR><BR><SPAN style="COLOR: rgb(128,64,64)"><STRONG>if</STRONG></SPAN> (log.IsErrorEnabled)<BR>{<BR>log.Error(<SPAN style="COLOR: rgb(255,0,255)">"Page Load failed : "</SPAN> + ex.Message);<BR>}<BR>或<BR><SPAN style="COLOR: rgb(128,64,64)"><STRONG>if</STRONG></SPAN> (log.IsDebugEnabled)<BR>{<BR>log.Debug(<SPAN style="COLOR: rgb(255,0,255)">"Application loaded successfully."</SPAN>);<BR>}<BR><BR>现在我们已经接触到log4net的皮毛了,log4net还有很多特性可用.&nbsp;</div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200842913159477</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200842913159477</guid>
    <pubDate>Thu, 29 May 2008 01:31:59 +0800</pubDate>
    <dcterms:modified>2008-05-29T01:31:59+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Log4Net五步走]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200842913120663</link>
    <description><![CDATA[<div><P>本文不是教你全面了解log4net,本文只是希望教会你按步就班,照糊芦画瓢般就会用log4net<BR>1,引入log4net.dll组件<BR>2,建立一个配置文件<BR>两种方法,一种是在Web.Config或App.Config里<BR>加入以下配置节<BR>&lt;configSections&gt;<BR>&nbsp;&lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /&gt;<BR>&lt;/configSections&gt;<BR>上面的配置节,复制就可以用了</P>
<P>加入log4net配置内容的定义,这个紧接着上面的内容定义在config文件里就可以了,下面是一个范例:<BR>&lt;log4net&gt;<BR>&nbsp;&lt;root&gt;<BR>&nbsp;&lt;level value="ALL" /&gt;<BR>&nbsp;&lt;appender-ref ref="rollingFile" /&gt;<BR>&nbsp;&lt;/root&gt;</P>
<P>&nbsp;&lt;appender&nbsp; name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net" &gt;<BR>&nbsp;&lt;param name="File" value="log.txt" /&gt;<BR>&nbsp;&lt;param name="AppendToFile" value="false" /&gt;<BR>&nbsp;&lt;param name="RollingStyle" value="Date" /&gt;<BR>&nbsp;&lt;param name="DatePattern" value="yyyy.MM.dd" /&gt;<BR>&nbsp;&lt;param name="StaticLogFileName" value="true" /&gt;<BR>&nbsp;&lt;layout type="log4net.Layout.PatternLayout,log4net"&gt;<BR>&nbsp;&nbsp;&lt;param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /&gt;<BR>&nbsp;&nbsp;&lt;param name="Header" value="&amp;#13;&amp;#10;----------------------header--------------------------&amp;#13;&amp;#10;" /&gt;<BR>&nbsp;&nbsp;&lt;param name="Footer" value="&amp;#13;&amp;#10;----------------------footer--------------------------&amp;#13;&amp;#10;" /&gt;<BR>&nbsp;&lt;/layout&gt;<BR>&nbsp;&lt;/appender&gt;&nbsp;<BR>&nbsp;&lt;appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net"&gt;&nbsp;<BR>&nbsp;&nbsp;&lt;layout type="log4net.Layout.PatternLayout,log4net"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /&gt;<BR>&nbsp;&nbsp;&lt;/layout&gt;<BR>&nbsp;&lt;/appender&gt;&nbsp;<BR>&nbsp;&lt;logger name="Log4NetTest.LogTest"&gt;<BR>&nbsp;&nbsp;&lt;level value="DEBUG" /&gt;<BR>&nbsp;&nbsp;&lt;appender-ref&nbsp; ref="rollingFile" /&gt;<BR>&nbsp;&nbsp;&lt;appender-ref ref="coloredConsoleApp" /&gt;<BR>&nbsp;&nbsp;&lt;appender-ref ref="SystemEvent" /&gt;<BR>&nbsp;&lt;/logger&gt;<BR>&lt;/log4net&gt;<BR>你懒得写的话,复制上面的内容也可以<BR>不过,还是稍做讲解,log4net配置节的XSD层次如下</P>
<P>&lt;log4net&gt;<BR>&nbsp;&lt;root&gt;&lt;level /&gt;&lt;appender-ref ref="" /&gt;&lt;/root&gt;<BR>&nbsp;&lt;appender name="" type="Appender的完全限定类名"&gt;<BR>&nbsp;&lt;param name="" value="" /&gt;<BR>&nbsp;&lt;layout type="log4net.Layout.PatternLayout,log4net"&gt;<BR>&nbsp;&nbsp;&lt;param name="" value="" /&gt;<BR>&nbsp;&lt;/layout&gt;<BR>&nbsp;&lt;/appender&gt;<BR>&nbsp;&lt;logger&gt;<BR>&nbsp;&lt;level value="" /&gt;<BR>&nbsp;&lt;appender-ref ref="" /&gt;<BR>&lt;/logger&gt;<BR>看不懂?其实很简单啦<BR>log4net是log4net配置节的根标记<BR>root标记定义一个根级别的记录者,log4net的记录者采用层级组织的, 两个logger,A的名字叫loggerA,B的名字叫loggerA.B的话,那么B就是A的儿子,B会自动继承A的一些定义,例如LEVEL定义,appender-ref定义等,root就是总的logger,其余定义的logger都是他的后代,都会继承他的设置</P>
<P>包括ROOT在内的每一个LOGGER(ROOT也是一个LOGGER,只不过,他是祖先而已,别的方面,跟其他LOGGER一样),都可以定义Level<BR>level定义记录的日志级别,就是说,你要记录哪个级别以上的日志,级别由高往低依次是:<BR>None<BR>Fatal<BR>ERROR<BR>WARN<BR>DEBUG<BR>INFO<BR>ALL</P>
<P>级别的定义要注意,如果你定义DEBUG,那么低于DEBUG级别以下的信息,将不会记入日志,啥意思呢?就是说,就算你在程序里,用log.info()来写入一个日志信息,可是你在配置中指定level为DEBUG,由于INFO级别低于DEBUG,所以,不会被记入日志.这样的处理非常灵活</P>
<P>Logger还有一个配置就是appender-ref了,ref是参照的意思,log4net的架构非常有意思,可扩展性非常高非常值得借鉴,他分为四个要素:<BR>logger<BR>appender<BR>layout<BR>filter</P>
<P>logger是负责日志的记录者<BR>appender提供记录的介质<BR>layout负责把记入的内容格式化<BR>filter负责把内容进行筛选</P>
<P>可以说,整个过程就是一个日志流水线,每个成员负责其中的一个环节<BR>logger发出记录信息,appender接到信息,根据内部的layout配置对记录信息格式化,根据filter决定此信息是否被过滤掉,最后,将其序列化</P>
<P>因此,logger的appender-ref就是定义说,LOGGER要找谁去将内容写入磁盘,流或其他介质,因此,十分重要吧<BR>既然是ref引用,那肯定要定义这个被引用的appender对象了呀</P>
<P>每个appender都代表了一个输出介质<BR>name属性指定其名称,type则是log4net.Appender命名空间的一个类的名称,意思是,指定使用哪种介质<BR>log4net支持的appender类型有十几种,最常用的有rollingFileAppender,AdoNetAppender,EventLogAppender,FileAppender,分别把日志记入文件,系统日志和数据库<BR>除此之外,appender内的其他参数都用param标记,以key/value形式定义于其内<BR>这里有个小提示,每一个appender,log4net并没有在文档中提出他们需要哪些参数,那么,我们怎么知道呢?<BR>原来,这些param的名称,你可以直接查对应的appender类的属性名即可,例如,使用EventLogAppender时,通过查看类的属性,我们知道其有<BR>LogName,ApplicationName属性,那么,意味着,你可以直接在这个APPENDER的param里加入以下内容:<BR>&lt;param name="LogName" value="Application" /&gt;<BR>&lt;param name="ApplicationName" value="log4netTest" /&gt;</P>
<P>定义了appender的NAME及TYPE属性,以及使用param为其指定参数后,一个appender就建立了,你可以使用他的名字在LOGGER的&lt;appender-ref中去 引用它,那么,引用它的LOGGER在写入日志时,就是写到了APPENDER中定义的介质中去了<BR>一个LOGGER可以引用多个APPENDER,其结果是,同一个日志,被同时记录到多个介质中去 ,便如,同时发邮件,写入系统日志,发送到远程主机.不过,虽然可以这样做,但是还是要小心,因为,会对性能有一定的影响,除非你需要,否则,不要乱用此功能</P>
<P>另外,appender中可以定义可选的layout,layout的定义非常有必要,如果你不想将来看到你的日志会感觉头晕的话,虽然log4net帮你写入日志,但是,日志信息的格式却是我们使用者自行定义的<BR>layout的type参数指定使用哪个类的定义来格式化,常用的有XmlLayout,SimpleLayout,PatternLayout,这个当然要根据你的需要,以及你要产生的格式来选啦,如果你要输出成XML文档格式,你肯定不能用simplelayout吧<BR>layout使用param以KEY/VALUE形式定义其参数<BR>各个Layout类使用的参数当然不一样啦,具体的,你可以去看各个Layout类的属性<BR>其中,PatternLayout可以使用ConversionPattern参数来指定一个格式化字符串<BR>以及可以指定一个Header参数,做为日志开头的字符串,Footer来指定结尾字符串<BR>这里有一个小技巧,日志中开头和结尾总想产生回车符吧,虽然logger在写入一条日志会自动回车,可是Header和FOOTER却不会,咋办?用\n\r吗?(我从别人的BLOG上看到过)经实践,\n\r会原样定改日志,根本不会转换.其实,我们可以用XML实体呀,使用&amp;#13;&amp;#10;就可以在指定位置插入一个回车换行符了</P>
<P>最后,像log4net的文档中说的那样,如果你不想你的日志文件变得很大,使读写的性能下降的话,建议你还是分级管理日志,把粒度变小点,也就是说,除了定义ROOT外,最后,对每一个模块或每一个实体,依据用途,目的,定义各自的LOGGER配置,这样的好处是日志被分散了,日志文件增长就没那么快了.每一个LOGGER的结构跟ROOT是一模一样的,这里不再叙述了.像前面说的那样,如果你相让日志产生层级关系,你可以跟他们的NAME属性像C#中的namespace那样命名就可以了<BR>要说明的是,LOGGER的定义是非必须的,只是一种建议罢了,Log4net的配置中,除了必须定义一个ROOT和一个APPENDER外,其他的都是可选的</P>
<P>另一种配置log4net的方法,是在单独的XML文件中配置,这个时候,只要把log4net标记中的内容复制过来就行了,不需要configSections</P>
<P>3,在应用程序代码中读取配置<BR>这一步非常简单,你可以在应用程序集的assemblyInfo.cs文件中读取log4net配置<BR>对于WINFORM应用程序,你可以加入<BR>[assembly:log4net.Config.DOMConfigurator()]或<BR>[assembly:log4net.Config.XmlConfigurator()]<BR>对于WEBFORM你可以加入<BR>[assembly:log4net.Config.DOMConfigurator(ConfigFile="web.config",Watch=true)]</P>
<P>注意:如果使用NUNIT测试的朋友,要用生成后事件,copy "$(ProjectDir)app.config" "$(TargetPath).config"</P>
<P>4.在应用程序中获取ILog对象<BR>在需要使用LOGGER功能的类中,引入log4net空间,为类加入静态只读成员(静态的目的是只用一个对象,只读是防止误改)<BR>private static readonly ILog logger=LogManager.GetLogger(typeof(类))<BR>这里就可以获取配置文件中与类名同名的LOGGER对象了</P>
<P>5,写入日志<BR>很简单 logger.Deub(写入的内容)<BR>其他的还有info,warn,error等,很容易理解的</P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200842913120663</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200842913120663</guid>
    <pubDate>Thu, 29 May 2008 01:31:20 +0800</pubDate>
    <dcterms:modified>2008-05-29T01:31:20+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[日志记录组件[Log4net]详细介绍(转)]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200842913015878</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">
<TABLE>
<TBODY>
<TR>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em">因为工作中有要用到Log记录，找到一篇不错的文章，就转了过来。</P>
<P style="TEXT-INDENT: 2em">一&nbsp;Log4net简介</P>
<P style="TEXT-INDENT: 2em">Log4net是基于.net开发的一款非常著名的记录日志开源组件。他最早是2001年7月由NeoWorks&nbsp;Limited启动的项目，基本的框架源于另外的一个非常著名的姐妹组件－log4j。Log4net记录日志的功能非常强大。它可以将日志分不同的等级，比不同的样式，将日志输出到不同的媒介。</P>
<P style="TEXT-INDENT: 2em">Log4net可以从<A href="http://logging.apache.org/log4net/downloads.html">http://logging.apache.org/log4net/downloads.html</A>网站下载最新版本。</P>
<P style="TEXT-INDENT: 2em"></P>
<P style="TEXT-INDENT: 2em">二&nbsp;Log4net核心组成</P>
<P style="TEXT-INDENT: 2em">Log4net主要由五个部分组成，分别为Logger，Appenders,&nbsp;Filters,&nbsp;Layouts&nbsp;和Object&nbsp;Renders。</P>
<P style="TEXT-INDENT: 2em">一）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger(日志)</P>
<P style="TEXT-INDENT: 2em">1．&nbsp;记录日志的分类：</P>
<P style="TEXT-INDENT: 2em">Log4net能够以多种方式输出日志。支持的日志输出常用的主要媒介有数据库（包括MS&nbsp;SQL&nbsp;Server,&nbsp;Access,&nbsp;Oracle9i,Oracle8i,DB2,SQLite，控制台，文件，事件日志(可以用事件查看器查看)和邮件等多种方式。</P>
<P style="TEXT-INDENT: 2em">2．&nbsp;日志的级别</P>
<P style="TEXT-INDENT: 2em">Log4net支持多种级别的日志。优先级从高到低依次排列如下:</P>
<P style="TEXT-INDENT: 2em">FATAL&nbsp;&gt;&nbsp;ERROR&nbsp;&gt;&nbsp;WARN&nbsp;&gt;&nbsp;INFO&nbsp;&gt;&nbsp;DEBUG</P>
<P style="TEXT-INDENT: 2em">此外还有ALL（允许所有的日志请求）和OFF（拒绝所有的日志请求）这两种特殊的级别。</P>
<P style="TEXT-INDENT: 2em">二）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Appenders</P>
<P style="TEXT-INDENT: 2em">Appenders决定日志输出的方式。</P>
<P style="TEXT-INDENT: 2em">Appenders必须实现log4net.Appenders.IAppender接口。</P>
<P style="TEXT-INDENT: 2em">Log4net目前支持的输出方式包括：</P>
<P style="TEXT-INDENT: 2em">1&nbsp;AdoNetAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志记录到数据库中。可以采用SQL和存储过程两种方式。</P>
<P style="TEXT-INDENT: 2em">2&nbsp;AnsiColorTerminalAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;在ANSI&nbsp;窗口终端写下高亮度的日志事件。</P>
<P style="TEXT-INDENT: 2em">3&nbsp;AspNetTraceAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;能用asp.net中Trace的方式查看记录的日志。</P>
<P style="TEXT-INDENT: 2em">4&nbsp;BufferingForwardingAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;在输出到子Appenders之前先缓存日志事件。</P>
<P style="TEXT-INDENT: 2em">5&nbsp;ConsoleAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志输出到控制台。</P>
<P style="TEXT-INDENT: 2em">6&nbsp;EventLogAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志写到Windows&nbsp;Event&nbsp;Log.&nbsp;</P>
<P style="TEXT-INDENT: 2em">7&nbsp;FileAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志写到文件中。</P>
<P style="TEXT-INDENT: 2em">8&nbsp;LocalSyslogAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志写到local&nbsp;syslog&nbsp;service&nbsp;(仅用于UNIX环境下).&nbsp;</P>
<P style="TEXT-INDENT: 2em">9&nbsp;MemoryAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志存到内存缓冲区。</P>
<P style="TEXT-INDENT: 2em">10&nbsp;NetSendAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志输出到Windows&nbsp;Messenger&nbsp;service.这些日志信息将在用户终端的对话框中显示。</P>
<P style="TEXT-INDENT: 2em">11&nbsp;RemoteSyslogAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;通过UDP网络协议将日志写到Remote&nbsp;syslog&nbsp;service。</P>
<P style="TEXT-INDENT: 2em">12&nbsp;RemotingAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;通过.NET&nbsp;Remoting将日志写到远程接收端。</P>
<P style="TEXT-INDENT: 2em">13&nbsp;RollingFileAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志以回滚文件的形式写到文件中。</P>
<P style="TEXT-INDENT: 2em">14&nbsp;SmtpAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志写到邮件中。</P>
<P style="TEXT-INDENT: 2em">15&nbsp;TraceAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志写到.NET&nbsp;trace&nbsp;系统。</P>
<P style="TEXT-INDENT: 2em">16&nbsp;UdpAppender</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;将日志connectionless&nbsp;UDP&nbsp;datagrams的形式送到远程宿主或以UdpClient的形式广播。&nbsp;</P>
<P style="TEXT-INDENT: 2em">三）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filters</P>
<P style="TEXT-INDENT: 2em">Appender对象将日志以缺省的方式传到输出流，然后Filter可以按照不同的标准控制日志的输出。Filter可以再配置文件中配置。最简单的形式是在appender中写明一个Threshold.这样只有级别大于或等于此Threshold的日志才被记录。</P>
<P style="TEXT-INDENT: 2em">Filters必须实现log4net.Filters.IFilter接口。</P>
<P style="TEXT-INDENT: 2em">四）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Layouts</P>
<P style="TEXT-INDENT: 2em">Layouts控制日志显示的格式样式。日志的显示格式如下：</P>
<P style="TEXT-INDENT: 2em">"%timestamp&nbsp;[%thread]&nbsp;%-5level&nbsp;%logger&nbsp;-&nbsp;%message%newline"</P>
<P style="TEXT-INDENT: 2em">Timestamp:&nbsp;表示程序已经开始执行的时间。&nbsp;单位[毫秒]。</P>
<P style="TEXT-INDENT: 2em">Thread:执行当前代码的线程。</P>
<P style="TEXT-INDENT: 2em">Level：日志的级别。</P>
<P style="TEXT-INDENT: 2em">Logger：日志相关请求的名称。</P>
<P style="TEXT-INDENT: 2em">Message:　日志消息。</P>
<P style="TEXT-INDENT: 2em">Layouts还可以控制日志的输出样式，比如以普通形式或以xml等形式输出。</P>
<P style="TEXT-INDENT: 2em">五）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;Renderers</P>
<P style="TEXT-INDENT: 2em">这是很重要的一项，log4net将按照用户定义的标准输出日志消息。</P>
<P style="TEXT-INDENT: 2em">Object&nbsp;Renders必须实现log4net.ObjectRenderer.IObjectRenerer接口。</P>
<P style="TEXT-INDENT: 2em"></P>
<P style="TEXT-INDENT: 2em">三&nbsp;如何在项目中使用log4net</P>
<P style="TEXT-INDENT: 2em">下面有个基于控制台的demo，举例描述了log4net怎么用于输出日志。</P>
<P style="TEXT-INDENT: 2em">本例中，日志将会记录到文件，控制台，事件日至和Access数据库中。</P>
<P style="TEXT-INDENT: 2em">一）主要代码:</P>
<P style="TEXT-INDENT: 2em">1.&nbsp;配置文件app.config</P>
<P style="TEXT-INDENT: 2em">&nbsp;1&lt;?xml&nbsp;version="1.0"&nbsp;encoding="utf-8"&nbsp;?&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;2&lt;configuration&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;Register&nbsp;a&nbsp;section&nbsp;handler&nbsp;for&nbsp;the&nbsp;log4net&nbsp;section&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&lt;configSections&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;section&nbsp;name="log4net"&nbsp;type="System.Configuration.IgnoreSectionHandler"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&lt;/configSections&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&lt;appSettings&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;To&nbsp;enable&nbsp;internal&nbsp;log4net&nbsp;logging&nbsp;specify&nbsp;the&nbsp;following&nbsp;appSettings&nbsp;key&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;&lt;add&nbsp;key="log4net.Internal.Debug"&nbsp;value="true"/&gt;&nbsp;--&gt;&lt;/appSettings&gt;</P>
<P style="TEXT-INDENT: 2em">10&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;This&nbsp;section&nbsp;contains&nbsp;the&nbsp;log4net&nbsp;configuration&nbsp;settings&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">11&nbsp;&nbsp;&nbsp;&nbsp;&lt;log4net&gt;</P>
<P style="TEXT-INDENT: 2em">12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义输出到文件中--&gt;</P>
<P style="TEXT-INDENT: 2em">13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender&nbsp;name="LogFileAppender"&nbsp;type="log4net.Appender.FileAppender"&gt;</P>
<P style="TEXT-INDENT: 2em">14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义文件存放位置--&gt;</P>
<P style="TEXT-INDENT: 2em">15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;file&nbsp;value="D:\log-file1.txt"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;Example&nbsp;using&nbsp;environment&nbsp;variables&nbsp;in&nbsp;params&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;&lt;file&nbsp;value="${TMP}\log-file.txt"&nbsp;/&gt;&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&lt;sppendToFile&nbsp;value="true"&nbsp;/&gt;--&gt;</P>
<P style="TEXT-INDENT: 2em">19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;An&nbsp;alternate&nbsp;output&nbsp;encoding&nbsp;can&nbsp;be&nbsp;specified&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;&lt;encoding&nbsp;value="unicodeFFFE"&nbsp;/&gt;&nbsp;--&gt;</P>
<P style="TEXT-INDENT: 2em">21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--每条日志末尾的文字说明--&gt;</P>
<P style="TEXT-INDENT: 2em">23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;footer&nbsp;value="[Footer]--Test&nbsp;By&nbsp;Ring1981&nbsp;&nbsp;"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--输出格式--&gt;</P>
<P style="TEXT-INDENT: 2em">25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%date&nbsp;[%thread]&nbsp;%-5level&nbsp;%logger&nbsp;[%ndc]&nbsp;&amp;lt;%property{auth}&amp;gt;&nbsp;-&nbsp;%message%newline"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/appender&gt;</P>
<P style="TEXT-INDENT: 2em">28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义输出到控制台命令行中--&gt;</P>
<P style="TEXT-INDENT: 2em">29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender&nbsp;name="ConsoleAppender"&nbsp;type="log4net.Appender.ConsoleAppender"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%date&nbsp;[%thread]&nbsp;%-5level&nbsp;%logger&nbsp;[%property{NDC}]&nbsp;-&nbsp;%message%newline"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/appender&gt;</P>
<P style="TEXT-INDENT: 2em">34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义输出到windows事件中--&gt;</P>
<P style="TEXT-INDENT: 2em">35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender&nbsp;name="EventLogAppender"&nbsp;type="log4net.Appender.EventLogAppender"&gt;</P>
<P style="TEXT-INDENT: 2em">36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%date&nbsp;[%thread]&nbsp;%-5level&nbsp;%logger&nbsp;[%property{NDC}]&nbsp;-&nbsp;%message%newline"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/appender&gt;</P>
<P style="TEXT-INDENT: 2em">40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义输出到数据库中，这里举例输出到Access数据库中，数据库为D盘的access.mdb--&gt;</P>
<P style="TEXT-INDENT: 2em">41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender&nbsp;name="AdoNetAppender_Access"&nbsp;type="log4net.Appender.AdoNetAppender"&gt;</P>
<P style="TEXT-INDENT: 2em">42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;connectionString&nbsp;value="Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=D:\access.mdb"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;commandText&nbsp;value="INSERT&nbsp;INTO&nbsp;Log&nbsp;([Date],[Thread],[Level],[Logger],[Message])&nbsp;VALUES&nbsp;(@log_date,&nbsp;@thread,&nbsp;@log_level,&nbsp;@logger,&nbsp;@message)"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义各个参数--&gt;</P>
<P style="TEXT-INDENT: 2em">45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter&gt;</P>
<P style="TEXT-INDENT: 2em">46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameterName&nbsp;value="@log_date"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dbType&nbsp;value="String"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;size&nbsp;value="255"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%date"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameter&gt;</P>
<P style="TEXT-INDENT: 2em">53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter&gt;</P>
<P style="TEXT-INDENT: 2em">54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameterName&nbsp;value="@thread"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dbType&nbsp;value="String"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;size&nbsp;value="255"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%thread"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameter&gt;</P>
<P style="TEXT-INDENT: 2em">61&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter&gt;</P>
<P style="TEXT-INDENT: 2em">62&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameterName&nbsp;value="@log_level"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dbType&nbsp;value="String"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;size&nbsp;value="50"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">65&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">66&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%level"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">67&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">68&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameter&gt;</P>
<P style="TEXT-INDENT: 2em">69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter&gt;</P>
<P style="TEXT-INDENT: 2em">70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameterName&nbsp;value="@logger"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dbType&nbsp;value="String"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;size&nbsp;value="255"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">74&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%logger"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">75&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">76&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameter&gt;</P>
<P style="TEXT-INDENT: 2em">77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter&gt;</P>
<P style="TEXT-INDENT: 2em">78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameterName&nbsp;value="@message"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dbType&nbsp;value="String"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;size&nbsp;value="1024"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;layout&nbsp;type="log4net.Layout.PatternLayout"&gt;</P>
<P style="TEXT-INDENT: 2em">82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;conversionPattern&nbsp;value="%message"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/layout&gt;</P>
<P style="TEXT-INDENT: 2em">84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameter&gt;</P>
<P style="TEXT-INDENT: 2em">85&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/appender&gt;</P>
<P style="TEXT-INDENT: 2em">86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--定义日志的输出媒介，下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。--&gt;</P>
<P style="TEXT-INDENT: 2em">87&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;root&gt;</P>
<P style="TEXT-INDENT: 2em">88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender-ref&nbsp;ref="LogFileAppender"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender-ref&nbsp;ref="ConsoleAppender"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender-ref&nbsp;ref="EventLogAppender"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;appender-ref&nbsp;ref="AdoNetAppender_Access"&nbsp;/&gt;</P>
<P style="TEXT-INDENT: 2em">92&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/root&gt;</P>
<P style="TEXT-INDENT: 2em">93&nbsp;&nbsp;&nbsp;&nbsp;&lt;/log4net&gt;</P>
<P style="TEXT-INDENT: 2em">94&lt;/configuration&gt;</P>
<P style="TEXT-INDENT: 2em">2.&nbsp;LoggingExample.cs</P>
<P style="TEXT-INDENT: 2em">&nbsp;1//&nbsp;Configure&nbsp;log4net&nbsp;using&nbsp;the&nbsp;.config&nbsp;file</P>
<P style="TEXT-INDENT: 2em">&nbsp;2[assembly:&nbsp;log4net.Config.XmlConfigurator(Watch=true)]</P>
<P style="TEXT-INDENT: 2em">&nbsp;3//&nbsp;This&nbsp;will&nbsp;cause&nbsp;log4net&nbsp;to&nbsp;look&nbsp;for&nbsp;a&nbsp;configuration&nbsp;file</P>
<P style="TEXT-INDENT: 2em">&nbsp;4//&nbsp;called&nbsp;ConsoleApp.exe.config&nbsp;in&nbsp;the&nbsp;application&nbsp;base</P>
<P style="TEXT-INDENT: 2em">&nbsp;5//&nbsp;directory&nbsp;(i.e.&nbsp;the&nbsp;directory&nbsp;containing&nbsp;ConsoleApp.exe)</P>
<P style="TEXT-INDENT: 2em">&nbsp;6</P>
<P style="TEXT-INDENT: 2em">&nbsp;7namespace&nbsp;ConsoleApp</P>
<P style="TEXT-INDENT: 2em">&nbsp;8{</P>
<P style="TEXT-INDENT: 2em">&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;System;</P>
<P style="TEXT-INDENT: 2em">10</P>
<P style="TEXT-INDENT: 2em">11&nbsp;&nbsp;&nbsp;&nbsp;/**////&nbsp;&lt;summary&gt;</P>
<P style="TEXT-INDENT: 2em">12&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Example&nbsp;of&nbsp;how&nbsp;to&nbsp;simply&nbsp;configure&nbsp;and&nbsp;use&nbsp;log4net</P>
<P style="TEXT-INDENT: 2em">13&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;</P>
<P style="TEXT-INDENT: 2em">14&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;LoggingExample</P>
<P style="TEXT-INDENT: 2em">15&nbsp;&nbsp;&nbsp;&nbsp;{</P>
<P style="TEXT-INDENT: 2em">16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;readonly&nbsp;log4net.ILog&nbsp;log&nbsp;=&nbsp;log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);</P>
<P style="TEXT-INDENT: 2em">17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;Main(string[]&nbsp;args)</P>
<P style="TEXT-INDENT: 2em">19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</P>
<P style="TEXT-INDENT: 2em">20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.Error("Error&nbsp;Acc");</P>
<P style="TEXT-INDENT: 2em">21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.Fatal("Fatle&nbsp;Acc");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Console.ReadLine();</P>
<P style="TEXT-INDENT: 2em">23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P>
<P style="TEXT-INDENT: 2em">24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P style="TEXT-INDENT: 2em">25</P>
<P style="TEXT-INDENT: 2em">26&nbsp;&nbsp;&nbsp;&nbsp;}</P>
<P style="TEXT-INDENT: 2em">27}</P>
<P style="TEXT-INDENT: 2em">28</P>
<P style="TEXT-INDENT: 2em">运行程序，日志就会以xml中定义的四种媒介形式输出。&nbsp;</P>
<P style="TEXT-INDENT: 2em">源代码可以从<A href="http://www.cnblogs.com/Files/Ring1981/Log4net%20Test.rar">http://www.cnblogs.com/Files/Ring1981/Log4net%20Test.rar</A>下载。</P>
<P style="TEXT-INDENT: 2em"></P></TD></TR></TBODY></TABLE></P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200842913015878</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200842913015878</guid>
    <pubDate>Thu, 29 May 2008 01:30:15 +0800</pubDate>
    <dcterms:modified>2008-05-29T01:30:15+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[在Struts中使用DBCP的一点心得]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200842110273703</link>
    <description><![CDATA[<div><P>我想这算个BUG吧。</P>
<P>&nbsp;</P>
<P>直接在Struts-config.XML中右键data-sources然后New。</P>
<P>默认的type是：</P>
<P>org.apache.struts.util.GenericDataSource</P>
<P>struts自带的一个数据库连接池。</P>
<P>然后正确输入各种property的value。</P>
<P>测试，好用。</P>
<P>&nbsp;</P>
<P>如果将type选择为：</P>
<P>org.apache.commons.dbcp.BasicDataSource</P>
<P>这个DBCP的数据库连接池。</P>
<P>然后键入正确的value。</P>
<P>测试，提示各种异常&amp;找不到Driver。</P>
<P>&nbsp;</P>
<P>查看DBCP的文档，发现MYEclipse生成的配置XML元素有问题。</P>
<P>DBCP需要的是driverClassName和username这两个propertys。</P>
<P>而Myeclipse自动生成的是driverClass和user这两个propertys。</P>
<P>&nbsp;</P>
<P>改过来之后发现DBCP的数据库连接池也好用了：）</P>
<P>这应该算是MYECLIPSE开发struts的一个BUG吧，数据库连接池的配置是按照struts默认的GenericDataSource来的。如果能动态的在选择数据库连接池的时候，找寻set()/get()方法来生成属性的名字应该更好。</P>
<P>也看出来不同的数据库连接池在命名规则方面存在的一些差异。</P>
<P>其实很简单的东西，我却花费了半天的时间，原因是我太相信工具了，以为生成的东西一定是正确的，所以一直在想是不是别的方面出错了。得到这次教训之后，要更加清晰的对工具持怀疑态度了。不能太过相信和依靠，还是自己对这些技术的了解最重要。</P>
<P>&nbsp;</P>
<P>PS：TOMCAT有自带DBCP。不过我是自己从jakarta上面下的commons dbcp放到自己的lib里面的，当然，<FONT color=#ff0000>官方doc上面有这样的说明：</FONT></P>
<P><FONT color=#ff0000>Commons-DBCP depends at runtime on commons-pool and commons-collections . 切切！！大多数文章没有提到commons-collections 这个文件！但是这个真的很重要。</FONT></P>
<P><BR>所以记得要把这两项也下回来和dbcp的jar文件一起放进lib才能保证不出错。</P>
<P>总之，认真＋心细，才能更好的解决问题。<BR></P></div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200842110273703</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200842110273703</guid>
    <pubDate>Wed, 21 May 2008 10:27:03 +0800</pubDate>
    <dcterms:modified>2008-05-21T10:27:03+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Struts配置连接池常见错误问题以及解决办法 ]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/51019200842195211275</link>
    <description><![CDATA[<div>1、<SPAN><FONT #ffff00?>Cannot</FONT></SPAN> <SPAN><FONT #55ff55?>create</FONT></SPAN> JDBC driver of class '' for connect URL '' <BR><BR><BR>问题：找不到jdbc驱动，但是提示信息里的class值为null，所以，可以断定Tomcat没有找到Server.xml里的Resource配置信息。可能的原因包括：（1）没有配置Resource；（2）Resource配置信息放置的位置错误。（3）一个不容易发现的错误，driverClassName和url拼写错误。解决办法：确认Resource配置正确，并且必须放在DefaultContext或者Context配置节内。 <BR><BR><BR>2、<SPAN><FONT #ffff00?>Cannot</FONT></SPAN> <SPAN><FONT #55ff55?>create</FONT></SPAN> JDBC driver of class 'xxx' for connect URL '' <BR><BR><BR>解决办法：配置的数据库驱动类名xxx是错误的，检查并修改即可；如果确认正确，那就是找不到驱动库，拷贝一个jar到Tomcat/common/lib中即可。 <BR><BR><BR>3、<SPAN><FONT #ffff00?>Cannot</FONT></SPAN> <SPAN><FONT #55ff55?>create</FONT></SPAN> JDBC driver of class '' for connect URL 'xxx' <BR><BR><BR>解决办法：配置的url字符串语法是错误的，检查后修改即可。 <BR><BR><BR>4、<SPAN><FONT #ffff00?>Cannot</FONT></SPAN> <SPAN><FONT #55ff55?>create</FONT></SPAN> <SPAN><FONT #aaffaa?>PoolableConnectionFactory</FONT></SPAN>, cause: Io 异常: Connection refused <BR><BR><BR>问题：无法创建连接池工厂对象，原因是连接被拒绝。解决办法：检查url字符串，可能服务器地址、端口、数据库名或者数据库实例名等信息错误。修改。 <BR><BR><BR>5、No suitable driver 没有匹配的驱动 <BR><BR><BR>分析：驱动程序配置错误，请确认Tomcat的common/lib子目录中是否有数据库驱动jar。 <BR><BR><BR>6、<SPAN><FONT #ffff00?>Cannot</FONT></SPAN> <SPAN><FONT #55ff55?>create</FONT></SPAN> resource instance无法创建数据源实例 <BR><BR><BR>问题：找不到commons-dbcp-1.1.jar（版本可能不同）解决办法：复制commons-dbcp-1.1.jar库文件到Tomcat/Common/lib子目录中。 <BR><BR><BR>7、root cause： <BR><BR><BR>java.lang.NoClassDefFoundError: org/apache/commons/collections/CursorableLinkedList问题：找不到commons-collections.jar。解决办法：复制commons-collections.jar库文件到Tomcat/Common/lib子目录中。 <BR><BR><BR>8、root cause： <BR><BR><BR>java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool问题：找不到commons-pool-1.1.jar（版本可能不同）。解决办法：复制commons-pool-1.1.jar库文件到Tomcat/Common/lib子目录中。11月13日 21:11 | 添加评论 | 固定链接 | 引用通告 (0) | 记录它 | J2EE究竟是用Struts的连接池好还是用tomcat的连接池好？还有struts的SQL Server连接池怎么配置啊 <BR>我的：在 struts-config里写： <BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>&lt;data-sources&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;data-source&nbsp;key=</SPAN><SPAN><FONT color=#0000ff>"xxxx"</FONT></SPAN><SPAN>&nbsp;&nbsp;type=</SPAN><SPAN><FONT color=#0000ff>"org.apache.commons.dbcp.BasicDataSource"</FONT></SPAN><SPAN>&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"driverClassName"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"com.microsoft.jdbc.sqlserver.SQLServerDriver"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"url"</FONT></SPAN><SPAN>&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=xxxxx"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"maxActive"</FONT></SPAN><SPAN>&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"5"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"username"</FONT></SPAN><SPAN>&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"xx"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"password"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"xx"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"autoCommit"</FONT></SPAN><SPAN>&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"true"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&lt;/data-sources&gt;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>&lt;data-sources&gt;
  &lt;data-source key="xxxx"  type="org.apache.commons.dbcp.BasicDataSource"&gt;
  &lt;set-property property="driverClassName"
   value="com.microsoft.jdbc.sqlserver.SQLServerDriver" /&gt;
  &lt;set-property property="url" 
   value="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=xxxxx"/&gt;
  &lt;set-property property="maxActive" 
   value="5" /&gt;
  &lt;set-property property="username" 
   value="xx" /&gt;
  &lt;set-property property="password"
   value="xx" /&gt;
  &lt;set-property property="autoCommit" 
   value="true" /&gt;
  &lt;/data-source&gt;
&lt;/data-sources&gt;

</PRE><BR>tomcat和struts中写都不好，tomcat中自带的配置连接池只是一个不成熟的项目， <BR><BR>最好只用于学习和小型项目中。struts是表示层框架，更不适于处理底层数据管理。 <BR><BR>在没有其他的连接池（如hibernate自带的；poolman等）时，相对来说还是在tomcat中配置较好 <BR><BR>Tomcat的连接池其实就是dbcp. 我比较过流行的 dbcp,c3p0,proxool 三种连接池，上网搜集了很多资料，发现都是proxool最好。现在hibernate3中已经放弃了对dbcp的集成，我从hibernate的官方网站上看到hibernate的作者说这样做的原因是因为实践过程中发现dbcp不稳定，至于c3p0，我见过国外有几篇文章讲到它的效率不高，不过具体怎样，我没试过。我们公司的维护的一个日访问量达数十万的网站就是用proxool，事实证明很稳定。struts的连接池，我没用过，我觉得连接池的效率跟稳定性是非常关键的，如果在大型应用中，选择连接池应抱谨 <BR><BR><BR>多个连接方法 <BR><BR>------------------------------------ <BR>在一个其于Struts的应用系统的设计过程中，最好能在web/表示层（presentation layer）和你的商务逻辑类（包含所有数据访问操作的层）的中间，定义一个Action类，作为小型的适配器（thin adapter）。 <BR><BR>所以，你可以先定义一些商务API（business API），这些API就是简单的Java类。你可以传递一些参数给这些对象，并从这些对象返回一个Java Bean或者Java Bean的集合。这个Action类负责调用这些对象，并把它们返回的值传递给web/表示层。 <BR><BR>通常，你可以为每一个你需要调用的商务方法/商务类API创建一个Action类。理想情况下，所有的数据库访问代码都被封装进了这些商务API类里，所以Struts并不知道你正在使用的持久层（persistent layer）（甚至都不知道你使用了持久层）。它只需要传递一个主键（Key）或者一个查询参数，然后处理返回的结果bean或者bean集合。这样，你就可以在其他的应用环境里复用这些商务API类，你还可以对这些独立于Struts或HTTP环境的商务API进行单体测试。 <BR><BR>开始的时候，最简单的方法就是设计一个1:1的方案，为你的每一个商务API入口（entry-point）定义一个Action类。当你的经验丰富了以后，你也可以使用DispatchAction组合这些Action类。你甚至可以定义一个简单的"框架"Action，用来调用所有的这些商务类。你可以在contrib目录里找到Scaffold设计的ProcessAction，这是一个"框架"Action的完整实现。使用这种方案可以使用更少的Action类，但你必须对Struts和MVC框架的底层实现有较深的理解。不要害怕在开始的时候定义过多的Action，Struts的配置方案可以给予你充分的自由在以后重构你的设计，因为你可以灵活的改变你的Action类，而不会对应用程序造成影响。 <BR><BR>在理想情况下，商务逻辑层（business logic layer）应该封装所有的数据访问细节，包括数据库连接的获得。但是，一些应用程序的设计要求调用者可以从一个DataSource对象来获得数据库连接。遇到这种情况时，Struts DataSource管理器可以使你在需要的时候配置这些DataSource资源。 <BR><BR>Struts DataSource管理器在Struts配置文件（Struts-config.xml）里定义。这个管理器可以用来分发和配置任何实现了javax.sql.DataSource接口的数据库连接池（connection pool）。如果你的DBMS或者容器内置了符合这些要求的连接池，你可以优先选用它。 <BR><BR><BR>［Jakarta的公共连接池实现 - BasicDataSource］ <BR><BR>如果你的手头没有连接池的本地（native）实现，你可以使用Jakarta提供的公共连接池实现[org.apache.commons.dbcp.BasicDataSource]，它可以和DataSource管理器"合作"的很好。另外，Struts还在它的util包里包含了一个GenericDataSource类，这也是一个连接池实现。但是这只是一个非常简单的实现方案，不推荐使用，因为它可能在Struts的以后版本中被BasicDataSource或其它的数据源实现替换掉。 <BR><BR>下面是一段Struts-config.xml配置文件中的数据源配置（使用GenericDataSource数据源实现），你可以更改相应的设置以适合你自己的系统。 <BR><BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>&lt;!--&nbsp;configuration&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>for</FONT></STRONG></SPAN><SPAN>&nbsp;GenericDataSource&nbsp;wrapper&nbsp;--&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&lt;data-sources&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"autoCommit"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"false"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"description"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"Example&nbsp;Data&nbsp;Source&nbsp;Configuration"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"driverClass"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"org.postgresql.Driver"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"maxCount"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"4"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"minCount"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"2"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"password"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"mypassword"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"url"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"jdbc:postgresql://localhost/mydatabase"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"user"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"myusername"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&lt;/data-sources&gt;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>&lt;!-- configuration for GenericDataSource wrapper --&gt;
&lt;data-sources&gt;
         &lt;data-source&gt;
           &lt;set-property
                 property="autoCommit"
                 value="false"/&gt;
           &lt;set-property
                 property="description"
                 value="Example Data Source Configuration"/&gt;
           &lt;set-property
                 property="driverClass"
                 value="org.postgresql.Driver"/&gt;
           &lt;set-property
                 property="maxCount"
                 value="4"/&gt;
           &lt;set-property
                 property="minCount"
                 value="2"/&gt;
           &lt;set-property
                 property="password"
                 value="mypassword"/&gt;
           &lt;set-property
                 property="url"
                 value="jdbc:postgresql://localhost/mydatabase"/&gt;
           &lt;set-property
                 property="user"
                 value="myusername"/&gt;
         &lt;/data-source&gt;
&lt;/data-sources&gt;

</PRE><BR>使用BasicDataSource数据源实现的配置方案如下： <BR><BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>&lt;data-sources&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;configuration&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>for</FONT></STRONG></SPAN><SPAN>&nbsp;commons&nbsp;BasicDataSource&nbsp;--&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source&nbsp;type=</SPAN><SPAN><FONT color=#0000ff>"org.apache.commons.dbcp.BasicDataSource"</FONT></SPAN><SPAN>&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"driverClassName"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"org.postgresql.Driver"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"url"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"jdbc:postgresql://localhost/mydatabase"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"username"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"me"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"password"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"test"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"maxActive"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"10"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"maxWait"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"5000"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"defaultAutoCommit"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"false"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"defaultReadOnly"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"false"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"validationQuery"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"selecｔ&nbsp;COUNT(*)&nbsp;FROM&nbsp;market"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&lt;/data-sources&gt;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>&lt;data-sources&gt;
        &lt;!-- configuration for commons BasicDataSource --&gt;
        &lt;data-source type="org.apache.commons.dbcp.BasicDataSource"&gt;
                &lt;set-property
                  property="driverClassName"
                  value="org.postgresql.Driver" /&gt;
                &lt;set-property
                  property="url"
                  value="jdbc:postgresql://localhost/mydatabase" /&gt;
                &lt;set-property
                  property="username"
                  value="me" /&gt;
                &lt;set-property
                  property="password"
                  value="test" /&gt;
                &lt;set-property
                  property="maxActive"
                  value="10" /&gt;
                &lt;set-property
                  property="maxWait"
                  value="5000" /&gt;
                &lt;set-property
                  property="defaultAutoCommit"
                  value="false" /&gt;
                &lt;set-property
                  property="defaultReadOnly"
                  value="false" /&gt;
                &lt;set-property
                  property="validationQuery"
                  value="selecｔ COUNT(*) FROM market" /&gt;
        &lt;/data-source&gt;
&lt;/data-sources&gt;
</PRE><BR>注意，你可以在你的应用系统中定义不止一个数据源，你可以根据需要定义多个数据源，并为它们分别起一个逻辑名（logical name）。这样做可以给你的应用系统提供更好的安全性和可测量性（scalability），你还可以定义一个专用于测试的数据源。 <BR><BR>配置好DataSource以后，你就可以在你的应用系统中使用这些数据源了。下面这段代码演示了怎样在Action类的execute方法中通过这些数据源来生成数据库连接。 <BR><BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN><STRONG><FONT color=#7f0055>public</FONT></STRONG></SPAN><SPAN>&nbsp;ActionForward&nbsp;execute( &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionMapping&nbsp;mapping, &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm&nbsp;form, &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest&nbsp;request, &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response) &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>throws</FONT></STRONG></SPAN><SPAN>&nbsp;Exception &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataSource&nbsp;dataSource; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;cnn; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>try</FONT></STRONG></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSource&nbsp;=&nbsp;getDataSource(request); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnn&nbsp;=&nbsp;dataSource.getConnection(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><FONT color=#008200>//&nbsp;数据连接已经建立了，你可以做你想做的事情了 </FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>catch</FONT></STRONG></SPAN><SPAN>&nbsp;(SQLException&nbsp;e) &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getServlet().log(</SPAN><SPAN><FONT color=#0000ff>"处理数据库连接"</FONT></SPAN><SPAN>,&nbsp;e); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>finally</FONT></STRONG></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><FONT color=#008200>//&nbsp;在finally块里包含这些代码 </FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><FONT color=#008200>//&nbsp;用以保证连接最后会被关闭 </FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>try</FONT></STRONG></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnn.close(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>catch</FONT></STRONG></SPAN><SPAN>&nbsp;(SQLException&nbsp;e) &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getServlet().log(</SPAN><SPAN><FONT color=#0000ff>"关闭数据库连接"</FONT></SPAN><SPAN>,&nbsp;e); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>}&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
{
        DataSource dataSource;
        Connection cnn;

        try
        {
                dataSource = getDataSource(request);
                cnn = dataSource.getConnection();
                // 数据连接已经建立了，你可以做你想做的事情了
        }
        catch (SQLException e)
        {
                getServlet().log("处理数据库连接", e);
        }
        finally
        {
                // 在finally块里包含这些代码
                // 用以保证连接最后会被关闭
                try
                {
                        cnn.close();
                }
                catch (SQLException e)
                {
                        getServlet().log("关闭数据库连接", e);
                }
        }
}
</PRE><BR>注意：如果你使用公共的BasicDataSource，你提供给pingQuery属性的查询语句（如果你设置了话）必须至少要能返回一行记录。 <BR><BR>例子：selecｔ COUNT(*) FROM VALIDTABLE <BR><BR>你可以把VALIDTABLE替换成你的数据库中包含的任何有效的表。 <BR><BR>［使用多个数据源］ <BR><BR>如果你需要在模块（Module）中使用多于一个的数据源，你可以在配置文件的&lt;data-source&gt;元素里包含一个key属性。 <BR><BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>&lt;data-source&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source&nbsp;key=</SPAN><SPAN><FONT color=#0000ff>"A"</FONT></SPAN><SPAN>&nbsp;type=</SPAN><SPAN><FONT color=#0000ff>"org.apache.commons.dbcp.BasicDataSource"</FONT></SPAN><SPAN>&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…属性配置略,&nbsp;同上… &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data-source&nbsp;key=</SPAN><SPAN><FONT color=#0000ff>"B"</FONT></SPAN><SPAN>&nbsp;type=</SPAN><SPAN><FONT color=#0000ff>"org.apache.commons.dbcp.BasicDataSource"</FONT></SPAN><SPAN>&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…属性配置略,&nbsp;同上… &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&lt;/data-source&gt;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>&lt;data-source&gt;
        &lt;data-source key="A" type="org.apache.commons.dbcp.BasicDataSource"&gt;
                …属性配置略, 同上…
        &lt;/data-source&gt;
        &lt;data-source key="B" type="org.apache.commons.dbcp.BasicDataSource"&gt;
                …属性配置略, 同上…
        &lt;/data-source&gt;
&lt;/data-source&gt;

</PRE><BR>你代码里，你可以通过这些key获得不同的数据源。代码如下： <BR><BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>… &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>try</FONT></STRONG></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>{ &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSourceA&nbsp;=&nbsp;getDataSource(request,&nbsp;</SPAN><SPAN><FONT color=#0000ff>"A"</FONT></SPAN><SPAN>); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataSourceB&nbsp;=&nbsp;getDataSource(request,&nbsp;</SPAN><SPAN><FONT color=#0000ff>"B"</FONT></SPAN><SPAN>); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>…&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>…
try
{
        dataSourceA = getDataSource(request, "A");
        dataSourceB = getDataSource(request, "B");
…
</PRE><BR><BR>你可以根据需要为每一个模块设置多个数据源。但同一模块里每个数据源的key属性必须唯一，因为Struts模块系统是以每一个模块为单位管理命名空间的。 <BR><BR>发表于 @ 2006年10月27日 12:49 PM | 评论 (0) <BR>Struts数据源配置过程(不在Action里连接) JDBC数据源(Data Source)的使用,简化了数据库的连接过程.Struts中使用JDBC 2.0标准扩展包中的javax.sql.DataSource接口来实现数据源的。扩展包是jdbc2_0-stdext.jar。，在jdk1.4后版本包含此扩展包。 例如下面的例子。数据库名“classuser”，表：“classuser”。在Struts配置文件“struts-config.xml中”配置Struts数据源，这些数据源由ActionServlet负责管理。 以下代码是Struts-config.xml的配置。 <BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN>&lt;struts-config&gt;&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&lt;data-sources&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;data-source&nbsp;key=</SPAN><SPAN><FONT color=#0000ff>"oracleDB1"</FONT></SPAN><SPAN>&nbsp;type=</SPAN><SPAN><FONT color=#0000ff>"org.apache.commons.dbcp.BasicDataSource"</FONT></SPAN><SPAN>&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"driverClassName"</FONT></SPAN><SPAN>&nbsp; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"com.microsoft.jdbc.sqlserver.SQLServerDriver"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"url"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=classuser;"</FONT></SPAN><SPAN>&nbsp;/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"maxActive"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"5"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"username"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"sa"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"password"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>""</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=</SPAN><SPAN><FONT color=#0000ff>"autoCommit"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;value=</SPAN><SPAN><FONT color=#0000ff>"true"</FONT></SPAN><SPAN>/&gt; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&lt;/data-source&gt; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&lt;/data-sources&gt;&nbsp;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>&lt;struts-config&gt; 
&lt;data-sources&gt;
  &lt;data-source key="oracleDB1" type="org.apache.commons.dbcp.BasicDataSource"&gt;
   &lt;set-property property="driverClassName" 
    value="com.microsoft.jdbc.sqlserver.SQLServerDriver" /&gt;
   &lt;set-property property="url"
    value="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=classuser;" /&gt;
   &lt;set-property property="maxActive"
    value="5"/&gt;
   &lt;set-property property="username"
    value="sa"/&gt;
   &lt;set-property property="password"
    value=""/&gt;
   &lt;set-property property="autoCommit"
    value="true"/&gt;
  &lt;/data-source&gt;
 &lt;/data-sources&gt; 
</PRE><BR>定义模型类DBUser，在该类中封装了与数据库操作相关的业务逻辑。 <BR>
<DIV>
<DIV>
<DIV>Java代码 <A title=复制代码 href="http://peter-kong.javaeye.com/blog/39307#" CopyToClipboard?,this);return false;?><IMG alt=复制代码 src="http://peter-kong.javaeye.com/images/icon_copy.gif" _counted="undefined"></A></DIV></DIV>
<OL>
<LI><SPAN><SPAN><STRONG><FONT color=#7f0055>package</FONT></STRONG></SPAN><SPAN>&nbsp;classmate; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>import</FONT></STRONG></SPAN><SPAN>&nbsp;javax.sql.DataSource; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>import</FONT></STRONG></SPAN><SPAN>&nbsp;java.sql.Connection; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>import</FONT></STRONG></SPAN><SPAN>&nbsp;java.sql.Statement; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>import</FONT></STRONG></SPAN><SPAN>&nbsp;java.sql.ResultSet; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN></SPAN><SPAN><STRONG><FONT color=#7f0055>import</FONT></STRONG></SPAN><SPAN>&nbsp;java.sql.SQLException;</SPAN><SPAN><STRONG><FONT color=#7f0055>public</FONT></STRONG></SPAN><SPAN>&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>class</FONT></STRONG></SPAN><SPAN>&nbsp;DBUser&nbsp;{&nbsp;DataSource&nbsp;dataSource; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>public</FONT></STRONG></SPAN><SPAN>&nbsp;DBUser(DataSource&nbsp;dataSource)&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>this</FONT></STRONG></SPAN><SPAN>.dataSource&nbsp;=&nbsp;dataSource; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>public</FONT></STRONG></SPAN><SPAN>&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>boolean</FONT></STRONG></SPAN><SPAN>&nbsp;checkUser(String&nbsp;name,String&nbsp;psw)&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>throws</FONT></STRONG></SPAN><SPAN>&nbsp;Exception{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;connect&nbsp;=&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>null</FONT></STRONG></SPAN><SPAN>; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;String&nbsp;strSql; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;ResultSet&nbsp;rs; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>boolean</FONT></STRONG></SPAN><SPAN>&nbsp;result=</SPAN><SPAN><STRONG><FONT color=#7f0055>false</FONT></STRONG></SPAN><SPAN>; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strSql&nbsp;=&nbsp;</SPAN><SPAN><FONT color=#0000ff>"select&nbsp;*&nbsp;from&nbsp;classuser&nbsp;where&nbsp;username='"</FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;name&nbsp;+&nbsp;</SPAN><SPAN><FONT color=#0000ff>"'&nbsp;and&nbsp;password='"</FONT></SPAN><SPAN>&nbsp;+&nbsp;psw&nbsp;+&nbsp;</SPAN><SPAN><FONT color=#0000ff>"'"</FONT></SPAN><SPAN>; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>try</FONT></STRONG></SPAN><SPAN>&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;connect&nbsp;=&nbsp;dataSource.getConnection(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;Statement&nbsp;stmt&nbsp;=&nbsp;connect.&lt;SPAN&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>class</FONT></STRONG></SPAN><SPAN>=hilite2&gt;create&lt;/SPAN&gt;Statement(); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;rs&nbsp;=&nbsp;stmt.executeQuery(strSql); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>if</FONT></STRONG></SPAN><SPAN>&nbsp;(&nbsp;rs.next())&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;result=</SPAN><SPAN><STRONG><FONT color=#7f0055>true</FONT></STRONG></SPAN><SPAN>; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>catch</FONT></STRONG></SPAN><SPAN>(SQLException&nbsp;ex)&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;ex.printStackTrace(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>finally</FONT></STRONG></SPAN><SPAN>{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>if</FONT></STRONG></SPAN><SPAN>(connect!=</SPAN><SPAN><STRONG><FONT color=#7f0055>null</FONT></STRONG></SPAN><SPAN>) &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;connect.close(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>return</FONT></STRONG></SPAN><SPAN>&nbsp;result; &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>改造Action&nbsp;Bean类LoginAction，在其中使用前面配置的数据源oracleDB1。&nbsp;ServletContext&nbsp;context&nbsp;=&nbsp;servlet.getServletContext(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;DataSource&nbsp;dataSource&nbsp;=&nbsp;(DataSource)context.getAttribute(</SPAN><SPAN><FONT color=#0000ff>"oracleDB1"</FONT></SPAN><SPAN>); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DBUser&nbsp;dbuser&nbsp;=&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>new</FONT></STRONG></SPAN><SPAN>&nbsp;DBUser(dataSource); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpSession&nbsp;session&nbsp;=&nbsp;request.getSession(); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>if</FONT></STRONG></SPAN><SPAN>&nbsp;(!dbuser.checkUser(name,psw))&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;ActionMessages&nbsp;errors&nbsp;=&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>new</FONT></STRONG></SPAN><SPAN>&nbsp;ActionMessages(); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;errors.add(ActionMessages.GLOBAL_MESSAGE, &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>new</FONT></STRONG></SPAN><SPAN>&nbsp;ActionMessage(</SPAN><SPAN><FONT color=#0000ff>"label.deny"</FONT></SPAN><SPAN>)); &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>if</FONT></STRONG></SPAN><SPAN>&nbsp;(!errors.isEmpty())&nbsp;{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;saveErrors(request,&nbsp;errors); &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>return</FONT></STRONG></SPAN><SPAN>&nbsp;&nbsp;mapping.findForward(</SPAN><SPAN><FONT color=#0000ff>"failed"</FONT></SPAN><SPAN>);&nbsp;&nbsp;</SPAN><SPAN><FONT color=#008200>//登陆失败 </FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>else</FONT></STRONG></SPAN><SPAN>{ &nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN><STRONG><FONT color=#7f0055>return</FONT></STRONG></SPAN><SPAN>&nbsp;(mapping.findForward(</SPAN><SPAN><FONT color=#0000ff>"successed"</FONT></SPAN><SPAN>));</SPAN><SPAN><FONT color=#008200>//登陆成功&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN><SPAN>&nbsp;&nbsp;</SPAN></SPAN> 
</LI><LI><SPAN>&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>&nbsp;} &nbsp;&nbsp;</SPAN> 
</LI><LI><SPAN>}&nbsp;&nbsp;&nbsp;</SPAN></LI></OL></DIV><PRE none?>package classmate;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;public class DBUser { DataSource dataSource;
 
 public DBUser(DataSource dataSource) {
  
   this.dataSource = dataSource;
 }
 
 
 public boolean checkUser(String name,String psw) throws Exception{
        Connection connect = null;
  String strSql;
  ResultSet rs;
  boolean result=false;
        strSql = "select * from classuser where username='"
     + name + "' and password='" + psw + "'";
  try {
   connect = dataSource.getConnection();
   Statement stmt = connect.<SPAN><FONT #55ff55?>create</FONT></SPAN>Statement();
   rs = stmt.executeQuery(strSql);
   if ( rs.next()) {
    result=true;
   }
  }
  catch(SQLException ex) {
   ex.printStackTrace();
  }
  finally{
   if(connect!=null)
    connect.close();
  }
  return result;
 
 }
 
}
改造Action Bean类LoginAction，在其中使用前面配置的数据源oracleDB1。 ServletContext context = servlet.getServletContext();
  DataSource dataSource = (DataSource)context.getAttribute("oracleDB1");
      
        DBUser dbuser = new DBUser(dataSource);
        HttpSession session = request.getSession();
       
        if (!dbuser.checkUser(name,psw)) {
   ActionMessages errors = new ActionMessages();
   errors.add(ActionMessages.GLOBAL_MESSAGE,
    new ActionMessage("label.deny"));
    
   if (!errors.isEmpty()) {
    saveErrors(request, errors);
   }
     return  mapping.findForward("failed");  //登陆失败
  }
  else{
       return (mapping.findForward("successed"));//登陆成功     
  } 
 }
} 
</PRE><BR>此外，在Struts架构中，根据需要也允许在配置文件中声明多个数据源，此时需要使用“key”属性为每一个数据源分配一个唯一的key值，标示特定数据源 </div>]]></description>
	    <author><![CDATA[Shawn]]></author>
	    <comments>http://zjuoliver.blog.163.com/blog/static/51019200842195211275</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zjuoliver.blog.163.com/blog/static/51019200842195211275</guid>
    <pubDate>Wed, 21 May 2008 09:52:11 +0800</pubDate>
    <dcterms:modified>2008-05-21T09:52:11+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[C# DataSet中的表“关系”]]></title>	
    <link>http://zjuoliver.blog.163.com/blog/static/510192008454351793</link>
    <description><![CDATA[<div><P dir=ltr style="TEXT-INDENT: 2em; MARGIN-RIGHT: 0px">DataSet是ADO.Net中相当重要的数据访问模型。有一个很大的优点是可以记录多个表之间的关系。有点类似与数据库的外键。这样一来，给我们数据查询带来很大方便。可以先用Access来预览一下建立关系的好处，在Access07中，两个有关系的表之间可以方便的引用，如图</P>
<P dir=ltr style="TEXT-