<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Ben.Sin</title>
    <description>个性开朗，喜好体育运动。</description>
    <link>http://ben-sin.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>猪的10万个为什么</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/209960" style="color:red;">http://ben-sin.javaeye.com/blog/209960</a>&nbsp;
          发表时间: 2008年06月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span class="bold">为什么总是猪</span>
<br /></p>
<div class="t_msgfont" id="message1259980">Version 1.0（广为流传的版本）&nbsp; &nbsp; <br />
<br />
&nbsp;&nbsp;讲述者：什么东西最喜欢问为什么？（神秘的模样） <br />
&nbsp;&nbsp;回答者：不知道。（很好奇的样子） <br />
&nbsp;&nbsp;讲述者：猪！（肯定果断） <br />
&nbsp;&nbsp;回答者：为什么？（天真加可爱） <br />
&nbsp;&nbsp;讲述者：相当明显，当然是猪才最喜欢问为什么啦。（故弄玄虚的模样） <br />
&nbsp;&nbsp;回答者：为什么？（还是不明白）&nbsp; </div>
<div class="t_msgfont"><br />
<br />
&nbsp;&nbsp;Version 2.0（第一次升级）&nbsp; <br />
<br />
&nbsp;&nbsp;讲述者：选择题，考考大家！（逗起兴趣） <br />
&nbsp;&nbsp;大家：快快！什么题？（从工作的疲倦中得救，巴不得赶快轻松） <br />
&nbsp;&nbsp;讲述者：以下动物，哪一个最喜欢问为什么？ <br />
&nbsp;&nbsp;　　　　A 兔子 <br />
&nbsp;&nbsp;　　　　B 松鼠 <br />
&nbsp;&nbsp;　　　　C 狗 <br />
&nbsp;&nbsp;　　　　D 猪 <br />
&nbsp;&nbsp;回答者甲：D！（事先买通的掮客，回答时轻松加愉快） <br />
&nbsp;&nbsp;讲述者：对，没错。（惊异的样子，好像在问，你怎么能这么快答出这么困难的问题，他们怎么就答不出来） <br />
&nbsp;&nbsp;其他参与者：为什么？ <br />
&nbsp;&nbsp;讲述者：问他\\她吧。（指指回答者甲） <br />
&nbsp;&nbsp;其他参与者：嘿，为什么？为什么？（围绕回答者甲）&nbsp; </div>
<div class="t_msgfont"><br />
<br />
&nbsp;&nbsp;Version 2.1（2.0的细微升级）&nbsp; <br />
<br />
&nbsp;&nbsp;讲述者：来来来，做道选择题。 <br />
&nbsp;&nbsp;大家：什么题啊？（好奇） <br />
&nbsp;&nbsp;讲述者：请指出以下动物最笨的动物是什么？（姜太公等鱼来上钩） </div>
<div class="t_msgfont">&nbsp; 　　　　A 驴 <br />
&nbsp;&nbsp;　　　　B 骡 <br />
&nbsp;&nbsp;　　　　C 猪 <br />
&nbsp;&nbsp;　　　　D 鹅 <br />
&nbsp;&nbsp;大家努力思考&hellip;&hellip; <br />
&nbsp;&nbsp;讲述者：当然是猪了！（指点迷津状） <br />
&nbsp;&nbsp;大家：为什么？ <br />
&nbsp;&nbsp;讲述者：因为，最笨的动物肯定这儿也不明白，那儿也不明白，所以，就总喜欢问：&ldquo;为什么？为什么？&rdquo;。而猪这种动物，就最喜欢问为什么，那当然是猪最笨了。 <br />
&nbsp;&nbsp;大家：&hellip;&hellip;（拳头朝他猛砸）&nbsp; <br />
</div>
<div class="t_msgfont"><br />
</div>
<div class="t_msgfont"><br />
&nbsp;&nbsp;Version 3.0（童话故事版本） <br />
<br />
&nbsp;&nbsp;讲述者开始讲故事&hellip;&hellip;（该作呆痴状的地方，一定表现出呆痴状，以便在欢笑中分散听众的注意力） <br />
&nbsp;&nbsp;　　费尔斯森林里住着各种各样的动物，大家和平共处，高高兴兴地生活。但是有一天，大家却开始争吵，争论的核心就是：谁是森林里最聪明的动物？由于争
论非常激烈，谁都不承认自己比别人笨，所以最后决定举行费尔斯森林智力大赛。因为要控制参赛人数，规定各种族参赛动物只能派一位代表参加，到时谁的代表获
胜，大家就同意谁是最聪明的。 <br />
<br />
&nbsp;&nbsp;　　比赛消息一下来，各种族便忙着开始选拔自己的代表。猪也想参加这个比赛，因为在人们的心目中，老是认为他们是最笨的，他们对这种偏见和种族歧视相
当不满，猪们一致认为这是他们澄清事实的一个绝好机会，他们要让大家看看，从猪八戒在高老庄骗到漂亮姑娘的显赫事实开始，猪就是很聪明的。 <br />
<br />
&nbsp;&nbsp;　　猪们经过仔细讨论，最后决定派小猪&ldquo;笨笨&rdquo;参赛。因为笨笨从小就特别好学，不懂的东西总及时问，所以学得特别快，&ldquo;我的哥哥叫我弟弟，我却要叫他
哥哥，为&hellip;&hellip;什&hellip;&hellip;么？&rdquo;，&ldquo;天上的鸟能飞，猪却不能飞，为&hellip;&hellip;什&hellip;&hellip;么？&rdquo;，&ldquo;猪八戒不叫猪九戒，为&hellip;&hellip;什&hellip;&hellip;么？&rdquo;，&ldquo;小姑娘喜欢刘德华不喜欢我，
为&hellip;&hellip;什&hellip;&hellip;么？&rdquo;，&ldquo;&hellip;&hellip;为&hellip;&hellip;什&hellip;&hellip;么？&rdquo;，现在让笨笨写本叫《小猪笨笨之百万个为什么》，我想问题应该不大。总之，大家认为，让学问渊博的笨笨参
赛，为猪群昭雪简直是十拿九稳。 <br />
<br />
&nbsp;&nbsp;　　到了比赛那天，各种动物到齐，赛场热闹非凡，老虎裁判主持比赛，比赛方式为抢答。 <br />
&nbsp;&nbsp;　　&ldquo;第一题，世界上最深的淡水湖是什么湖？&rdquo; <br />
&nbsp;&nbsp;　　&ldquo;贝加尔湖&rdquo;，笨笨抢道。 <br />
<br />
&nbsp;&nbsp;　　&ldquo;第二题，圆周率约为多少？&rdquo; <br />
&nbsp;&nbsp;　　&ldquo;3.14&rdquo;，笨笨不失时机地答道。 <br />
<br />
&nbsp;&nbsp;　　&ldquo;第三题，DNA翻译成中文是什么？&rdquo; <br />
&nbsp;&nbsp;　　&ldquo;脱氧核糖核酸&rdquo;，笨笨再次胜出。 <br />
<br />
&nbsp;&nbsp;　　三道题，笨笨连续得分，大获全胜。 <br />
&nbsp;&nbsp;　　围观的猪群爆发出阵阵喝彩，在场的其他动物也不得不赞叹。 <br />
<br />
&nbsp;&nbsp;　　最后，老虎裁判示意大家安静。 <br />
&nbsp;&nbsp;　　&ldquo;现在，我公布比赛的结果，事实非常明显，小猪笨笨反应敏捷，机智过人，三道题全部答对，但是，它决不能成为此次比赛的冠军！！！&rdquo; <br />
<br />
&nbsp;&nbsp;　　（现在，等着听众说为什么）</div>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/209960#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 30 Jun 2008 23:24:05 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/209960</link>
        <guid>http://ben-sin.javaeye.com/blog/209960</guid>
      </item>
      <item>
        <title>利用API函数修改PB自带toolbar的字体</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/209739" style="color:red;">http://ben-sin.javaeye.com/blog/209739</a>&nbsp;
          发表时间: 2008年06月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>改变PB自带工具栏的字体﹐不要自定义控件做工具栏。<br />
<br />
function long FN_ToolBarSetFont(long unknown,string fontname,long fontsize,long unknown1,string str) library &quot;pbvm100.dll&quot;<br />
用这个方法可以改<br />
<br />
声明<br />
function long FindWindowExA( long hParent, long hChildAfter, String lpszClass, String lpszWindow ) Library &quot;user32.dll&quot;<br />
function long GetWindowLongA( long hWnd, integer index) Library &quot;user32.dll&quot;<br />
function long FN_ToolBarSetFont(long unknown,string fontname,long fontsize,long unknown1,string str) library &quot;pbvm80.dll&quot;</p>
<p>&nbsp;</p>
<p>修改代码</p>
<p>long ll_null, ll_hwndToolBar, ll_hwnd, ll_pToolbar<br />
string ls_windowName<br />
<br />
SetNull(ls_windowName)<br />
SetNull(ll_null)<br />
<br />
try<br />
&nbsp;&nbsp;&nbsp; ll_hwnd = Handle(awin)<br />
&nbsp;&nbsp;&nbsp; ll_hwndToolBar = FindWindowEXA(ll_hwnd, ll_NULL, IS_TOOLBARCLASSNAME, ls_WindowName )<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; if ll_hwndToolBar &gt; 0 then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ll_pToolbar = GetWindowLongA(ll_hwndToolBar,0)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FN_ToolBarSetFont(ll_pToolbar, aFontName, aFontSize, 0, space(aTextSize))<br />
&nbsp;&nbsp;&nbsp; end if<br />
catch(throwable ex)<br />
&nbsp;&nbsp;&nbsp; SignalError(-1, &quot;Call API function to set toolbar font failed.&quot;)<br />
&nbsp;&nbsp;&nbsp; return -1<br />
end try</p>
<p><br />
如果是pb9的话IS_TOOLBARCLASSNAME = &quot;FNFIXEDBAR90&quot;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/209739#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 30 Jun 2008 13:48:26 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/209739</link>
        <guid>http://ben-sin.javaeye.com/blog/209739</guid>
      </item>
      <item>
        <title>[PB]读取下拉框的显示值</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/200419" style="color:red;">http://ben-sin.javaeye.com/blog/200419</a>&nbsp;
          发表时间: 2008年06月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>DW(数据窗口)作为下拉方式存在，可以设置datavalue和displayvalue。</p>
<p>datavalue是column的实际数值，而我们看到的是displayvalue，当然可以设置两个都相同</p>
<p>&nbsp;</p>
<p>如果要取得datavalue很简单，dw_control.getItemXXX(row, column_name)</p>
<p>(XXX为column的类型，比如String, Number等等)</p>
<p>&nbsp;</p>
<p>如果要取得显示值得时候就相对麻烦些(datavalue跟displayvalue不一样)</p>
<p>方法有两种，一种是getChild方法取得下拉句柄，并顺藤摸瓜取得。这个方法略显麻烦，但结果是肯定的</p>
<pre name="code" class="java">DataWindowChild ldw_child
String ls_dataCol, ls_displayCol
String ls_dataValue, ls_displayValue
long ll_row

if dw_control.getChild(col_name, ref ldw_child) = 1 then
    // 取得当前行的datavalue
    ls_dataValue = dw_control.getItemString(dw_control.getRow(), col_name)
    
    // 取得下拉dw对应的datacolumn和displaycolumn
    ls_dataCol = dw_control.describe(col_name + &quot;.dddw.datacolumn&quot;)
    ls_displayCol = dw_control.describe(col_name + &quot;.dddw.displayColumn&quot;)

    // 查找对应资料的位置
    ll_row = ldw_child.find(ls_dataCol + &quot; = '&quot; + ls_dataValue + &quot;'&quot;, 1, ldw_child.rowCount())

    // 取得显示值
    if ll_row &gt; 0 then
        ls_displayValue = ldw_child.getItemString(ll_row, ls_displayCol)
    end if

end if</pre>
&nbsp;
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>另外一种利用dw内部函数取得，这个就显得相当简洁</p>
<pre name="code" class="java">long ll_row

ll_row = dw_control.getRow()
dw_control.Describe(&quot;Evaluate('lookupdisplay(col_name)',&quot;+String(ll_row)+&quot;)&quot;)</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/200419#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 05 Jun 2008 10:56:51 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/200419</link>
        <guid>http://ben-sin.javaeye.com/blog/200419</guid>
      </item>
      <item>
        <title>JS-纯html传递参数例子</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/197469" style="color:red;">http://ben-sin.javaeye.com/blog/197469</a>&nbsp;
          发表时间: 2008年05月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>利用javascript的正则表达式来检索当前url上的参数信息，来达到传递参数的目的。</p>
<p>JS代码是网上找到的，还有一些通过分析字符串来获得，但我觉得这个比较简洁一点。</p>
<p>以下是一个小例子的代码</p>
<pre name="code" class="html">&lt;html&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;html/text; charset=utf-8&quot;/&gt;
	&lt;title&gt;JS get Parameter&lt;/title&gt;
	&lt;script src=&quot;resource/js/param.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;user&quot; /&gt;&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;password&quot; /&gt;&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;sysno&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	var LocString=String(window.document.location.href);
	
	function getQueryStr(str){
		var rs = new RegExp(&quot;(^|)&quot;+str+&quot;=([^\&amp;]*)(\&amp;|$)&quot;,&quot;gi&quot;).exec(LocString), tmp;
	
		if(tmp=rs){
			return tmp[2];
		}
	
		// parameter cannot be found
		return &quot;&quot;;
	}

	document.getElementById(&quot;user&quot;).value = getQueryStr(&quot;user&quot;);
	document.getElementById(&quot;password&quot;).value = getQueryStr(&quot;password&quot;);
	document.getElementById(&quot;sysno&quot;).value = getQueryStr(&quot;sysno&quot;);
&lt;/script&gt;
&lt;/html&gt;</pre>
<p>&nbsp;通过test.html?user=abc&amp;password=123&amp;sysno=001的测试结果来看，截获参数的目的达到了</p>
<p>&nbsp;</p>
<p>具体的原理没有仔细研究，希望明白的能指点一二</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/197469#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 27 May 2008 15:05:02 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/197469</link>
        <guid>http://ben-sin.javaeye.com/blog/197469</guid>
      </item>
      <item>
        <title>JSP学习笔记-JSP002 中文字符问题</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/197121" style="color:red;">http://ben-sin.javaeye.com/blog/197121</a>&nbsp;
          发表时间: 2008年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>案例：静态html设置了utf-8格式，title还有keywords都有中文，而且有的时候是繁体的，比如一下片断</p>
<pre name="code" class="html">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;中文标题&lt;/title&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
	&lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot;/&gt;
	&lt;meta content=&quot;中文描述&quot; name=&quot;description&quot;/&gt;
	&lt;meta content=&quot;关键字&quot; name=&quot;keywords&quot;/&gt;
&lt;/head&gt;
&lt;body&gt;
...
&lt;/body&gt;
&lt;/html&gt; </pre>
<p>&nbsp;但是有时会出现很奇怪的现象-页面无法显示，选择源文件确切看到代码是存在的。</p>
<p>&nbsp;</p>
<p>解决方法：将字符集的声明放到最前面，例如</p>
<pre name="code" class="html">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
	&lt;title&gt;中文标题&lt;/title&gt;
	&lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot;/&gt;
	&lt;meta content=&quot;中文描述&quot; name=&quot;description&quot;/&gt;
	&lt;meta content=&quot;关键字&quot; name=&quot;keywords&quot;/&gt;
&lt;/head&gt;
&lt;body&gt;
...
&lt;/body&gt;
&lt;/html&gt; 
</pre>
<p>&nbsp;这样就可以很好地将页面信息显示出来了</p>
<p>&nbsp;</p>
<p>个人理解：JSP最终生成的也是html代码然后下载到客户端由浏览器解析显示。由于html是由上而下解析的，案例中字符集声明在head的第二行，第一行的title所包含的中文被浏览器的默认字符集解析，如果是繁体而游览器默认字符集不是big5、或者简体而浏览器默认字符集不是gb2312的时候，就会出现了空白的页面。</p>
<p>&nbsp;</p>
<p>如有错漏的请指正，万分感谢。</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/197121#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 May 2008 16:20:30 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/197121</link>
        <guid>http://ben-sin.javaeye.com/blog/197121</guid>
      </item>
      <item>
        <title>SFTP上传和下载</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/190247" style="color:red;">http://ben-sin.javaeye.com/blog/190247</a>&nbsp;
          发表时间: 2008年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>维护一个旧项目(eJMS)，先前从JDK1.3升级到1.5，后来还要从FTP转换到SFTP</p>
<p>转SFTP用了一个开源的jftp.jar包支持，download的代码</p>
<pre name="code" class="java">public byte[] downloadFile(String remoteDir, String fileName){
	Session session;
	Channel channel;
	JSch jsch = new JSch();
		
	try {
		session = jsch.getSession(this.userName, this.hostName, this.port);
		System.out.println(&quot;Get Session : &quot; + session);
		session.setPassword(password);
		System.out.println(&quot;set password ... &quot;);
		session.setUserInfo(defaultUserInfo);
		System.out.println(&quot;set user info ... &quot;);
		session.connect();
		System.out.println(&quot;connected session : sftp://&quot; + this.hostName + &quot;:&quot; + this.port);
		channel = session.openChannel(&quot;sftp&quot;);
		System.out.println(&quot;opened channel ... &quot;);
		channel.connect();
		System.out.println(&quot;connected channel ... &quot;);
		ChannelSftp c = (ChannelSftp)channel;
		System.out.println(&quot;remoted channel ... &quot;);
		
		c.cd(remoteDir);
		Vector getFile = new Vector();
		InputStream in = c.get(fileName);
		int length = 0;
		int totalLength = 0;
		
		byte[] buffer = new byte[1024];
		while ((length = in.read(buffer)) &gt; 0){
			byte[] tmpBuffer = new byte[length];
			System.arraycopy(buffer, 0, tmpBuffer, 0, length);
			getFile.addElement(tmpBuffer);
			totalLength = totalLength + length;
		}
		in.close();
		
		byte[] result = new byte[totalLength];
		int pos = 0;
		for (int i = 0; i &lt; getFile.size(); i ++){
			byte[] tmpBuffer = (byte[])getFile.elementAt(i);
			System.arraycopy(tmpBuffer, 0, result, pos, tmpBuffer.length);
			pos = pos + tmpBuffer.length;
		}
		getFile.clear();
		
		System.out.println(&quot;downloaded file '&quot; + remoteDir + &quot;\\&quot; + fileName + &quot;'&quot;);
		
		c.disconnect();
		System.out.println(&quot;disconnected channel ... &quot;);
		
		session.disconnect();
		System.out.println(&quot;disconnected session ... &quot;);
		
		return result;
	} catch (JSchException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SftpException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	return null;
}</pre>
<p>&nbsp;调用download的方法</p>
<pre name="code" class="java">public byte[] getFile(String server, String user, String pwd, String tar_dir, String filename)	{
	if(server!=null &amp;&amp; user != null &amp;&amp; pwd!=null) {
		SFtp sftp = new SFtp(server, user, pwd);
		return sftp.downloadFile(tar_dir, filename);
	} else {
	    return null;
	}
}</pre>
<p>&nbsp;上传的代码</p>
<pre name="code" class="java">public boolean uploadFile(String remoteDir, String fileName, byte[] data){
	Session session;
	Channel channel;
	JSch jsch = new JSch();

	try {
		session = jsch.getSession(this.userName, this.hostName, this.port);
		System.out.println(&quot;Get Session : &quot; + session);
		session.setPassword(password);
		System.out.println(&quot;set password ... &quot;);
		session.setUserInfo(defaultUserInfo);
		System.out.println(&quot;set user info ... &quot;);
		session.connect();
		System.out.println(&quot;connected session : sftp://&quot; + this.hostName + &quot;:&quot; + this.port);

		channel = session.openChannel(&quot;sftp&quot;);
		System.out.println(&quot;opened channel ... &quot;);
		channel.connect();
		System.out.println(&quot;connected channel ... &quot;);
		ChannelSftp c = (ChannelSftp)channel;
		System.out.println(&quot;remoted channel ... &quot;);
		
		c.cd(remoteDir);
		OutputStream out = c.put(fileName);
		int length = data.length;
		
		out.write(data, 0, length);
		out.flush();
		out.close();
		
		System.out.println(&quot;uploaded file to '&quot; + remoteDir + &quot;\\&quot; + fileName + &quot;'&quot;);
		
		c.disconnect();
		System.out.println(&quot;disconnected channel ... &quot;);
		
		session.disconnect();
		System.out.println(&quot;disconnected session ... &quot;);
		
		return true;
	} catch (JSchException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (SftpException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	return false;
}</pre>
<p>&nbsp;调用上传的方法的部分代码</p>
<pre name="code" class="java">public int getUploadFile(HttpServletRequest request, int maxSize){ 
	maxsize = maxSize;
	int length=0;

	try {
	        // Setup incoming data
		multi = new MultipartRequest(request, 1024*1024*10);
		int flength = multi.checkFileSize();
		    
		// check file's length
		if(flength &gt; (maxSize * 1024)){
		    	return -1;
		}

    		multi.getFileData();
	    	Hashtable all=multi.getAllFile();
		Enumeration files = all.elements();
		    
		while(files.hasMoreElements()) {
    			UploadedFile up = (UploadedFile)files.nextElement();
    			
    			// upload file must be *.doc
        	        if (!up.getFilesystemName().toLowerCase().endsWith(&quot;.doc&quot;)){
                		return -2;
	                }
			byte[] data = up.getData();
			log(server+&quot;, &quot;+user+&quot;,&quot;+pwd+&quot;,&quot;+tar_dir+&quot;,&quot;+filename);
			    
			SFtp sftp = new SFtp(server, portNo, user, pwd);
			
			if (sftp.uploadFile(tar_dir, filename, data)  == true){
				    length = length + data.length;
			}else{
				log(&quot;ftp file error:&quot; + filename);
			}
    		}
    	} catch (Exception e) {
    		log(e, &quot;upload error&quot;); 
    		return 0;
        }
	return length; 
}</pre>
<p>上传的时候直接call JavaBean就可以了</p>
<p>下载的时候由于返回的是byte[]，所以call JavaBean之后还需要返回给客户端</p>
<p>ServletOutputStream outs = response.getOutputStream();</p>
<p>outs.write(data);</p>
<p>outs.flush();</p>
<p>outs.close();</p>
<p>&nbsp;</p>
<p>这里还要注意一个问题，当你引入一些package或者其他定义之类的代码，它们之间不可以存在有空格</p>
<p>比如这样没有问题</p>
<p>&lt;%%&gt;&lt;%%&gt;&lt;%</p>
<p>...</p>
<p>%&gt;</p>
<p>但是如果是</p>
<p>&lt;%%&gt;</p>
<p>&lt;%</p>
<p>...</p>
<p>%&gt;</p>
<p>就会抛出异常</p>
<p>2008-5-6 15:17:01 org.apache.catalina.core.StandardWrapperValve invoke<br />
严重: Servlet.service() for servlet jsp threw exception<br />
java.lang.IllegalStateException: getOutputStream() has already been called for this response</p>
<p>....</p>
<p>&nbsp;</p>
<p>这个问题我是不怎么好理解...<img src="../../images/smiles/icon_sad.gif" alt="" />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/190247#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 06 May 2008 15:24:38 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/190247</link>
        <guid>http://ben-sin.javaeye.com/blog/190247</guid>
      </item>
      <item>
        <title>PB-数据窗口关闭事件ID</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/187728" style="color:red;">http://ben-sin.javaeye.com/blog/187728</a>&nbsp;
          发表时间: 2008年04月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>数据窗口根窗口一样，有titlebar, control menu, minBox, maxbox</p>
<p>当点击关闭安钮的，pb似乎没有提供这样的事件ID，pbm_close/pbm_closequery都不是</p>
<p>尽管如此，我们还有功能强大的other事件，我们只需要在other事件写上</p>
<p>if message.number = 24 then</p>
<p>&nbsp;&nbsp;&nbsp; messagebox('Close', 'Close datawindow')</p>
<p>end if</p>
<p>return 0</p>
<p>当你关闭的时候就会看到一个提示框，证明你已经捕获到数据窗口的close事件了</p>
<p>&nbsp;</p>
<p>(closequery事件的ID找到以后再补充)</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/187728#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 28 Apr 2008 18:35:04 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/187728</link>
        <guid>http://ben-sin.javaeye.com/blog/187728</guid>
      </item>
      <item>
        <title>项目由OC4J 9i升级到OC4J10g</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/187312" style="color:red;">http://ben-sin.javaeye.com/blog/187312</a>&nbsp;
          发表时间: 2008年04月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>最近项目eJMS需要由oc4j 9i 升级到10g，相应的jdk由1.31 升级为1.5</p>
<p>项目没有使用什么架构，纯粹是Java Bean + JSP编写。</p>
<p>由于JDK 1.31允许将Java Bean直接放在default package下，而JDK1.42以上必须使用package</p>
<p>所以升级工作的第一步就是将class移植到一个package中，早期项目的文件比较乱，所以在做这一步的同时也按照一般web project的规范，将编译后的Java class放进WEB-INF/classes当中。</p>
<p>&nbsp;</p>
<p>第二步就是测试，由于对OC4J不熟悉，所以不敢直接打包然后部署到OC4J 10g上，于是就选择tomcat</p>
<p>开始的时候使用tomcat5.0，后来发现tomcat 5.0只支持到JDK1.42，配置好数据源之后不断出现Naming Exception,后来改换tomcat5.5就没有出现这个问题了，连接数据源成功。</p>
<p>使用tomcat配置data source的时候发现，5.0跟5.5有一定的差别，http://ben-sin.javaeye.com/blog/186080里面有详细描述。</p>
<p>&nbsp;</p>
<p>tomcat里面测试完后，开始部署到OC4J 10g上面测试了</p>
<p>但是出现难题了，OC4J怎样配置数据源？直接修改config下的data-source.xml文件，换来的结果就是console就进不去了，于是在网上搜索之后发现OC4J在console有一个叫管理tabpage的地方提供了这样的接口</p>
<p>&gt;&gt;选择部署的服务器-管理tabpage-服务-jdbc</p>
<p>进入去之后可以有两个列表，一个是datasource，另外一个是connection pool</p>
<p>这里首先配置connection pool，新建一个之后发现使用URL配置连接不上，后来改用从连接信息生成URL,填上需要的参数之后测试成功了，</p>
<p>然后配置data source, 选择新建，受管数据源，填上名称，jndi，选择连接池，timeout，完成就ok,测试也成功</p>
<p>&nbsp;</p>
<p>准备工夫做好之后就开始部署web application了，部署很顺利，最后测试</p>
<p>发现提示连接数据库出错，比较了数据源地jndi和class里面使用到的jndi配置，发现两个没有什么不同</p>
<p>后来才发现当我读取jndi的时候实际上使用了java:env/comp/jdbc/pooled_ejms10g，这个在tomcat没有问题，因为tomcat时使用jdbc连接，而OC4J有专用的连接库，所以就无需java:env/comp/了，直接使用jdbc/pooled_ejms10g。</p>
<p>rebuild application, 部署，测试，连接成功。粗略地测试了一下页面，基本上没有什么异常。</p>
<p>&nbsp;</p>
<p>看看表已经下午6点半了，明天再做一个详细的测试。</p>
<p>这几天一直担心的问题终于接近尾声了，晚上可以睡个安乐觉了，哈哈。。。</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/187312#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 27 Apr 2008 18:45:05 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/187312</link>
        <guid>http://ben-sin.javaeye.com/blog/187312</guid>
      </item>
      <item>
        <title>Tomcat 热配置以及配置DataSource</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/186080" style="color:red;">http://ben-sin.javaeye.com/blog/186080</a>&nbsp;
          发表时间: 2008年04月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Tomcat可以在Webapps新建项目，但通常这样的做法不利于管理项目文件，也不利于切换版本</p>
<p>Tomcat可以在配置Tomcat Folder\conf\Catalina\localhost\目录下新建xxx.xml进行热配置，通过docBase指向项目文件目录则可</p>
<pre name="code" class="xml">&lt;?xml version='1.0' encoding='utf-8'?&gt;

&lt;Context docBase=&quot;E:\Work\AnsonSolder\WebRoot&quot; path=&quot;/anson&quot; reloadable=&quot;true&quot; debug=&quot;0&quot;&gt;
&lt;/Context&gt;</pre>
<p>docBase指定项目文件所在目录</p>
<p>path指定web application发布的别名</p>
<p>reloadable指定是否实时同步(发布)项目文件</p>
<p>debug指定是否允许debug</p>
<p>(其他参数待补充)</p>
<p>&nbsp;</p>
<p>除此之外，还可以在这个文件配置DataSource，但是Tomcat5.0跟5.5有点区别，以下是5.5的DataSource配置</p>
<pre name="code" class="xml">&lt;?xml version='1.0' encoding='utf-8'?&gt;

&lt;Context docBase=&quot;E:\Work\AnsonSolder\WebRoot&quot; path=&quot;/anson&quot; reloadable=&quot;true&quot; debug=&quot;0&quot;&gt;

	&lt;Resource name=&quot;jdbc/AnsonSolderDB&quot;
			  auth=&quot;Container&quot;
			  type=&quot;javax.sql.DataSource&quot;
			  maxActive=&quot;100&quot;
			  maxIdle=&quot;30&quot;
	                  maxWait=&quot;10000&quot;
	                  username=&quot;sa&quot;
	                  password=&quot;dbsa&quot;
	                  driverClassName=&quot;oracle.jdbc.driver.OracleDriver&quot;
	                  url=&quot;jdbc:oracle:thin:@192.168.0.12:1521:test&quot;/&gt;
&lt;/Context&gt;
</pre>
<p>&nbsp;5.0的DataSource配置</p>
<pre name="code" class="xml">&lt;?xml version='1.0' encoding='utf-8'?&gt;

&lt;Context docBase=&quot;E:\Work\AnsonSolder\WebRoot&quot; path=&quot;/anson&quot; reloadable=&quot;true&quot; debug=&quot;0&quot;&gt;

	&lt;Resource name=&quot;jdbc/AnsonSolderDB&quot;
			  auth=&quot;Container&quot;
			  type=&quot;javax.sql.DataSource&quot;&gt;
	&lt;/Resource&gt;
	&lt;ResourceParamters&gt;
		&lt;Parameter&gt;
			&lt;name&gt;maxActive&lt;/name&gt;
			&lt;value&gt;100&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;maxIdle&lt;/name&gt;
			&lt;value&gt;30&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;maxWait&lt;/name&gt;
			&lt;value&gt;10000&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;username&lt;/name&gt;
			&lt;value&gt;sa&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;password&lt;/name&gt;
			&lt;value&gt;dbsa&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;driverClassName&lt;/name&gt;
			&lt;value&gt;oracle.jdbc.driver.OracleDriver&lt;/value&gt;
		&lt;/Parameter&gt;
		&lt;Parameter&gt;
			&lt;name&gt;url&lt;/name&gt;
			&lt;value&gt;jdbc:oracle:thin:@192.168.0.12:1521:test&lt;/value&gt;
		&lt;/Parameter&gt;
	&lt;/ResourceParameters&gt;

&lt;/Context&gt;
</pre>
<p>&nbsp;Java可以通过一下代码获得DataSource</p>
<pre name="code" class="java">import java.sql.*;
import java.io.*;
import java.util.*;
import java.util.Date;
import javax.naming.InitialContext;
import javax.sql.*;

public class DBConnectionManager {
    private PrintWriter log;

    private InitialContext context;
    private DataSource myDS;

    /**
    * A private constructor since this is a Singleton
    */
    public DBConnectionManager() {
        init();
    }

    /**
    * Returns a connection to the named pool.
    *
    * @param name The pool name as defined in the properties file
    * @param con The Connection
    */
    public synchronized void freeDBConnection(String name, DBConnection dbcon) {
        try {
            dbcon.close();
        }
        catch (Exception e) {
            log(e, e.toString());
        }
    }

    /**
    * Returns an open connection. If no one is available, and the max
    * number of connections has not been reached, a new connection is
    * created.
    *
    * @param name The pool name as defined in the properties file
    * @return Connection The connection or null
    */

    public synchronized DBConnection getDBConnection(String name) {
        try {
            return new DBConnection(myDS.getConnection());
        }
        catch (Exception e) {
            log(e, e.toString());
        }
        return null;
    }


    /**
    * Loads properties and initializes the instance with its values.
    */
    private void init() {
        InputStream is = getClass().getResourceAsStream(&quot;/db.properties&quot;);
        Properties dbProps = new Properties();
        try {
            dbProps.load(is);
        }
        catch (Exception e) {
            System.err.println(&quot;Can't read the properties file. &quot; +
            &quot;Make sure db.properties is in the CLASSPATH&quot;);
            return;
        }
        String logFile = dbProps.getProperty(&quot;logfile&quot;, &quot;DBConnectionManager.log&quot;);
        try {
            log = new PrintWriter(new FileWriter(logFile, true), true);
        }
       catch (IOException e) {
            System.err.println(&quot;Can't open the log file: &quot; + logFile);
            log = new PrintWriter(System.err);
        }

        String datasource = dbProps.getProperty(&quot;datasource&quot;, &quot;jdbc/OracleCoreDS_ejms&quot;);
        try {
            context = new InitialContext();
            myDS = (DataSource) context.lookup(datasource);
        }
        catch (Exception e) {
            log(e, e.toString());
        }
    }

    /**
    * Writes a message to the log file.
    */
    private void log(String msg) {
        log.println(new Date() + &quot;: &quot; + msg);
    }

    /**
    * Writes a message with an Exception to the log file.
    */
    private void log(Throwable e, String msg) {
        log.println(new Date() + &quot;: &quot; + msg);
        e.printStackTrace(log);
    }
}</pre>
<p>&nbsp;db.properties</p>
<pre name="code" class="java">datasource=java:env/comp/jdbc/AnsonSolderDB</pre>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/186080#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 Apr 2008 21:40:19 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/186080</link>
        <guid>http://ben-sin.javaeye.com/blog/186080</guid>
      </item>
      <item>
        <title>提取DataWindow的参数</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/185382" style="color:red;">http://ben-sin.javaeye.com/blog/185382</a>&nbsp;
          发表时间: 2008年04月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>这里说的DataWindow是指dataobject的那个，而不是DataWindow Control</p>
<p>DataWindow可以有几个参数，但是PB并没有提供专门的函数去取得这些参数，DW Syntax也没有指出用那些关系可以去除这些参数信息。但是这些信息还是可以直接取得</p>
<p>dw_control.object.dataWindow.table.arguments</p>
<p>取出来的是一个字符串，参数之间通过~n连接，参数名和参数类型之间通过~t连接</p>
<p>比如有参数arg1/String和arg2/Number，我们用上述语句得到的结果就会是</p>
<p>&quot;arg1~tString~narg2~tNumber&quot;</p>
<p>所以这里取出来还需要做一些出来才能利用这些信息</p>
<p>// 定义一个custom user object去记录参数信息</p>
<p>(PB代码)</p>
<pre name="code" class="java">$PBExportHeader$nvo_dw_args.sru
forward
global type nvo_dw_args from nonvisualobject
end type
end forward

global type nvo_dw_args from nonvisualobject autoinstantiate
end type

type variables
string argName
string argType
end variables

on nvo_dw_args.create
call super::create
TriggerEvent( this, &quot;constructor&quot; )
end on

on nvo_dw_args.destroy
TriggerEvent( this, &quot;destructor&quot; )
call super::destroy
end on

event constructor;/**
 * This object use to store the argument info of datawindow
 * argName store argument's name
 * argType store argument's data type
 */
end event
</pre>
<p>// 读取和分析参数并返回参数信息</p>
<p>(PB代码)</p>
<pre name="code" class="java">$PBExportHeader$n_cst_dw_util2.sru
forward
global type n_cst_dw_util2 from nonvisualobject
end type
end forward

global type n_cst_dw_util2 from nonvisualobject
end type

global n_cst_dw_util2 n_cst_dw_util2

type variables
DataWindow		idw
end variables

forward prototypes
public function integer of_getarguments (ref nvo_dw_args args[])
end prototypes

public function integer of_getarguments (ref nvo_dw_args args[]);/**
 * get the registe datawindow arguments. 
 * the arguments will be store into nvo_dw_args array args[]
 * @param ref args[]- nvo_dw_args
 * @return integer
 * - return the arguments count if successful
 * - return 0 if no arguments
 * - return -1 if invalid idw or error
 * @author Ben
 * @history
 * 1. created	21-Apr-2008		Ben
 */

string ls_argStr
string ls_tmpArg
integer li_pos, li_posTab, li_index

if not isValid(idw) then return -1	

ls_argStr = idw.object.dataWindow.table.arguments

if isNull(ls_argStr) or ls_argStr = &quot;&quot; then return 0

do
	li_pos = pos(ls_argStr, '~n')	

	if li_pos &gt; 0 then
		ls_tmpArg = left(ls_argStr, li_pos - 1)
		ls_argStr = right(ls_argStr, len(ls_argStr) - li_pos)
	else
		ls_tmpArg = ls_argStr
	end if

	if not isNull(ls_tmpArg) and ls_tmpArg &lt;&gt; &quot;&quot; then
		li_posTab = pos(ls_tmpArg, '~t')
		
		if li_posTab &gt; 0 then
			li_index = upperBound(args) + 1
			args[li_index].argName = left(ls_tmpArg, li_posTab - 1)
			args[li_index].argType = right(ls_tmpArg, len(ls_tmpArg) - li_posTab)
		end if
	end if
loop while li_pos &gt; 0

return 1
end function

on n_cst_dw_util2.create
call super::create
TriggerEvent( this, &quot;constructor&quot; )
end on

on n_cst_dw_util2.destroy
TriggerEvent( this, &quot;destructor&quot; )
call super::destroy
end on
</pre>
<p>返回的nvo_dw_args数组包含了参数名和参数类型，这样比较方便使用.</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/185382#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 22 Apr 2008 11:46:00 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/185382</link>
        <guid>http://ben-sin.javaeye.com/blog/185382</guid>
      </item>
      <item>
        <title>Java日积月累001-字符串比较的技巧，避免NullPointerException</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/183556" style="color:red;">http://ben-sin.javaeye.com/blog/183556</a>&nbsp;
          发表时间: 2008年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>这里说的String的比较是value的比较，通过equals()或者equalsIgnoreCase()来进行</p>
<p>当一个String变量和一个String常量比较的时候，两个String顺序不一样会带来一些意想不到的效果</p>
<pre name="code" class="java">String tmStr = null;

....

// 有可能引起NullPointerException
tmpStr.equalsIgnoreCase(&quot;A&quot;);
		
// 这种情况不会有NullPointerException
&quot;B&quot;.equalsIgnoreCase(tmpStr);</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/183556#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Apr 2008 23:33:03 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/183556</link>
        <guid>http://ben-sin.javaeye.com/blog/183556</guid>
      </item>
      <item>
        <title>JS日积月累001 - rows 和 cells的使用</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/183546" style="color:red;">http://ben-sin.javaeye.com/blog/183546</a>&nbsp;
          发表时间: 2008年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Table下面可以有thead和tbody两个分组对象，某些时候可以代替div使用，比如实现某部份表格隐藏。<br />
<br />
tr是行，th或者td是列，这些对象构成表格阵列<br />
<br />
每一个...就是我们所说得rows[id]<br />
<br />
每一个...或者...就是cells[id]了<br />
<br />
对于使用table来作为整个分组，我个人更喜欢tbody来代替table.<br />
<br />
在table生命周期，只要我们知道tbody预设的id,我们就可以通过以下js代码获得这个tbody<br />
<br />
document.getElementById(tbodyID);<br />
<br />
js是弱类型语言，我们可以通过var一个对象来作为这个tbody的标记,然后就可以引用rows和cells了<br />
<br />
var tbodyObj = document.getElementById(tbodyID);<br />
<br />
tbodyObj.rows[rowID].cells[colID].innerText = &quot;abcd&quot;;<br />
<br />
tbodyObj.rows[rowID].cells[colID].innerHTML = &quot;abcd<br />
<br />
(innerHTML是指html代码，innerText是指显示的text);<br />
<br />
通过以下例子来说说rows和cells的一些应用<br />
<br />
代码：</p>
<pre name="code" class="html">&lt;html&gt;
	&lt;head&gt;
			&lt;title&gt;JS日积月累001 - rows 和 cells的使用&lt;/title&gt;
			&lt;script type=&quot;text/javascript&quot;&gt;
				function validForm(curForm, bodyName){
					var bodyObj = document.getElementById(bodyName);
					var rowObj = null;
					var cellObj = null;
					
					if (bodyObj == null){
						return false;
					}
					
					// 引用rows
					for (var i = 0; i &lt; bodyObj.rows.length; i ++){
						rowObj = bodyObj.rows[i];
						
						// 带*的必须输入，引用cells
						if (rowObj.cells[0].innerText.indexOf(&quot;*&quot;) &gt; 0){
							if (rowObj.cells[1].childNodes[0].value == &quot;&quot;){
								alert(rowObj.cells[0].innerText.replace(&quot; * :&quot;, &quot;&quot;) + &quot;不能为空！&quot;);
								return false;
							}
						}
					}
					
					alert(&quot;Pass validation&quot;);
					//curForm.submit();
				}
			&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;form action=&quot;&quot; method=&quot;post&quot; name=&quot;loginFrm&quot;&gt;
			&lt;table&gt;
			  &lt;tbody id=&quot;validBody&quot;&gt;
			    &lt;tr&gt;
			      &lt;td align=&quot;right&quot;&gt;用户名 &lt;font color=&quot;red&quot;&gt;*&lt;/font&gt; :&lt;/td&gt;
			      &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;username&quot; /&gt;&lt;/td&gt;
			    &lt;/tr&gt;
			    &lt;tr&gt;
			      &lt;td align=&quot;right&quot;&gt;密码 &lt;font color=&quot;red&quot;&gt;*&lt;/font&gt; :&lt;/td&gt;
			      &lt;td&gt;&lt;input type=&quot;password&quot; name=&quot;username&quot; /&gt;&lt;/td&gt;
			    &lt;/tr&gt;
			    &lt;tr&gt;
			      &lt;td align=&quot;right&quot;&gt;子系统 &lt;font color=&quot;red&quot;&gt;*&lt;/font&gt; :&lt;/td&gt;
			      &lt;td&gt;
			        &lt;select name=&quot;systemname&quot;&gt;
			          &lt;option value=&quot;&quot;&gt;---请选择---&lt;/option&gt;
			          &lt;option value=&quot;HR&quot;&gt;人力资源系统&lt;/option&gt;
			          &lt;option value=&quot;PUR&quot;&gt;采购系统&lt;/option&gt;
			          &lt;option value=&quot;SAL&quot;&gt;销售系统&lt;/option&gt;
			        &lt;/select&gt;
			      &lt;/td&gt;
			    &lt;/tr&gt;
			  &lt;/tbody&gt;
			  &lt;tbody&gt;
			  	&lt;tr&gt;
			  		&lt;td colspan=&quot;2&quot;&gt;
			  			&lt;input type=&quot;button&quot; value=&quot;提交&quot; name=&quot;submit&quot; onclick=&quot;validForm(this.form, 'validBody')&quot;/&gt;
			  			&lt;input type=&quot;reset&quot; value=&quot;Reset&quot; name=&quot;reset&quot;/&gt;
			  		&lt;/td&gt;
			  	&lt;/tr&gt;
			  &lt;/tbody&gt;
			&lt;/table&gt;
		&lt;/form&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
&nbsp;
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/183546#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Apr 2008 23:09:13 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/183546</link>
        <guid>http://ben-sin.javaeye.com/blog/183546</guid>
      </item>
      <item>
        <title>JS动态增加删除行</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/180440" style="color:red;">http://ben-sin.javaeye.com/blog/180440</a>&nbsp;
          发表时间: 2008年04月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          利用html的特性实现动态增加删除行，一下是JS函数代码。<br /><br />        // 用于增加行的时候参照隐藏的row<br />        function addRow2(tbodyName, hiddenTbodyName){<br />		// Get the tbody<br />		var orgBody = document.getElementById(tbodyName);<br />		var recordRowCount=orgBody.rows.length;<br />		var hiddenBody = document.getElementById(hiddenTbodyName)<br />		//var firstRow = orgBody.rows[0];<br />		var firstRow = hiddenBody.rows[0];<br />		var newRow = firstRow.cloneNode(true);<br /><br />		// Call function to general the new ID<br />		var newID = shiftID(firstRow.id, orgBody.rows.length + 1)<br />		// Set the row's ID<br />		newRow.id = newID;<br />	   <br />		// add the new row<br />		orgBody.appendChild(newRow);<br />	   <br />		// Reset the item status<br />		resetRow(newRow);<br />		<br />		// Reset the item number for this page only<br />		resetItemNum(orgBody);<br />	}<br />        // 参照第一行来增加<br />	function addRow(tbodyName){<br />		// Get the tbody<br />		var orgBody = document.getElementById(tbodyName);<br />		var recordRowCount=orgBody.rows.length;<br />		var firstRow = orgBody.rows[0];<br />		var newRow = firstRow.cloneNode(true);<br /><br />		// Call function to general the new ID<br />		var newID = shiftID(firstRow.id, orgBody.rows.length + 1)<br />		// Set the row's ID<br />		newRow.id = newID;<br />	   <br />		// add the new row<br />		orgBody.appendChild(newRow);<br />	   <br />		// Reset the item status<br />		resetRow(newRow);<br />		<br />		// Reset the item number for this page only<br />		resetItemNum(orgBody);<br />	}<br />	<br />	// Reset the input field value<br />	function resetRow(obj){		<br />		var items = obj.childNodes;<br />		//alert(items.length);<br />		for (var m = 0; m &lt; items.length; m ++){<br />			// loop the elements of object<br />			if (items[m].childNodes.length > 0){<br />				resetRow(items[m]);<br />			}<br />			<br />			if (items[m] != undefined && items[m].type != undefined){<br />				if (items[m].type == "select-one"){<br />					items[m].selectIndex = -1;<br />					items[m].value="";<br />				}else if (items[m].type == "radio"){<br />					// pass<br />					//items[m].id = shiftID(items[m].id, newIndex);<br />				}else if (items[m].type == "text"){<br />					// Empty input text<br />					items[m].value = "";<br />				}else if (items[m].type == "hidden"){<br />					// Empty input text<br />					items[m].value = "";<br />				}else if (items[m].type == "checkbox"){<br />					// Empty input text<br />					items[m].checked = false;<br />				}else{<br />					break;<br />				}<br />			}<br />		}<br />	}<br />	<br />	function resetItemNum(tbody){<br />		var item<br />		for (var i = 0; i &lt; tbody.rows.length; i ++){<br />			item = tbody.rows[i].cells[1];<br />			item.innerHTML = (i + 1);<br />		}<br />	}<br />	<br />	// General the new ID<br />	function shiftID(oldID, rowNum){<br />		var newNum = "0" + rowNum;<br />		// Split the last two characters<br />		newNum = newNum.slice(newNum.length - 2, newNum.length)<br />		return oldID.slice(0, oldID.length - 2) + newNum;<br />	}<br />	<br />	// Delete the selected row<br />	function deleteRow(bodyName){<br />		var tbody = document.getElementById(bodyName);<br />		if (tbody == null){<br />			return;<br />		}<br />		<br />		// loop the rows<br />		for (var i = tbody.rows.length - 1; i >= 0 ; i --){<br />			// selected row<br />			if (rowSelected(tbody.rows[i])){<br />				// delete the selected row if it has more than one row<br />				if (tbody.rows.length > 1){<br />					// remove the selected row<br />					tbody.removeChild(tbody.rows[i]);<br />				}else{<br />					// reset the last row<br />					resetRow(tbody.rows[i]);<br />				}<br />			}<br />		}<br />		<br />		// reset the item number<br />		resetItemNum(tbody);<br />	}<br />	<br />	// check the special row is selected<br />	function rowSelected(row){<br />		var firstCell = row.cells[0];<br />		var child = null;<br />		for (var i = 0; i &lt; firstCell.childNodes.length; i ++){<br />			child = firstCell.childNodes[i];<br />			if (child.type != undefined && child.type.toString() == "checkbox"){<br />				return firstCell.childNodes[i].checked;<br />			}<br />		}<br />		return false;<br />	}
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/180440#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 08 Apr 2008 13:49:07 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/180440</link>
        <guid>http://ben-sin.javaeye.com/blog/180440</guid>
      </item>
      <item>
        <title>PB用OLE DB连接MS SQL Server </title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177507" style="color:red;">http://ben-sin.javaeye.com/blog/177507</a>&nbsp;
          发表时间: 2008年03月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          PB9.0（含）前的版本都由提供MSSQL server 的专用接口<br />但PB10之后，这个接口就被取消了，改而使用ole db或者odbc接口来连接database<br /><br />举个例子<br />//MSSQL Server的连接配置<br />sqlca.dbms=MSS Microsoft SQL Server<br />sqlca.database=yourdb<br />sqlca.dbparm=<br />sqlca.logid=sa<br />SQLCA.LogPass = &lt;password><br />sqlca.servername=SERVERNAME<br />sqlca.autocommit=false<br /><br />// OLE DB的连接配置<br />SQLCA.DBMS = "OLE DB"<br />SQLCA.LogPass = &lt;password><br />SQLCA.LogId = "sa"<br />SQLCA.AutoCommit = False<br />SQLCA.DBParm = "PROVIDER='SQLOLEDB',DATASOURCE='SERVERNAME',PROVIDERSTRING='database=yourdb'"<br /><br />DBMS在这里是OLE DB<br />DBParm里面跟ODBC不同<br />PROVIDER=‘SQLOLEDB‘指示这里要连接的是MSSQL Server<br />DATASOURCE='SERVERNAME'指示要连接的MSSQL Server名称<br />PROVIDERSTRING='database=yourdb'则指定了要连接的数据库名
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177507#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 29 Mar 2008 02:00:49 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177507</link>
        <guid>http://ben-sin.javaeye.com/blog/177507</guid>
      </item>
      <item>
        <title>JS - 动态创建2维数组Array (例子源码) </title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177506" style="color:red;">http://ben-sin.javaeye.com/blog/177506</a>&nbsp;
          发表时间: 2008年03月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &lt;html><br /> &lt;head><br /> &lt;/head><br /> <br /> &lt;script type="text/javascript"><br />  // Storing the list display value<br />  var listArray;<br />  <br />  /**<br />   * Store the input value to listArray<br />   * with identified by name.<br />   */<br />  function setListArray(sName, sValue){<br />   alert(sValue);<br />   // listArray is null<br />   if (listArray == null){<br />    // Initialize the listArray<br />    listArray = new Array();<br />    // Store the first group<br />    listArray[0] = new Array(sName, sValue);<br />   }<br />   // listArray is not null<br />   else{<br />    // declare flag<br />    var valueFound = false;<br />    for (var i = 0; i &lt; listArray.length; i ++){<br />     // find in the old array<br />     if (listArray[i][0] == sName){<br />      // store the value<br />      listArray[i][listArray[i].length] = sValue;<br />      // set flag when matched<br />      valueFound = true;<br />      // Exit for looping when matched<br />      break;<br />     }<br />    }<br />    //alert(listArray[0].length);<br />    // new a group when not matched<br />    if (!valueFound){<br />     //var index = listArray.length;<br />     listArray[listArray] = new Array(sName, sValue);<br />    }<br />   }<br />   //alert(listArray[0].length);<br />  }<br />  <br />  /**<br />   * get the value from listArray with name and index<br />   */<br />  function getListArray(name, index){<br />   if (index == 0){<br />    return "";<br />   }<br />   // return false when listArray is null;<br />   if (listArray == null){<br />    alert("No listArray found!");<br />    return false;<br />   }<br />   // Loop the listArray to found the object.<br />   for (var i = 0; i &lt; listArray.length; i ++){<br />    if (listArray[i][0] == name){<br />     // display the value<br />     return listArray[i][index];<br />    }<br />   }<br />   alert("No record could be found in listArray");<br />  }<br />  <br />  /**<br />   * Set the value to the special Element<br />   */<br />  function selectChanged(name, index, targetObj){<br />   // get the target element<br />   var obj = document.getElementById(targetObj);<br />   // return false when target element cannot be found.<br />   if (obj == null){<br />    alert("Element '" + targetObj + "' cannot be found!");<br />    return false;<br />   }<br />   obj.value = getListArray(name, index);<br />  }<br /> &lt;/script><br /> &lt;body><br />  &lt;table><br />   &lt;tr><br />    &lt;td><br />     &lt;select name="sel" onchange="selectChanged('sel', this.selectedIndex, 'show')"><br />      &lt;option value="00">(none)&lt;/option><br />      &lt;option value="01">name 01&lt;/option><br />      &lt;option value="02">name 02&lt;/option><br />      &lt;option value="03">name 03&lt;/option><br />      &lt;option value="04">name 04&lt;/option><br />     &lt;/select><br />    &lt;/td><br />    &lt;td><br />     &lt;input type="text" name="show" value=""/><br />    &lt;/td><br />   &lt;/tr><br />   &lt;tr><br />    &lt;td colspan="2">&lt;input type="button" value="disply"/>&lt;/td><br />   &lt;/tr><br />  &lt;/table><br /> &lt;/body><br />&lt;/html><br />&lt;script type="text/javascript"><br /> setListArray('sel', 'name 01');<br /> setListArray('sel', 'name 02');<br /> setListArray('sel', 'name 03');<br /> setListArray('sel', 'name 04');<br />&lt;/script>
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177506#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 29 Mar 2008 01:59:04 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177506</link>
        <guid>http://ben-sin.javaeye.com/blog/177506</guid>
      </item>
      <item>
        <title>PB事件/函数的触发机制和触发方式 </title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177505" style="color:red;">http://ben-sin.javaeye.com/blog/177505</a>&nbsp;
          发表时间: 2008年03月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          B作为windows下的一个非常便捷的DB开发工具，有着和windows一样的消息触发机制<br />PB提供了相应event/function触发机制和触发方式，用户可以根据自己的实际需要选用不同方法。<br /><br />1. 触发机制 trigger/post<br /><br />使用trigger会即时触发event/function；<br />使用post的时候则有所不同，系统会将event/function放在消息队列中，等待排在前面的event/function完成后才会执行，因为这个消息队列实现先进先出。<br /><br />默认情况下系统以trigger方式触发event/function<br /><br />什么情况下该用trigger,什么情况下该用post？这里举个例子简单说说。<br /><br />举例：<br />当实现某一功能a的时候会触发某个事件/函数(A), 在这个A事件要去触发某个功能b的事件/函数(B)以及功能c的事件/函数C。<br /><br />当B无需在A之后就能拿到满足的条件，这个时候采用trigger;<br />但C必须在A完成后才拿到足够的条件，这个时候采用post.<br /><br />-- 假设<br />当某sle在获得焦点的时候，如果有权限修改的话就高亮显示，如果没有权的修改的时候就返回。<br /><br />getFocus事件是获得焦点功能触发的，uf_check()函数能够检查权限，selectText函数能将text高亮显示<br /><br />-- 分析<br />uf_check()函数已经获得足够的条件，selectText必须在A完成后才能触发或者不触发。<br /><br />所以在这里uf_check()可以直接trigger(默认触发方式)；selectText()就需要使用post，让其排在getFocus()之后执行<br /><br />-- 结果<br />if uf_check() = true then<br />   post selectText(1, len(this.text))<br />end if<br /><br /><br />-- 总结<br />采用哪一种触发机制可以充两方面考虑：<br />a) 从触发对象考虑。<br />触发对象需要马上执行的应当采用trigger;<br />触发对象必须在某个事件/函数之后才能触发的，但必须在这个时候去完成触发动作的，采用post.<br /><br />b) 从触发源考虑。<br />充当触发源的事件/函数在某特定功能中属于是功能完成前事件/函数的时候，应当采用post；<br />如果属于功能完成后的事件/函数，采用trigger.<br /><br /><br />2. 触发方式<br /><br />PB也为event/function提供了几种触发的方式<br /><br />a) obj.triggerEvent(event_id) / obj.postEvent(event_id) -- 只用于事件<br />   这一类触发方式多用于PB提供的系统event, 也可以用于触发不带参数的用户事件(user event). 或许会有疑问，为什么会常用于触发系统事件？<br />   个人理解是这样的，系统事件多为带参数的事件，用obj.triggerEvent(event_id) / obj.postEvent(event_id)可以省去为这些事件准备参数的工作。如果用户事件没有带参数的，也可以使用这类方式去触发。<br /><br />b) obj.[trigger/post] [event/function] event_id/function_id(args) --  用于事件/函数<br />   这一类触发方式多用于触发带参数的用户事件/所有函数, 也可以用于不带参数的用户事件/系统事件。<br />  <br />   其实这类触发方式还可以这样写<br />   obj.[event/function] [trigger/post] event_id/function_id(args) <br /><br />   我们可以用说明方式来描述这种触发方式：obj.[触发机制] [触发机制] [触发对象](参数). [触发机制]默认的是trigger, [触发机制]默认的是函数, [参数]可选。<br />   也就是说，我们如果不写trigger/post，就会默认采用trigger机制。我们如果没有声明[触发机制]，系统会理解[触发对象]为某一实体函数。如果[触发对象]是事件，那么就必须声明[触发机制]为event.<br /><br />   举例说明：现有函数 uf_test(args) 和事件 ue_test(args)。我们可以采用以下方式来触发它们：<br />   obj.trigger event ue_test(args) / obj.post event ue_test(args)<br />   obj.event trigger ue_test(args) / obj.event post ue_test(args)<br />   obj.event ue_test(args)         / 没有对应的post方式<br /><br />   obj.trigger function uf_test(args) / obj.post function uf_test(args)<br />   obj.function trigger uf_test(args) / obj.function post uf_test(args)<br />   obj.uf_test(args                   / obj.post uf_test(args)<br /><br />c) 动态事件和函数<br />   为什么将动态事件/函数纳入某一种触发方式？其实所谓的动态触发的事件/函数也是某一object的实体事件和函数，但在触发的时候是未知的。<br />   第一种触发方式其实也可以触发未知的事件，但仅限于事件，而且是不带参数的事件。在这个时候就需要有一种更加灵活的触发方式来达到触发未知事件或者函数的目的。<br />   这类的触发方式可以混合第二中使用，但在这里就不详细解析了。以下是动态事件/函数触发方式的举例写法。<br /><br />   obj.dynamic event event_id(args)<br />   obj.dynamic function_id(args)<br /><br />   动态触发的事件/函数可以是实体事件/函数，也可以没有这个事件/函数。如果找不到这个事件/函数，系统会默认跳过，不会报错。这类方式适当运用可以起到很好的效果<br /><br /><br />Ben<br />2008/03/14
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177505#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 29 Mar 2008 01:57:02 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177505</link>
        <guid>http://ben-sin.javaeye.com/blog/177505</guid>
      </item>
      <item>
        <title>js代码触发事件-函数列表 </title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177509" style="color:red;">http://ben-sin.javaeye.com/blog/177509</a>&nbsp;
          发表时间: 2008年03月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          onabort 当用户中断下载图像时触发。 <br />onactivate 当对象设置为活动元素时触发。 <br />onafterprint 对象所关联的文档打印或打印预览后立即在对象上触发。 <br />onafterupdate 当成功更新数据源对象中的关联对象后在数据绑定对象上触发。 <br />onbeforeactivate 对象要被设置为当前元素前立即触发。 <br />onbeforecopy 当选中区复制到系统剪贴板之前在源对象触发。 <br />onbeforecut 当选中区从文档中删除之前在源对象触发。 <br />onbeforedeactivate 在 activeElement 从当前对象变为父文档其它对象之前立即触发。 <br />onbeforeeditfocus 在包含于可编辑元素内的对象进入用户界面激活状态前或可编辑容器变成控件选中区前触发。 <br />onbeforepaste 在选中区从系统剪贴板粘贴到文档前在目标对象上触发。 <br />onbeforeprint 对象的关联文档打印或打印预览前在对象上触发。 <br />onbeforeunload 在页面将要被卸载前触发。 <br />onbeforeupdate 当成功更新数据源对象中的关联对象前在数据绑定对象上触发。 <br />onblur 在对象失去输入焦点时触发。 <br />onbounce 当 marquee 对象的 behavior 属性设置为&ldquo;alternate&rdquo;且字幕的内容到达窗口一边时触发。 <br />oncellchange 在数据供应者中的数据变更时触发。 <br />onchange 当对象或选中区的内容改变时触发。 <br />onclick 在用户用鼠标左键单击对象时触发。 <br />oncontextmenu 在用户使用鼠标右键单击客户区打开上下文菜单时触发。 <br />oncontrolselect 当用户将要对该对象制作一个控件选中区时触发。 <br />oncopy 当用户复制对象或选中区，将其添加到系统剪贴板上时在源元素上触发。 <br />oncut 当对象或选中区从文档中删除并添加到系统剪贴板上时在源元素上触发。 <br />ondataavailable 每当异步传输数据的数据源对象的数据到达时触发。 <br />ondatasetchanged 当数据源对象对应的数据集发生变更时触发。 <br />ondatasetcomplete 触发就表明数据源对象所有数据都可用。 <br />ondblclick 当用户双击对象时触发。 <br />ondeactivate 当 activeElement 从当前对象变为父文档其它对象时触发。 <br />ondrag 当进行拖曳操作时在源对象上持续触发。 <br />ondragend 当用户在拖曳操作结束后释放鼠标时在源对象上触发。 <br />ondragenter 当用户拖曳对象到一个合法拖曳目标时在目标元素上触发。 <br />ondragleave 当用户在拖曳操作过程中将鼠标移出合法拖曳目标时在目标对象上触发。 <br />ondragover 当用户拖曳对象划过合法拖曳目标时持续在目标元素上触发。 <br />ondragstart 当用户开始拖曳文本选中区或选中对象时在源对象上触发。 <br />ondrop 当鼠标按钮在拖曳操作过程中释放时在目标对象上触发。 <br />onerror 当对象装载过程中发生错误时触发。 <br />onerrorupdate 更新数据源对象中的关联数据出错时在数据绑定对象上触发。 <br />onfilterchange 当可视滤镜更改状态或完成转换时触发。 <br />onfinish 当字幕循环完成后触发。 <br />onfocus 当对象获得焦点时触发。 <br />onfocusin 当元素将要被设置为焦点之前触发。 <br />onfocusout 在移动焦点到其它元素之后立即触发于当前拥有焦点的元素上触发。 <br />onhelp 当用户在浏览器为当前窗口时按 F1 键时触发。 <br />onkeydown 当用户按下键盘按键时触发。 <br />onkeypress 当用户按下字面键时触发。 <br />onkeyup 当用户释放键盘按键时触发。 <br />onlayoutcomplete 当打印或打印预览版面处理完成用来自于源文档的内容填充当前 LayoutRect 对象时触发。 <br />onload 在浏览器完成对象的装载后立即触发。 <br />onlosecapture 当对象失去鼠标捕捉时触发。 <br />onmousedown 当用户用任何鼠标按钮单击对象时触发。 <br />onmouseenter 当用户将鼠标指针移动到对象内时触发。 <br />onmouseleave 当用户将鼠标指针移出对象边界时触发。 <br />onmousemove 当用户将鼠标划过对象时触发。 <br />onmouseout 当用户将鼠标指针移出对象边界时触发。 <br />onmouseover 当用户将鼠标指针移动到对象内时触发。 <br />onmouseup 当用户在鼠标位于对象之上时释放鼠标按钮时触发。 <br />onmousewheel 当鼠标滚轮按钮旋转时触发。 <br />onmove 当对象移动时触发。 <br />onmoveend 当对象停止移动时触发。 <br />onmovestart 当对象开始移动时触发。 <br />onpaste 当用户粘贴数据以便从系统剪贴板向文档传送数据时在目标对象上触发。 <br />onpropertychange 当在对象上发生对象上发生属性更改时触发。 <br />onreadystatechange 当对象状态变更时触发。 <br />onreset 当用户重置表单时触发。 <br />onresize 当对象的大小将要改变时触发。 <br />onresizeend 当用户更改完控件选中区中对象的尺寸时触发。 <br />onresizestart 当用户开始更改控件选中区中对象的尺寸时触发。 <br />onrowenter 触发就表明当前行已经在数据源中更改，对象上有可用的新数据值。 <br />onrowexit 当数据源控件更改对象当前行前触发。 <br />onrowsdelete 当行将要从记录集中被删除时触发。 <br />onrowsinserted 当在当前记录集中插入新行后触发。 <br />onscroll 当用户滚动对象的滚动条时触发。 <br />onselect 当当前选中区改变时触发。 <br />onselectionchange 当文档的选中状态改变时触发。 <br />onselectstart 对象将要被选中时触发。 <br />onstart 在 marquee 对象的每次循环开始时触发。 <br />onstop 当用户单击停止按钮或离开 Web 页面时触发。 <br />onsubmit 当表单将要被提交时触发。 <br />onunload 在对象卸载前立即触发。&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177509#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 18 Mar 2008 11:00:41 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177509</link>
        <guid>http://ben-sin.javaeye.com/blog/177509</guid>
      </item>
      <item>
        <title>PB 读取大文件小例</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177511" style="color:red;">http://ben-sin.javaeye.com/blog/177511</a>&nbsp;
          发表时间: 2008年02月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          PB读取文件的时候，每次只能读取32K，所以当文件大于32K的时候就要分多次读取<br />以下是一个读取大于32K的文件并放在一个blob对象里面<br /><br />long ll_filelen, ll_read = 0<br />integer li_fileid<br />blob lblb_tmp, lblb_total<br />string ls_filepath, ls_content<br /><br />try<br />&nbsp;&nbsp;&nbsp; // 取得文件的长度<br />&nbsp;&nbsp;&nbsp; ll_filelen = FileLength ( ls_filepath )<br />&nbsp;&nbsp;&nbsp; // 打开文件并取得文件句柄<br />&nbsp;&nbsp;&nbsp; li_fileid = FileOpen (ls_filepath, StreamMode!, Read!,&nbsp; LockRead!)<br />&nbsp;&nbsp;&nbsp; // 成功打开文件<br />&nbsp;&nbsp;&nbsp; if li_fileid &gt; 0 then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 循环读取文件直至结束<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do while ll_read &lt; ll_filelen<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 读文件并记录位置<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ll_read = ll_read + fileRead(li_fileId, lblb_tmp)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将文件碎片汇总<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lblb_total = lblb_total + lblb_tmp<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 此处将文件转换为string类型<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_content = string(lblb_total, EncodingANSI!)<br />&nbsp;&nbsp;&nbsp; end if<br />catch(throwable ex)<br />&nbsp;&nbsp;&nbsp; // 异常处理<br />&nbsp;&nbsp;&nbsp; messagebox('Error', ex.text)<br />&nbsp;&nbsp;&nbsp; return -1<br />finally<br />&nbsp;&nbsp;&nbsp; // 最后关闭文件<br />&nbsp;&nbsp;&nbsp; fileClose(li_fileid)<br />end try
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177511#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Feb 2008 12:14:00 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177511</link>
        <guid>http://ben-sin.javaeye.com/blog/177511</guid>
      </item>
      <item>
        <title>合理利用DW完成PB的多表更新</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/177513" style="color:red;">http://ben-sin.javaeye.com/blog/177513</a>&nbsp;
          发表时间: 2008年01月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          案例：有一个业务需要同时更新两个或以上的表<br />分析：<br />同时更新两个表，简单一点的就是用其中一个表做DW更新，同时用SQL更新另外一个表；或者页trigger实现其他表的更新。但这样对于相类似的业务就无疑是大大增加工作量。而且维护不方便。<br />但我们细细考虑一下，DW作为PB的利器自然有他独到的地方。更新属性就好像是为了这种多表更新而设计的。<br />PB更新数据库的时候首先看更新的table,然后看需要更新的column。也就是说，只需要在更新的时候设置好更新属性，就可以方便的实现多表更新了。<br />步骤可以简单理解为：更新的时候将表1作为可更新表，表1的column作为可更新column。更新完后再设置表2作为可更新表，表2的column作为可更新column。<br /><br />实例：<br />假设有tabletbl_1(col_1, col_2), tbl_2(col_1, col3)<br /><br />那么，DW的SQL就是<br />select&nbsp; tbl_1.col_1, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; tbl_1.col_2,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tbl_2.col_3<br />&nbsp;&nbsp; from tbl_1, tbl_2<br />where tbl_1.col_1 = tbl_2.col_1<br /><br />当DW作了一系列操作后，在更新的时候执行以下script<br /><br />long ll_cnt = 0<br />int i = 0<br />string ls_table[2] = {'tbl_1', 'tbl_2&lsquo;}<br />string ls_col<br />string ls_col_dbname<br />string ls_update<br />string ls_updateable<br />string ls_error<br />boolean lb_update<br /><br />// 循环table列表，实现多表更新<br /> for i = 1 to upperBound(ls_table)<br />&nbsp;&nbsp;&nbsp; // 循环dw的column<br />&nbsp;&nbsp;&nbsp; for ll_cnt = 1 to long(dw_1.describe(&quot;DataWindow.Column.Count&quot;))<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_col = dw_1.describe(&quot;#&quot; + string(ll_cnt) + &quot;.name&quot;)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_col_dbname = dw_1.describe(&quot;#&quot; + string(ll_cnt) + &quot;.dbname&quot;)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 如果属于更新表的column或者key，设为可更新column<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 这里也可以将公共column也列作可更新column<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if pos(ls_col_dbname, ls_table + &quot;.&quot;) = 1 or &amp;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lower(dw_1.describe(&quot;#&quot; + string(ll_cnt) + &quot;.key&quot;)) = &quot;yes&quot; then<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_updateable = &quot;.update=yes&quot;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_updateable = &quot;.update=no&quot;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; end if<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ls_update += &quot;~t&quot; + ls_col + ls_updateable<br />&nbsp;&nbsp;&nbsp; next<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; // 设置更新table<br />&nbsp;&nbsp;&nbsp; ls_update += &quot;~tDataWindow.Table.UpdateTable='&quot; + ls_table[i] + &quot;'&quot;<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; // 更新设置无误后update<br />&nbsp;&nbsp;&nbsp; ls_error = dw_1.modify(ls_update)<br />&nbsp;&nbsp;&nbsp; if trim(ls_error) &lt;&gt; '' or ls_error &lt;&gt; '!' then<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if dw_1.update(true, false) = 1 then<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  lb_update = true<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lb_update = false<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  // 退出for循环<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end if<br />&nbsp;&nbsp;&nbsp; end if<br /><br />nex<br /><br />// 此处根据更新情况提交事务<br />if lb_update then<br />&nbsp;&nbsp;&nbsp; commit;<br />&nbsp;&nbsp;&nbsp; // 重设dw状态<br />&nbsp;&nbsp;&nbsp; dw_1.resetupdate()<br />else<br />&nbsp;&nbsp;&nbsp; rollback;<br />end if<br /><br />//到这里就完成了多表更新了
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/177513#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 22 Jan 2008 23:26:50 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/177513</link>
        <guid>http://ben-sin.javaeye.com/blog/177513</guid>
      </item>
      <item>
        <title>PB动态创建DW的两个例子</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/148651" style="color:red;">http://ben-sin.javaeye.com/blog/148651</a>&nbsp;
          发表时间: 2007年12月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          PB提供了关于如何动态创建Datawindow的相关函数<br />transaction.SyntaxFromSQL ( sqlselect, presentation, err )<br />dwcontrol.Create ( string syntax {, string errorbuffer } ) <br /><br />关于这两个方法如何使用，这里就不再陈述了，帮助里面已经很详细了(使用帮助是很好的习惯).<br /><br />例子1：动态创建有SQL的DW<br />说明：这个比较常用的方法，首先利用SQL得到DW的语法，然后用语法来创建DW<br />这过程跟创建可视化的DW，然后保存在PBL，在将这个保存的名字赋值给DW作为dataobject是同样的道理<br /><br />string ls_sql = ""<br />string ls_syntax = ""<br />string ls_err = ""<br /><br />// 初始化, SQL以oracle为例<br />// ls_sql = "select FIELDS from TABLE"<br />ls_sql = "select ‘’ as sID, '' as sName from dual"<br /><br />// 创建syntax, 用ls_sql创建一个grid类型的DW<br />sqlca.syntaxFromSQL(ls_sql, "style(type=grid)", ls_err)<br /><br />if len(ls_err) > 0 then<br />   messageBox('Error', ‘Create DW syntax failed! ~r~n’ + ls_err)<br />   return -1<br />end if<br /><br />// 创建DW<br />ls_err = ‘’<br />dw_1.create(ls_syntax, ls_err)<br /><br />if len(ls_err) > 0 then<br />   messageBox('Error', ‘Create DW failed! ~r~n’ + ls_err)<br />   return -1<br />end if<br /><br />// 创建成功<br />messageBox('Success', 'Create dynamic DW with SQL successful!')<br /><br />例子2：动态创建外部数据源的DW(没有SQL)<br />说明：外部数据源的DW没有SQL，但跟有SQL的DW相同的部分就是DW语法的table部分。<br />而创建DW的时候，对于例如区域、显示、HTML、update等等属性都有默认的设置。<br />所以无需用过份详细的syntax来创建DW，那部分将由PB帮助完成，我们只需要有table部分就可以了。<br /><br />string ls_syntax = ""<br />string ls_err = ""<br /><br />// 由SQL创建syntax部分可以省略<br />// 初始化syntax, release 9;表示PB9.0的例子<br />ls_syntax = "release 9;~r~n" +&<br />        "table(" +&<br />        " column=(type=number name=handle dbname=~"handle~" )~r~n" +&<br />        " column=(type=char(255) name=sdata dbname=~"sdata~" )~r~n" +&<br />        " column=(type=char(255) name=slabel dbname=~"slabel~" )~r~n" +&<br />        ")"<br /><br />// 创建DW<br />ls_err = ‘’<br />dw_1.create(ls_syntax, ls_err)<br /><br />if len(ls_err) > 0 then<br />   messageBox('Error', ‘Create DW failed! ~r~n’ + ls_err)<br />   return -1<br />end if<br /><br />// 创建成功<br />messageBox('Success', 'Create dynamic DW without SQL successful!')<br /><br />©All copyright resersed<br />Ben.Sin (Ben.BHX#gmail.com)
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/148651#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 16 Dec 2007 02:42:19 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/148651</link>
        <guid>http://ben-sin.javaeye.com/blog/148651</guid>
      </item>
      <item>
        <title>道理简单，谁能做到？</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/138010" style="color:red;">http://ben-sin.javaeye.com/blog/138010</a>&nbsp;
          发表时间: 2007年11月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          First: I love you not because of who you are, but because of who I am when I  am with you.<br />
<br />
Then: Just because someone doesn&lsquo;t love you the way you want  them to, doesn&lsquo;t mean they don&lsquo;t love you with all they have.<br />
<br />
But: No man  or woman is worth your tears, and the one who is, won&lsquo;t make you  cry.<br />
<br />
So: Don&lsquo;t cry because it is over, smile because it  happened.<br />
<br />
Later: Never frown, even when you are sad, because you never know  who is falling in love with your smile.
          <br/>
          <span style="color:red;">
            <a href="http://ben-sin.javaeye.com/blog/138010#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 Nov 2007 11:04:00 +0800</pubDate>
        <link>http://ben-sin.javaeye.com/blog/138010</link>
        <guid>http://ben-sin.javaeye.com/blog/138010</guid>
      </item>
      <item>
        <title>动态配置log4j</title>
        <author>Ben.Sin</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ben-sin.javaeye.com">Ben.Sin</a>&nbsp;
          链接：<a href="http://ben-sin.javaeye.com/blog/120171" style="color:red;">http://ben-sin.javaeye.com/blog/120171</a>&nbsp;
          发表时间: 2007年09月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>看到好的文章，收录以备学习之用。文章来源于<span style="font-family: Arial"><a href="http://www.javaresearch.org/article/11393.htm">http://www.javaresearch.org/article/11393.htm</a></span></p>
<p>二　动态配置log4j</p>
<p><br />
1&nbsp;配置外部配置文件来配置的基本步骤<br />
1.1　一个运用配置文件的实例<br />
Log4j之所以能成功的原因之一是它的灵活性。但如果只是简单的调用BasicConfigurator.configure()来进行配置工作，那么所有的配置都是在函数中写死的，以后修改配置就要修改原代码，这就不能体现出log4j的灵活性了，所以基本上不会通过BasicConfigurator.configure()来进行配置工作的。<br />
为了增加软件的灵活性，最常用的做法就是使用配置文件，如web.xml之于J2EE，struts-config.xml之于struts一样，log4j也提供了让我们把配置信息从程序转移到配置文件中的方法。Log4j提供了两种方式的配置文件：XML文件和Java的property配置文件。通过把配置信息转移到外部文件中，当我们要修改配置信息时，就可以直接修改配置文件而不用去修改代码了，下面，我们就来完成一个通过配置文件来实现log4j的实例。<br />
例2-a：<br />
package&nbsp;TestLog4j;<br />
import&nbsp;org.apache.log4j.Logger;<br />
import&nbsp;org.apache.log4j.BasicConfigurator;<br />
import&nbsp;org.apache.log4j.PropertyConfigurator;<br />
import&nbsp;org.apache.log4j.Priority;&nbsp;public&nbsp;class&nbsp;TestLog4j&nbsp;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp; static&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;Logger.getLogger(TestLog4j.class.getName());<br />
&nbsp;&nbsp;&nbsp; public&nbsp;TestLog4j(){}<br />
<br />
&nbsp;&nbsp;&nbsp; public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //通过BasicConfigurator类来初始化<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //BasicConfigurator.configure();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //（1）通过配置文件来初始化<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PropertyConfigurator.configure(&quot;F:\\nepalon\\log4j.properties&quot;);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug(&quot;Start&nbsp;of&nbsp;the&nbsp;main()&nbsp;in&nbsp;TestLog4j&quot;);　//代码（2）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info(&quot;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;INFO&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.warn(&quot;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;WARN&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error(&quot;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;ERROR&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.fatal(&quot;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;FATAL&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.log(Priority.WARN,&nbsp;&quot;Testing&nbsp;a&nbsp;log&nbsp;message&nbsp;use&nbsp;a&nbsp;alternate&nbsp;form&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug(TestLog4j.class.getName());　//代码（2）<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
在这个例子中，我们用PropertyConfigurator.configure(&quot;F:\\nepalon\\log4j.properties&quot;)代替BasicConfigurator.configure()进行配置。PropertyConfigurator.configure()函数的参数可以是一个properties文件所在路径的String对象，可以是一个properties文件所在路径的URL对象，也可以是一个properties对象。通过PropertyConfigurator.configure()可以通过指定的properties文件来配置信息。如果要用XML文件进行信息配置，可以在代码中调用DOMConfigurator()函数来进行配置工作。在这里，我们只以properties文件来完成例子。接着，我们来看一下log4j.properties文件中都有些什么东西：<br />
例2-b：<br />
log4j.rootLogger&nbsp;=&nbsp;DEBUG,&nbsp;A1<br />
log4j.appender.A1&nbsp;=&nbsp;org.apache.log4j.ConsoleAppender<br />
log4j.appender.A1.layout&nbsp;=&nbsp;org.apache.log4j.PatternLayout<br />
log4j.appender.A1.layout.ConversionPattern&nbsp;=&nbsp;%-4r&nbsp;[%t]&nbsp;%-5p&nbsp;%c&nbsp;%x&nbsp;-&nbsp;%m%n<br />
运行这个实例，运行结果为<br />
0&nbsp;[main]&nbsp;DEBUG&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Start&nbsp;of&nbsp;the&nbsp;main()&nbsp;in&nbsp;TestLog4j<br />
20&nbsp;[main]&nbsp;INFO&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;INFO<br />
20&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;WARN<br />
20&nbsp;[main]&nbsp;ERROR&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;ERROR<br />
20&nbsp;[main]&nbsp;FATAL&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;FATAL<br />
180&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Testing&nbsp;a&nbsp;log&nbsp;message&nbsp;use&nbsp;a&nbsp;alternate&nbsp;form<br />
180&nbsp;[main]&nbsp;DEBUG&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;TestLog4j.TestLog4j<br />
下面，我们分析一下这个配置文件。<br />
1)&nbsp;由于每一个Logger对旬都有一个级别，文件的第一行就是定义了一个Logger及其级别。在这里定义了一个根记录器&nbsp;&nbsp;&nbsp; （root&nbsp;logger），这涉及到记录器的层次问题，在些暂时不深入讨论，在后面的章节再进行讨论。<br />
2)&nbsp;第二行定义了一个名为A1的输出流，这个流就是控制台，所以通过Logger对象打印的信息会在控制台输出。<br />
3)&nbsp;第三行定义了打印信息的布局。在这里我们用PatternLayout作为此记录器的布局，PatternLayout允许你以灵活的格式来打印信息。<br />
4)&nbsp;第四行指定的打印信息的具体格式，从结果可知，这个实例的打印格式为：当前打印语句所使用的时间&nbsp;[日志所在的线程]&nbsp;打印的级别&nbsp;当前日志所在的类的全名&nbsp;日志信息。<br />
现在我们来修改一下这个记录器的级别，把第一行的DEBUG改为INFO，再运行程序，结果将变为：<br />
&nbsp;&nbsp;&nbsp; 0&nbsp;[main]&nbsp;INFO&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;INFO<br />
&nbsp;&nbsp;&nbsp; 10&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;WARN<br />
&nbsp;&nbsp;&nbsp; 10&nbsp;[main]&nbsp;ERROR&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;ERROR<br />
&nbsp;&nbsp;&nbsp; 10&nbsp;[main]&nbsp;FATAL&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;FATAL<br />
&nbsp;&nbsp;&nbsp; 10&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Testing&nbsp;a&nbsp;log&nbsp;message&nbsp;use&nbsp;a&nbsp;alternate&nbsp;form<br />
由于这个Logger的级别变为INFO，而代码（2）是调用debug()函数来输出日志信息时只能当记录器级别为DEBUG时才输出信息，所以代码（2）将不输出信息。</p>
<p><br />
1.2　实例原理<br />
1.2.1　初始化配置信息<br />
如果要通过JAVA的properties文件来配置信息，那么在代码中就要通过PropertyConfigurator.configure()函数从properties文件中加载配置信息，这个函数有三种参数形式：一个properties文件所在路径的String对象，可以是一个properties文件所在路径的URL对象，也可以是一个properties对象。如果要用XML文件来配置信息，则可用类型的<br />
DOMConfigurator()函数来从一个XML文件中加载配置信息。<br />
1.2.2　输出端Appender<br />
在上面的例子中，我们都是简单的把日志信息输出到控制台中。其实在log4j中还可以把日志信息输出到其它的输出端，对于同一个日志信息，我们还可以让它同时输出到多个输出端中，如同时在控制台和文件中进行打印。一个输出端就是一个appender。要在配置文件中定义一个appender有三步：<br />
1)&nbsp;在定义一个记录器的同时定义出该记录器的输出端appender。在例2的配置文件的第一句log4j.rootLogger&nbsp;=&nbsp;DEBUG,&nbsp;A1中，我们定义了一个根记录器，它的级别为DEBUG，它有一个appender名为A1。定义根记录器的格式为log4j.rootLogger&nbsp;=&nbsp;[&nbsp;level&nbsp;],&nbsp;appendName1,&nbsp;appendName2,&nbsp;&hellip;appendNameN。同一个记录器可有多个输出端。<br />
2)&nbsp;定义appender的输出目的地。定义一个appender的输出目的地的格式为log4j.appender.appenderName&nbsp;=&nbsp;fully.qualified.name.of.appender.class。log4j提供了以下几种常用的输出目的地：<br />
?&nbsp;org.apache.log4j.ConsoleAppender，将日志信息输出到控制台<br />
?&nbsp;org.apache.log4j.FileAppender，将日志信息输出到一个文件<br />
?&nbsp;org.apache.log4j.DailyRollingFileAppender，将日志信息输出到一个，并且每天输出到一个新的日志文件<br />
?&nbsp;org.apache.log4j.RollingFileAppender，将日志信息输出到一个文件，通过指定文件的的尺寸，当文件大小到达指定尺寸的时候会自动把文件改名，如名为example.log的文件会改名为example.log.1，同时产生一个新的example.log文件。如果新的文件再次达到指定尺寸，又会自动把文件改名为example.log.2，同时产生一个example.log文件。依此类推，直到example.log.&nbsp;MaxBackupIndex，MaxBackupIndex的值可在配置文件中定义。<br />
?&nbsp;org.apache.log4j.WriterAppender，将日志信息以流格式发送到任意指定的地方。<br />
?&nbsp;org.apache.log4j.jdbc.JDBCAppender，通过JDBC把日志信息输出到数据库中。<br />
在例2中，log4j.appender.A1&nbsp;=&nbsp;org.apache.log4j.ConsoleAppender定义了名为A1的appender的输出目的地为控制台，所以日志信息将输出到控制台。<br />
3)&nbsp;定义与所选的输出目的地相关的参数，定义格式为：<br />
log4j.appender.appenderName.optionName1&nbsp;=&nbsp;value1<br />
&hellip;&hellip;<br />
log4j.appender.appenderName.optionNameN&nbsp;=&nbsp;valueN<br />
其中一个最常用的参数layout将在下面介绍。<br />
1.2.3　输出格式（布局）layout<br />
通过appender可以控制输出的目的地，而如果要控制输出的格式，就可通过log4j的layout组件来实现。通过配置文件定义一个appender的输出格式，也通常需要两个步骤：<br />
1)&nbsp;定义appender的布局模式。定义一个appender的布局模式的格式为log4j.appender.appenderName.layout&nbsp;=&nbsp;fully.qualified.name.of.layout.class。Log4j提供的布局模式有以下几种：<br />
?&nbsp;org.apache.log4j.HTMLLayout，以HTML表格形式布局<br />
?&nbsp;org.apache.log4j.PatternLayout，可以灵活地指定布局模式<br />
?&nbsp;org.apache.log4j.SimpleLayout，包含日志信息的级别和信息字符串<br />
在例2　中log4j.appender.A1.layout&nbsp;=&nbsp;org.apache.log4j.PatternLayout定义了名为A1的appender的布局模式为PatternLayout。<br />
2)&nbsp;定义与所选的布局模式相关的设置信息，定义格式为：<br />
log4j.appender.appenderName.layout.optionName1&nbsp;=&nbsp;value1<br />
&hellip;&hellip;<br />
log4j.appender.appenderName.layout.optionNameN&nbsp;=&nbsp;valueN<br />
选择了不同的布局模式可能会有不同的设置信息。实例2所选的布局模式PatternLayout的一个PatternLayout为ConversionPattern&nbsp;，通过定义这个PatternLayout的值，我们可以指定输出信息的输出格式。在例2的配置文件中的定义如下log4j.appender.A1.layout.ConversionPattern&nbsp;=&nbsp;%-4r&nbsp;[%t]&nbsp;%-5p&nbsp;%c&nbsp;%x&nbsp;-&nbsp;%m%n。在下面，我们将介绍布局模式PatternLayout的参数ConversionPattern的各个值代表的含义。<br />
1.2.4　ConversionPattern参数的格式含义<br />
格式名&nbsp;含义<br />
%c&nbsp;输出日志信息所属的类的全名<br />
%d&nbsp;输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy-MM-dd&nbsp;HH:mm:ss&nbsp;}，输出类似：2002-10-18-&nbsp;22：10：28<br />
%f&nbsp;输出日志信息所属的类的类名<br />
%l&nbsp;输出日志事件的发生位置，即输出日志信息的语句处于它所在的类的第几行<br />
%m&nbsp;输出代码中指定的信息，如log(message)中的message<br />
%n&nbsp;输出一个回车换行符，Windows平台为&ldquo;\r\n&rdquo;，Unix平台为&ldquo;\n&rdquo;<br />
%p&nbsp;输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL。如果是调用debug()输出的，则为DEBUG，依此类推<br />
%r&nbsp;输出自应用启动到输出该日志信息所耗费的毫秒数<br />
%t&nbsp;输出产生该日志事件的线程名<br />
1.3　定义多个输出目的地的实例<br />
从上面的实例原理中我们已经知道，同一个日志信息可以同时输出到多个输出目的地，在这个例子中，我们将实现一个把日志信息同时输出到控制器、一个文件中的实例和数据库中。这个实例的Java代码我们沿用例2中的代码，我们只需修改配置文件即可。这也体现了log4j的灵活性。<br />
例3-a：<br />
create&nbsp;table&nbsp;log4j(<br />
&nbsp;&nbsp;&nbsp; logID&nbsp;int&nbsp;primary&nbsp;key&nbsp;identity,<br />
&nbsp;&nbsp;&nbsp; message&nbsp;varchar(1024),<br />
&nbsp;&nbsp;&nbsp; priority&nbsp;varchar(10),<br />
&nbsp;&nbsp;&nbsp; milliseconds&nbsp;int,<br />
&nbsp;&nbsp;&nbsp; category&nbsp;varchar(256),<br />
&nbsp;&nbsp;&nbsp; thread&nbsp;varchar(100),<br />
&nbsp;&nbsp;&nbsp; NDC&nbsp;varchar(256),<br />
&nbsp;&nbsp;&nbsp; createDate&nbsp;datetime,<br />
&nbsp;&nbsp;&nbsp; location&nbsp;varchar(256),<br />
&nbsp;&nbsp;&nbsp; caller&nbsp;varchar(100),<br />
&nbsp;&nbsp;&nbsp; method&nbsp;varchar(100),<br />
&nbsp;&nbsp;&nbsp; filename&nbsp;varchar(100),<br />
&nbsp;&nbsp;&nbsp; line&nbsp;int<br />
)<br />
例3-b：<br />
#1&nbsp;定义了两个输出端<br />
log4j.rootLogger&nbsp;=&nbsp;INFO,&nbsp;A1,&nbsp;A2,A3<br />
<br />
#2&nbsp;定义A1输出到控制器<br />
log4j.appender.A1&nbsp;=&nbsp;org.apache.log4j.ConsoleAppender<br />
#3&nbsp;定义A1的布局模式为PatternLayout<br />
log4j.appender.A1.layout&nbsp;=&nbsp;org.apache.log4j.PatternLayout<br />
#4&nbsp;定义A1的输出格式<br />
log4j.appender.A1.layout.ConversionPattern&nbsp;=&nbsp;%-4r&nbsp;[%t]&nbsp;%-5p&nbsp;%c&nbsp;-&nbsp;%m%n<br />
<br />
#5&nbsp;定义A2输出到文件<br />
log4j.appender.A2&nbsp;=&nbsp;org.apache.log4j.RollingFileAppender<br />
#6&nbsp;定义A2要输出到哪一个文件<br />
log4j.appender.A2.File&nbsp;=&nbsp;F:\\nepalon\\classes\\example3.log<br />
#7&nbsp;定义A2的输出文件的最大长度<br />
log4j.appender.A2.MaxFileSize&nbsp;=&nbsp;1KB<br />
#8&nbsp;定义A2的备份文件数<br />
log4j.appender.A2.MaxBackupIndex&nbsp;=&nbsp;3<br />
#9&nbsp;定义A2的布局模式为PatternLayout<br />
log4j.appender.A2.layout&nbsp;=&nbsp;org.apache.log4j.PatternLayout<br />
#10&nbsp;定义A2的输出格式<br />
log4j.appender.A2.layout.ConversionPattern&nbsp;=&nbsp;%d{yyyy-MM-dd&nbsp;hh:mm:ss}:%p&nbsp;%t&nbsp;%c&nbsp;-&nbsp;%m%n<br />
<br />
#11区&nbsp;定义A3输出到数据库<br />
log4j.appender.A3&nbsp;=&nbsp;org.apache.log4j.jdbc.JDBCAppender<br />
log4j.appender.A3.BufferSize&nbsp;=&nbsp;40<br />
log4j.appender.A3.Driver&nbsp;=&nbsp;com.microsoft.jdbc.sqlserver.SQLServerDriver<br />
log4j.appender.A3.URL&nbsp;=&nbsp;jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=nepalon<br />
log4j.appender.A3.User&nbsp;=&nbsp;sa<br />
log4j.appender.A3.Password&nbsp;=&nbsp;<br />
log4j.appender.A3.layout&nbsp;=&nbsp;org.apache.log4j.PatternLayout<br />
log4j.appender.A3.layout.ConversionPattern&nbsp;=&nbsp;INSERT&nbsp;INTO&nbsp;log4j&nbsp;(createDate,&nbsp;thread,&nbsp;priority,&nbsp;category,&nbsp;message)&nbsp;values(getdate(),&nbsp;'%t',&nbsp;'%-5p',&nbsp;'%c',&nbsp;'%m')<br />
配置文件中的6、7、8行显示了输出端为RollingFileAppender的特有参数及其运用的方法。11区显示了输出端为JDBCAppender的特有参数及其运用方法。在这着重讲解一下6、7、8行的作用。6行指定日志信息输出到哪个文件，7行指定日志文件的最大长度，最后要详细介绍8行。第8行的参数是设置备份文件的个数的参数，在这里我们设置为3，表示最多有3个备份文件，具体作用为：<br />
1)&nbsp;当example3.log文件的大小超过K时，就把文件改名为example3.log.1，同时生成一个新的example3.log文件<br />
2)&nbsp;当example3.log文件的大小再次超过1K，又把文件改名为example3.log.1。但由于此时example3.log.1已存在，则先把example3.log.1更名为example3.log.2，再把example3.log文件改名为example3.log.1<br />
3)&nbsp;同理，当example3.log文件的大小再次超过1K，先把example3.log.2文件更名为example3.log.3，把example3.log.1文件更名为example3.log.2，再把example3.log文件改名为example3.log.1<br />
4)&nbsp;当example3.log文件的大小再次超过1K，先把example3.log.2文件更名为example3.log.3，旧的example3.log.3文件将被覆盖；把example3.log.1文件更名为example3.log.2，旧的example3.log.2文件被覆盖；最后把example3.log文件改名为example3.log.1并覆盖掉旧的example3.log.1文件。<br />
运行结果将分为两部分<br />
在控制器中：<br />
0&nbsp;[main]&nbsp;INFO&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;INFO<br />
11&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;WARN<br />
21&nbsp;[main]&nbsp;ERROR&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;ERROR&nbsp;21&nbsp;[main]&nbsp;FATAL&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;set&nbsp;to&nbsp;FATAL<br />
21&nbsp;[main]&nbsp;WARN&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Testing&nbsp;a&nbsp;log&nbsp;message&nbsp;use&nbsp;a&nbsp;alternate&nbsp;form<br />
在文件example3.log中：<br />
2003-12-18&nbsp;04:23:02:INFO&nbsp;main&nbsp;TestLog4j.TestLog4j&nbsp;-&nbsp;Just&nbsp;testing&nbsp;a&nbsp;log&nbsp;message&nbsp;with&nbsp;priority&nbsp;s