<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>wyl232</title>
    <description></description>
    <link>http://wyl232.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>jq插件之仿“卓越亚马逊”首页弹出菜单效果 </title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/230207" style="color:red;">http://wyl232.javaeye.com/blog/230207</a>&nbsp;
          发表时间: 2008年08月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="color: #008000;"><a href="http://www.cnblogs.com/regedit/archive/2008/07/02/1234340.html" class="postTitle2" id="AjaxHolder_ctl01_TitleUrl">jq插件之仿&ldquo;卓越亚马逊&rdquo;首页弹出菜单效果</a><span style="color: #000000;"> </span></span></p>
<p><span style="color: #008000;">转自<a href="http://www.cnblogs.com/regedit/archive/2008/07/02/1234340.html">http://www.cnblogs.com/regedit/archive/2008/07/02/1234340.html</a></span></p>
<p><span style="color: #008000;">/*</span><span style="color: #008000;">弹出式菜单</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /></span><span style="color: #008000;">//</span><span style="color: #008000;">没剑&nbsp;2008-07-03</span><span style="color: #008000;"><br />//</span><span style="color: #008000;">http://regedit.cnblogs.com</span><span style="color: #008000;"><br />/*</span><span style="color: #008000;">参数说明</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /></span><span style="color: #008000;">//</span><span style="color: #008000;">showobj:要显示的菜单ID</span><span style="color: #008000;"><br />//</span><span style="color: #008000;">timeout：延时时间,鼠标停留/离开后延时多久开始显示/隐藏菜单</span><span style="color: #008000;"><br />//</span><span style="color: #008000;">speed：菜单显示速度，数字越大，显示越慢,默认为100</span><span style="color: #008000;"><br />//</span><span style="color: #008000;">调用示例:$("#button").DMenu("#content");</span><span style="color: #008000;"><br /></span><span style="color: #000000;">jQuery.fn.DMenu</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(showobj,timeout,speed){<br />&nbsp;&nbsp;&nbsp;&nbsp;timeout</span><span style="color: #000000;">=</span><span style="color: #000000;">timeout</span><span style="color: #000000;">?</span><span style="color: #000000;">timeout:</span><span style="color: #000000;">300</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;speed</span><span style="color: #000000;">=</span><span style="color: #000000;">speed</span><span style="color: #000000;">?</span><span style="color: #000000;">speed:</span><span style="color: #000000;">100</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">按钮对象</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;button</span><span style="color: #000000;">=</span><span style="color: #000000;">$(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">延时计数器</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;timer</span><span style="color: #000000;">=</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">隐藏的浮动层</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;hideDiv</span><span style="color: #000000;">=</span><span style="color: #000000;">$(</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;div&gt;&lt;/div&gt;</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">容器对象</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;Container</span><span style="color: #000000;">=</span><span style="color: #000000;">$(</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;div&nbsp;id=\</span><span style="color: #000000;">"</span><span style="color: #000000;">Container\</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;&lt;/div&gt;</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />&nbsp;&nbsp;&nbsp;&nbsp;Container.hide();<br />&nbsp;&nbsp;&nbsp;&nbsp;hideDiv.append(Container);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">菜单对象</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;jqShowObj</span><span style="color: #000000;">=</span><span style="color: #000000;">$(showobj);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">隐藏菜单</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;jqShowObj.hide();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">菜单显示的状态</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;display</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">按钮的offset</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;offset</span><span style="color: #000000;">=</span><span style="color: #000000;">button.offset();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">菜单区高</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;height</span><span style="color: #000000;">=</span><span style="color: #000000;">jqShowObj.height();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">菜单区宽</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;width</span><span style="color: #000000;">=</span><span style="color: #000000;">jqShowObj.width();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">按钮的高</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;btnHeight</span><span style="color: #000000;">=</span><span style="color: #000000;">button.height();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">按钮的宽</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;btnWidth</span><span style="color: #000000;">=</span><span style="color: #000000;">button.width();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定位层放到最前面</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;$(document.body).prepend(hideDiv);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">放到容器中</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Container.append(jqShowObj);</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">****显示菜单方法开始****//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;showMenu</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">如果菜单为显示则退出操作</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(display)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">设置容器属性</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;margin:</span><span style="color: #000000;">"</span><span style="color: #000000;">0&nbsp;auto</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width:btnWidth</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height:btnHeight</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定位隐藏层</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hideDiv.css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position:</span><span style="color: #000000;">"</span><span style="color: #000000;">absolute</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;top:offset.top</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left:offset.left</span><span style="color: #000000;">+</span><span style="color: #000000;">(btnWidth</span><span style="color: #000000;">/</span><span style="color: #000000;">2)-(width</span><span style="color: #000000;">/</span><span style="color: #000000;">2</span><span style="color: #000000;">)</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height:height</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width:width</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">px</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}).show();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">给容器加个黑边框</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;border:</span><span style="color: #000000;">"</span><span style="color: #000000;">1px&nbsp;solid&nbsp;#666666</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">显示定位层</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">高宽慢慢增大</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.animate({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marginTop:btnHeight</span><span style="color: #000000;">+</span><span style="color: #000000;">4</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height:height</span><span style="color: #000000;">+</span><span style="color: #000000;">4</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width:width</span><span style="color: #000000;">+</span><span style="color: #000000;">4</span><span style="color: #000000;">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opacity:</span><span style="color: #000000;">'</span><span style="color: #000000;">100</span><span style="color: #000000;">'</span><span style="color: #000000;">},speed,</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">动画结束时&nbsp;start//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">显示菜单</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jqShowObj.show();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">添加菜单入容器</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.append(jqShowObj);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">去除边框</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;border:</span><span style="color: #000000;">"</span><span style="color: #000000;">0px</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">显示状态置为true</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display</span><span style="color: #000000;">=</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">鼠标移入</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jqShowObj.mouseover(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clearTimeout(timer);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">鼠标移开</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jqShowObj.mouseout(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hideMenu();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">动画结束时&nbsp;end//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">****显示菜单方法结束****//</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">****隐藏菜单方法开始****//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">var</span><span style="color: #000000;">&nbsp;hideMenu</span><span style="color: #000000;">=</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clearTimeout(timer);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">延时隐藏菜单</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer</span><span style="color: #000000;">=</span><span style="color: #000000;">setTimeout(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">显示边框</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;border:</span><span style="color: #000000;">"</span><span style="color: #000000;">1px&nbsp;solid&nbsp;#666666</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">清空容器</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.empty();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">收缩容器</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.animate({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width:btnWidth,height:btnHeight,marginTop:</span><span style="color: #000000;">'</span><span style="color: #000000;">0</span><span style="color: #000000;">'</span><span style="color: #000000;">,&nbsp;opacity:&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">0</span><span style="color: #000000;">'</span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;speed,</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">动画结束时&nbsp;start//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">隐藏容器</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Container.hide();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定位层隐藏</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hideDiv.hide();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">显示状态置为false</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">动画结束时&nbsp;end//</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;timeout);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">****隐藏菜单方法结束****//</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">绑定按钮鼠标经过事件</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;button.hover(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(e){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">延时显示菜单</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clearTimeout(timer);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer</span><span style="color: #000000;">=</span><span style="color: #000000;">setTimeout(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;showMenu();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;timeout);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;},</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clearTimeout(timer);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">鼠标离开按钮时，如果菜单还是显示状态则隐藏</span><span style="color: #008000;"><br /></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(display){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer</span><span style="color: #000000;">=</span><span style="color: #000000;">setTimeout(</span><span style="color: #0000ff;">function</span><span style="color: #000000;">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hideMenu();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},timeout);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;});<br />};</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/230207#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Aug 2008 17:07:27 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/230207</link>
        <guid>http://wyl232.javaeye.com/blog/230207</guid>
      </item>
      <item>
        <title>疑问，我这样操作后还是不行，不出现提示</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/227894" style="color:red;">http://wyl232.javaeye.com/blog/227894</a>&nbsp;
          发表时间: 2008年08月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>首先用Eclipse创建一个WEB项目.<br />&nbsp;<a href="http://www.yiboit.com/batch.download.php?aid=1553" target="_blank"><img src="http://www.yiboit.com/attachments/2007/11/7_200711280851311.jpg" border="0" alt="" style="width: 400px;" /></a><br />再用MyEclipse 的自动功能给项目增加Tapestry的能力.向导中都选默认就可.直到完成.<br />&nbsp;<a href="http://www.yiboit.com/batch.download.php?aid=1554" target="_blank"><img src="http://www.yiboit.com/attachments/2007/11/7_200711280851312.jpg" border="0" alt="" style="width: 400px;" /></a><br />完成后目录结构如下:</p>
<p>&nbsp;<a href="http://www.yiboit.com/batch.download.php?aid=1555" target="_blank"><img src="http://www.yiboit.com/attachments/2007/11/7_200711280851313.jpg" border="0" alt="" /></a><br />但是一个问题,MyEclipse用的T3的库和文件<br />只是需要把T4的库覆盖了就可以了.<br />&nbsp;在T4里有几种XML文件,扩展名是.application 和.page的.需要配一下MyEclipse XML Editor.需要修改如下<br />单击菜单 窗口-&gt;首选项 ,出现首选项对话框;<br />然后选择左面的目录树:常规-&gt;编辑器-&gt;文件关联<br />选择右上的文件类型 *.application,下面的相关联的文件编辑器点添加,选择MyEclipse XML Editor,这样就可以用MyEclipse XML Editor来编辑.application了.同样给.page的文件添加相关联的编辑器.<br />&nbsp;然后点击右上角的文字超链接"内容类型",选"文本"-&gt;XML .下面的文件关联添加两项*.page 和 *.application 点确定就可以了.<br />&nbsp;以上的设定就是想用MyEclipse XML Editor来编写T4的XML文件.\<br />如果想加编辑代码提示还要做如下设置:<br />&nbsp;在首选项对话框里找到MyEclipse-&gt;Files and Editor-&gt;XML-&gt;XML catalog <br />做如下配置<br />&nbsp;<a href="http://www.yiboit.com/batch.download.php?aid=1556" target="_blank"><img src="http://www.yiboit.com/attachments/2007/11/7_200711280851314.jpg" border="0" alt="" style="width: 400px;" /></a><br />这样写XML就会有提示了:看看效果:&nbsp; </p>
<p><a href="http://www.yiboit.com/batch.download.php?aid=1557" target="_blank"><img src="http://www.yiboit.com/attachments/2007/11/7_200711280851315.jpg" border="0" alt="" style="width: 400px;" /></a><br />代码提示只是方便我们写配置文件了,有些东西不用死记硬背了。但配置标记和相应的属性都要很好的去研究理解. </p>
<p>&nbsp;</p>
<p>这样配置后 还是不能出现提示，哪里有问题呢？请各位老大指教！</p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/227894#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 14 Aug 2008 09:34:44 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/227894</link>
        <guid>http://wyl232.javaeye.com/blog/227894</guid>
      </item>
      <item>
        <title>window.opener 的用法</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/226622" style="color:red;">http://wyl232.javaeye.com/blog/226622</a>&nbsp;
          发表时间: 2008年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          window.opener 的用法 
   window.opener 返回的是创建当前窗口的那个窗口的引用，比如点击了a.htm上的一个链接而打开了b.htm，然后我们打算在b.htm上输入一个值然后赋予a.htm上的一个id为“name”的textbox中，就可以写为： 
    
   window.opener.document.getElementById("name").value = "输入的数据"; 
    
    
   对于javascript中的window.opener没有很好的理解。 
   为什么框架中不能使用，弹出窗口的父窗口不能在框架里面的某个页面呢？那怎样通过弹出窗口操作框架中的父窗口呢？ 
    
   opener.parent.frames['frameName'].document.all.input1.value 试试这个：）

   转：
在一般的用法中，只是用来解决关闭窗口时不提示弹出窗口， 而对它更深层的了解一般比较少。其 实 window.opener是指调用window.open方法的窗口。
在工作中主要是用来解决部分提交的。这种跨页操作对工作是非常有帮助的。
如果你在主窗口打开了一个页面，并且希望主窗口刷新就用这个，打开页面的window.opener就相当于
主窗口的window。
主窗口的刷新你可以用
window.opener.location.reload()；
如果你用虚拟的目录：如struts的*.do会提示你重试

你可以改成这样 window.opener.yourformname.submit()
就好了
2〉

在应用中有这样一个情况，
在A窗口中打开B窗口，在B窗口中操作完以后关闭B窗口，同时自动刷新A窗口


function closeWin(){
hasClosed = true;
window.opener.location="javascript:reloadPage();";
window.close();
}
function window.onbeforeunload(){
if(!hasClosed){
window.opener.location="javascript:reloadPage();";
}
}


上面的代码在关闭B窗口的时候会提示错误，说缺少Object,正确的代码如下：
function closeWin(){
hasClosed = true;
window.opener.location="javascript:reloadPage();";
window.opener=null;
window.close();
}
function window.onbeforeunload(){
if(!hasClosed){//如果已经执行了closeWin方法，则不执行本方法
window.opener.location="javascript:reloadPage();";
}
}


reloadPage方法如下:
function reloadPage() {
history.go(0);
document.execCommand("refresh")
document.location = document.location;
document.location.reload();
}
PS:由于需要支持正常关闭和强制关闭窗口时能捕捉到事件，用了全局变量hasClosed

==============================================

补充，在父窗口是frame的时候在刷新父窗口的时候会出现问题:

The page cannot be refreshed without resending the information.
后修改如下: 
window.opener.parent.document.frames.item('mainFrame').location.href = window.opener.location.href;
不需要执行自带的reload()方法,注意，不要再画蛇添足加上这一句:

window.opener.parent.document.frames.item('mainFrame').location.reload();

========================================================================================
最后，为了同时支持刷新普通父窗口和frame父窗口，代码如下:
function closeWin() {
hasClosed = true;
<%if(null != frame){%>
window.opener.parent.document.frames.item('mainFrame').location.href = window.opener.location.href;
<%}else{%>
window.opener.location = "javascript:reloadPage();";
<%}%>
//window.opener.top.mainFrame.location="javascript:reloadPage();";
//self.opener.frames.mainFrame.location.reload(true);
window.opener = null;
window.close();
}
function window.onbeforeunload(){
if (!hasClosed) {
<%if(null != frame){%>
window.opener.parent.document.frames.item('mainFrame').location.href = window.opener.location.href;
<%}else{%>
window.opener.location = "javascript:reloadPage();";
<%}%>
window.opener = null;
}
} 
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/226622#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 11 Aug 2008 15:00:06 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/226622</link>
        <guid>http://wyl232.javaeye.com/blog/226622</guid>
      </item>
      <item>
        <title>showModalDialog模式窗口提交打开新页面的解决办法</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/225034" style="color:red;">http://wyl232.javaeye.com/blog/225034</a>&nbsp;
          发表时间: 2008年08月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1.在head区加入&lt;base target="_self"/&gt; <br />2.</p>
<p>window.showModalDialog("xxx.htm") &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; xx.htm &nbsp; <br />&nbsp; ====================&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; &lt;frameset &nbsp; rows="0,*"&gt; &nbsp; <br />&nbsp; &lt;frame &nbsp; src="about:blank"&gt; &nbsp; <br />&nbsp; &lt;frame &nbsp; src="xxx.asp"&gt; &nbsp; <br />&nbsp; &lt;/frameset&gt; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; xxx.asp &nbsp; <br />&nbsp; ========= &nbsp; <br />&nbsp; &lt;form &nbsp; target="_self" &nbsp; method=post&gt;</p>
<p>&nbsp;</p>
<p>或者 </p>
<p>&lt;script language="javascript"&gt;&nbsp;&nbsp;<br /><br />window.name="win_test" <br />&lt;/script&gt; <br />&lt;form action=""&nbsp;&nbsp;target="win_test"&gt; <br />&lt;/form&gt; </p>
<p>&nbsp;</p>
<p>&lt;head&gt;之间加入<br />&lt;BASE target=_self&gt;</p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/225034#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 06 Aug 2008 15:37:37 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/225034</link>
        <guid>http://wyl232.javaeye.com/blog/225034</guid>
      </item>
      <item>
        <title>eclipse 插件implementors </title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/222062" style="color:red;">http://wyl232.javaeye.com/blog/222062</a>&nbsp;
          发表时间: 2008年07月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>如今用spring ioc容器进行接口注入，会给程序带来极大的灵活性，编程过程中要想查看一个对象的方法时一般要按注Ctrl键再单击左键就会跳转过去，可是面向接口编程时这样做会跳到接口里，有没有好方法可以直接跳到接口的实现代码中，有！implementors可以做到强烈推荐大家安装！ <br /><strong>插件名称：</strong> implementors <br /><strong>更新地址：</strong> <br /><br /><a href="http://eclipse-tools.sourceforge.net/updates" target="_blank"><span style="color: #006699;">http://eclipse-tools.sourceforge.net/updates</span></a> <br /><br /><strong>安装步骤：</strong> <br />进入 Help -&gt; Soft Ware Updates -&gt; Find and Install... -&gt; Search for new features to install -&gt; Next <br />-&gt; New Remote Site ， 输入Name: eclipse-tools， URL: http://eclipse-tools.sourceforge.net/updates <br />-&gt; Finish， 选择 implementors。 <br /><br /><strong>使用方法：</strong> <br /><br />光标定位到调用某接口某方法的代码处，按 Alt + F3，即可跳到代码实现处！ </p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/222062#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 31 Jul 2008 09:48:16 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/222062</link>
        <guid>http://wyl232.javaeye.com/blog/222062</guid>
      </item>
      <item>
        <title>Hibernate Tool </title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/221062" style="color:red;">http://wyl232.javaeye.com/blog/221062</a>&nbsp;
          发表时间: 2008年07月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div>1．使用环境</div>
<div>eclipse 3.2.1</div>
<div>HibernateTools-3.2.0.beta8<span>&nbsp;&nbsp; (<span style="color: #333333;"><a href="http://www.hibernate.org/255.html">http://www.hibernate.org/255.html</a></span>)</span></div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>把HibernateTools下的features plugins 拷贝到eclipse下就可以了</div>
<p><span>
<div>简单说一下HibernateTools的使用思路，在cfg.xml中定义基本的数据库配置，反向工程文件reveng.xml中定义需要映射的库表，code gen工具来定义想要生成哪些文件，目标路径，包名，然后生产代码，console中进行可视化管理，调试hql语句等。</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>2．配置configuration file</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>Ctril + N 打开新建窗口</div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/new%20window.jpg" border="0" alt="" /></div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/cfg.jpg" border="0" alt="" /></div>
<span>
<div>需要注意的是 Database dialect: 输入框的内容最好从下拉条中选，直接写的话一定要注意大小写</div>
<div>点击 finish 后cfg.xml就生成出来了</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>3．配置 hibernate console</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>hibernate console是个比较非常方便的工具，尤其是其中的hql和 criteira 的编辑器非常好，可以直接写语句运行，然后查看结果集和生成的sql语句。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div><span style="font-size: 10.5pt;">Ctril + N </span><span style="font-size: 10.5pt;">打开新建窗口，选择</span><span style="font-size: 10.5pt;">Hibernate Console Configration</span></div>
<div><span style="font-size: 10.5pt;"><img src="http://www.zhuoda.org/upload/irini/blog/console%20cfg.jpg" border="0" alt="" /></span></div>
<span style="font-size: 10.5pt;">
<div>要填的就是 Name，Configration file (选择刚配好的cfg.xml)，还有就是在Classpath 框中添加数据库驱动的jar包，Finish 后就ok了。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div><span style="font-size: 10.5pt;">打开</span><span style="font-size: 10.5pt;">Hibernate Console Perspective</span><span style="font-size: 10.5pt;">窗口</span></div>
<div><span style="font-size: 10.5pt;"><img src="http://www.zhuoda.org/upload/irini/blog/console%20window.jpg" border="0" alt="" /></span></div>
<span style="font-size: 10.5pt;">
<p>现在就可以看到我们连接的数据库了，等后面我们把映射文件和类生成出来后在这就可以看到他们了 </p>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>4．配置reverse engineering file</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>这个文件是用来根据数据库反向生成hbm.xml 和 pojo 的</div>
<div>Ctril + N 打开新建窗口，选择 Hibernate Reverse Engineering File(reveng.xml)</div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/reveng.jpg" border="0" alt="" /></div>
<div>在这选择配好的 console configuration file，finish后生成hibernate.reveng.xml，打开这个文件，可以看到 overview 标签，选择一个Console Configration，然后打开 Table &amp; Colunm 标签，用add按钮来添加想要映射的表，根据需要配置好后保存。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>5．代码生成</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div><img src="http://www.zhuoda.org/upload/irini/blog/code%20gen.jpg" border="0" alt="" /></div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/code%20gen2.jpg" border="0" alt="" /></div>
<div>可以在Exporters 标签中设置你想要的生成文件，都配置好后Run，想要的文件就都生成好了。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>现在我们要把生成的文件加到console中，切换到Hibernate Console Perspective窗口，右键点击上面生成的console的名字，选择Edit Configration，打开了console的配置框，在Classpath栏中添加生成的类文件的目录，我直接填了项目的bin目录，因为里面什么都有了，以后也不用在添别的目录了。</div>
<div>还要记得在cfg.xml中添加生成的hbm.xml文件。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>现在进入Hibernate Console Perspective窗口，打开Configration和SessionFactory就可以看到我们映射的类了，如果看不到就再打开一次Edit Configration窗口，什么也不改，直接按finish，相信就可以了。如果打开SessionFactory时出现异常，肯定是cfg.xml中映射文件的路径写错了。</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>6．HQL Editor</div>
<p>&nbsp;</p>
<div>&nbsp;</div>
<p>&nbsp;</p>
<div>Hibernate Console Perspective窗口中右键打开&ldquo;HQL Editor&rdquo;，输入hql语句</div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/hql%20editor.jpg" border="0" alt="" /></div>
<div>ctrl+shift+f 格式化语句，点击绿前头执行。</div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/hql%20ret.jpg" border="0" alt="" /></div>
<span>
<div>在Query Result窗口中就可以看到结果</div>
<div><img src="http://www.zhuoda.org/upload/irini/blog/hql%20sql.jpg" border="0" alt="" /></div>
<span>
<p>查看sql时要注意，上面写的hql一定要是格式化后的，不然会找不到hql语句的。</p>
</span></span></span></span></span></span></p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/221062#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 29 Jul 2008 14:25:27 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/221062</link>
        <guid>http://wyl232.javaeye.com/blog/221062</guid>
      </item>
      <item>
        <title>数据库设计中的14个技巧</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/219558" style="color:red;">http://wyl232.javaeye.com/blog/219558</a>&nbsp;
          发表时间: 2008年07月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>【转】</p>
<p>1. 原始单据与实体之间的关系 </p>
<p>　　可以是一对一、一对多、多对多的关系。在一般情况下，它们是一对一的关系：即一张原始单据对应且只对应一个实体。在特殊情况下，它们可能是一对多或多对一的关系，即一张原始单据对应多个实体，或多张原始单据对应一个实体。这里的实体可以理解为基本表。明确这种对应关系后，对我们设计录入界面大有好处。 </p>
<p>　　〖例1〗：一份员工履历资料，在人力资源信息系统中，就对应三个
<script src="../../../CMS/JS/newsad.js"></script>
基本表：员工基本情况表、社会关系表、工作简历表。这就是&ldquo;一张原始单据对应多个实体&rdquo;的典型例子。 </p>
<p>　　2. 主键与外键 </p>
<p>　　一般而言，一个实体不能既无主键又无外键。在E－R 图中, 处于叶子部位的实体, 可以定义主键，也可以不定义主键(因为它无子孙), 但必须要有外键(因为它有父亲)。 </p>
<p>　　主键与外键的设计，在全局数据库的设计中，占有重要地位。当全局数据库的设计完成以后，有个美国数据库设计专家说：&ldquo;键，到处都是键，除了键之外，什么也没有&rdquo;，这就是他的数据库设计经验之谈，也反映了他对信息系统核心(数据模型)的高度抽象思想。因为：主键是实体的高度抽象，主键与外键的配对，表示实体之间的连接。 </p>
<p>　　3. 基本表的性质 </p>
<p>　　基本表与中间表、临时表不同，因为它具有如下四个特性： </p>
<p>　　(1) 原子性。基本表中的字段是不可再分解的。 </p>
<p>　　(2) 原始性。基本表中的记录是原始数据（基础数据）的记录。 </p>
<p>　　(3) 演绎性。由基本表与代码表中的数据，可以派生出所有的输出数据。 </p>
<p>　　(4) 稳定性。基本表的结构是相对稳定的，表中的记录是要长期保存的。 </p>
<p>　　理解基本表的性质后，在设计数据库时，就能将基本表与中间表、临时表区分开来。 </p>
<p>　　4. 范式标准 </p>
<p>　　基本表及其字段之间的关系, 应尽量满足第三范式。但是，满足第三范式的数据库设计，往往不是最好的设计。为了提高数据库的运行效率，常常需要降低范式标准：适当增加冗余，达到以空间换时间的目的。 </p>
<p>　　〖例2〗：有一张存放商品的基本表，如表1所示。&ldquo;金额&rdquo;这个字段的存在，表明该表的设计不满足第三范式，因为&ldquo;金额&rdquo;可以由&ldquo;单价&rdquo;乘以&ldquo;数量&rdquo;得到，说明&ldquo;金额&rdquo;是冗余字段。但是，增加&ldquo;金额&rdquo;这个冗余字段，可以提高查询统计的速度，这就是以空间换时间的作法。 </p>
<p>　　在Rose 2002中，规定列有两种类型：数据列和计算列。&ldquo;金额&rdquo;这样的列被称为&ldquo;计算列&rdquo;，而&ldquo;单价&rdquo;和&ldquo;数量&rdquo;这样的列被称为&ldquo;数据列&rdquo;。 </p>
<p>　　表1 商品表的表结构 </p>
<p>　　商品名称 商品型号 单价 数量 金额 </p>
<p>　　电视机 29吋 2,500 40 100,000 </p>
<p>　　5. 通俗地理解三个范式 </p>
<p>　　通俗地理解三个范式，对于数据库设计大有好处。在数据库设计中，为了更好地应用三个范式，就必须通俗地理解三个范式(通俗地理解是够用的理解，并不是最科学最准确的理解)： </p>
<p>　　第一范式：1NF是对属性的原子性约束，要求属性具有原子性，不可再分解； </p>
<p>　　第二范式：2NF是对记录的惟一性约束，要求记录有惟一标识，即实体的惟一性； </p>
<p>　　第三范式：3NF是对字段冗余性的约束，即任何字段不能由其他字段派生出来，它要求字段没有冗余。 </p>
<p>　　没有冗余的数据库设计可以做到。但是，没有冗余的数据库未必是最好的数据库，有时为了提高运行效率，就必须降低范式标准，适当保留冗余数据。具体做法是：在概念数据模型设计时遵守第三范式，降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段，允许冗余。 </p>
<p>　　6. 要善于识别与正确处理多对多的关系 </p>
<p>　　若两个实体之间存在多对多的关系，则应消除这种关系。消除的办法是，在两者之间增加第三个实体。这样，原来一个多对多的关系，现在变为两个一对多的关系。要将原来两个实体的属性合理地分配到三个实体中去。这里的第三个实体，实质上是一个较复杂的关系，它对应一张基本表。一般来讲，数据库设计工具不能识别多对多的关系，但能处理多对多的关系。 </p>
<p>　　〖例3〗：在&ldquo;图书馆信息系统&rdquo;中，&ldquo;图书&rdquo;是一个实体，&ldquo;读者&rdquo;也是一个实体。这两个实体之间的关系，是一个典型的多对多关系：一本图书在不同时间可以被多个读者借阅，一个读者又可以借多本图书。为此，要在二者之间增加第三个实体，该实体取名为&ldquo;借还书&rdquo;，它的属性为：借还时间、借还标志(0表示借书，1表示还书)，另外，它还应该有两个外键(&ldquo;图书&rdquo;的主键，&ldquo;读者&rdquo;的主键)，使它能与&ldquo;图书&rdquo;和&ldquo;读者&rdquo;连接。 </p>
<p>　　7. 主键PK的取值方法 </p>
<p>　　PK是供程序员使用的表间连接工具，可以是一无物理意义的数字串, 由程序自动加1来实现。也可以是有物理意义的字段名或字段名的组合。不过前者比后者好。当PK是字段名的组合时，建议字段的个数不要太多，多了不但索引占用空间大，而且速度也慢。</p>
<p>8. 正确认识数据冗余 </p>
<p>　　主键与外键在多表中的重复出现, 不属于数据冗余，这个概念必须清楚，事实上有许多人还不清楚。非键字段的重复出现, 才是数据冗余！而且是一种低级冗余，即重复性的冗余。高级冗余不是字段的重复出现，而是字段的派生出现。 </p>
<p>　　〖例4〗：商品中的&ldquo;单价、数量、金额&rdquo;三个字段，&ldquo;金额&rdquo;就是由&ldquo;单价&rdquo;乘以&ldquo;数量&rdquo;派生出来的，它就是冗余，而且是一种高级冗余。冗余的目的是为了提高处理速度。只有低级冗余才会增加数据的不一致性，因为同一数据，可能从不同时间、地点、角色上多次录入。因此，我们提倡高级冗余(派生性冗余)，反对低级冗余(重复性冗余)。 </p>
<p>　　9. E－R图没有标准答案 </p>
<p>　　信息系统的E－R图没有标准答案，因为它的设计与画法不是惟一的，只要它覆盖了系统需求的业务范围和功能内容，就是可行的。反之要修改E－R图。尽管它没有惟一的标准答案，并不意味着可以随意设计。好的E－图的标准是：结构清晰、关联简洁、实体个数适中、属性分配合理、没有低级冗余。 </p>
<p>　　10. 视图技术在数据库设计中很有用 </p>
<p>　　与基本表、代码表、中间表不同，视图是一种虚表，它依赖数据源的实表而存在。视图是供程序员使用数据库的一个窗口，是基表数据综合的一种形式, 是数据处理的一种方法，是用户数据保密的一种手段。为了进行复杂处理、提高运算速度和节省存储空间, 视图的定义深度一般不得超过三层。 若三层视图仍不够用, 则应在视图上定义临时表, 在临时表上再定义视图。这样反复交迭定义, 视图的深度就不受限制了。 </p>
<p>　　对于某些与国家政治、经济、技术、军事和安全利益有关的信息系统，视图的作用更加重要。这些系统的基本表完成物理设计之后，立即在基本表上建立第一层视图，这层视图的个数和结构，与基本表的个数和结构是完全相同。并且规定，所有的程序员，一律只准在视图上操作。只有数据库管理员，带着多个人员共同掌握的&ldquo;安全钥匙&rdquo;，才能直接在基本表上操作。请读者想想：这是为什么？ </p>
<p>　　11. 中间表、报表和临时表 </p>
<p>　　中间表是存放统计数据的表，它是为数据仓库、输出报表或查询结果而设计的，有时它没有主键与外键(数据仓库除外)。临时表是程序员个人设计的，存放临时记录，为个人所用。基表和中间表由DBA维护，临时表由程序员自己用程序自动维护。 </p>
<p>　　12. 完整性约束表现在三个方面 </p>
<p>　　域的完整性：用Check来实现约束，在数据库设计工具中，对字段的取值范围进行定义时，有一个Check按钮，通过它定义字段的值城。 </p>
<p>　　参照完整性：用PK、FK、表级触发器来实现。 </p>
<p>　　用户定义完整性：它是一些业务规则，用存储过程和触发器来实现。 </p>
<p>　　13. 防止数据库设计打补丁的方法是&ldquo;三少原则&rdquo; </p>
<p>　　(1) 一个数据库中表的个数越少越好。只有表的个数少了，才能说明系统的E－R图少而精，去掉了重复的多余的实体，形成了对客观世界的高度抽象，进行了系统的数据集成，防止了打补丁式的设计； </p>
<p>　　(2) 一个表中组合主键的字段个数越少越好。因为主键的作用，一是建主键索引，二是做为子表的外键，所以组合主键的字段个数少了，不仅节省了运行时间，而且节省了索引存储空间； </p>
<p>　　(3) 一个表中的字段个数越少越好。只有字段的个数少了，才能说明在系统中不存在数据重复，且很少有数据冗余，更重要的是督促读者学会&ldquo;列变行&rdquo;，这样就防止了将子表中的字段拉入到主表中去，在主表中留下许多空余的字段。所谓&ldquo;列变行&rdquo;，就是将主表中的一部分内容拉出去，另外单独建一个子表。这个方法很简单，有的人就是不习惯、不采纳、不执行。 </p>
<p>　　数据库设计的实用原则是：在数据冗余和处理速度之间找到合适的平衡点。&ldquo;三少&rdquo;是一个整体概念，综合观点，不能孤立某一个原则。该原则是相对的，不是绝对的。&ldquo;三多&rdquo;原则肯定是错误的。试想：若覆盖系统同样的功能，一百个实体(共一千个属性) 的E－R图，肯定比二百个实体(共二千个属性)的E－R图，要好得多。 </p>
<p>　　提倡&ldquo;三少&rdquo;原则，是叫读者学会利用数据库设计技术进行系统的数据集成。数据集成的步骤是将文件系统集成为应用数据库，将应用数据库集成为主题数据库，将主题数据库集成为全局综合数据库。集成的程度越高，数据共享性就越强，信息孤岛现象就越少，整个企业信息系统的全局E&mdash;R图中实体的个数、主键的个数、属性的个数就会越少。 </p>
<p>　　提倡&ldquo;三少&rdquo;原则的目的，是防止读者利用打补丁技术，不断地对数据库进行增删改，使企业数据库变成了随意设计数据库表的&ldquo;垃圾堆&rdquo;，或数据库表的&ldquo;大杂院&rdquo;，最后造成数据库中的基本表、代码表、中间表、临时表杂乱无章，不计其数，导致企事业单位的信息系统无法维护而瘫痪。 </p>
<p>　　&ldquo;三多&rdquo;原则任何人都可以做到，该原则是&ldquo;打补丁方法&rdquo;设计数据库的歪理学说。&ldquo;三少&rdquo;原则是少而精的原则，它要求有较高的数据库设计技巧与艺术，不是任何人都能做到的，因为该原则是杜绝用&ldquo;打补丁方法&rdquo;设计数据库的理论依据。 </p>
<p>　　14. 提高数据库运行效率的办法 </p>
<p>　　在给定的系统硬件和系统软件条件下，提高数据库系统的运行效率的办法是： </p>
<p>　　(1) 在数据库物理设计时，降低范式，增加冗余, 少用触发器, 多用存储过程。 </p>
<p>　　(2) 当计算非常复杂、而且记录条数非常巨大时(例如一千万条)，复杂计算要先在数据库外面，以文件系统方式用C++语言计算处理完成之后，最后才入库追加到表中去。这是电信计费系统设计的经验。 </p>
<p>　　(3) 发现某个表的记录太多，例如超过一千万条，则要对该表进行水平分割。水平分割的做法是，以该表主键PK的某个值为界线，将该表的记录水平分割为两个表。若发现某个表的字段太多，例如超过八十个，则垂直分割该表，将原来的一个表分解为两个表。 </p>
<p>　　(4) 对数据库管理系统DBMS进行系统优化，即优化各种系统参数，如缓冲区个数。 </p>
<p>　　(5) 在使用面向数据的SQL语言进行程序设计时，尽量采取优化算法。 </p>
<p>　　总之，要提高数据库的运行效率，必须从数据库系统级优化、数据库设计级优化、程序实现级优化，这三个层次上同时下功夫。 </p>
<p>　　上述十四个技巧，是许多人在大量的数据库分析与设计实践中，逐步总结出来的。对于这些经验的运用，读者不能生帮硬套，死记硬背，而要消化理解，实事求是，灵活掌握。并逐步做到：在应用中发展，在发展中应用。 </p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/219558#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 25 Jul 2008 15:42:57 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/219558</link>
        <guid>http://wyl232.javaeye.com/blog/219558</guid>
      </item>
      <item>
        <title>STRUTS2获得session和request </title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/218854" style="color:red;">http://wyl232.javaeye.com/blog/218854</a>&nbsp;
          发表时间: 2008年07月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>【转】</p>
<p>在struts1中，获得到系统的request或者session对象非常方便，都是按照形参传递的，但是在struts2中，request和session都被隐藏了<br />struts提供两种方式访问session和request，其中比较常用的是利用SPRING里面所说的IOC即控制反转<br />IOC方式：<br />action类实现ServletRequestAware接口，并新建一个HttpServletRequest request<br />public class UserLoginAction extends ActionSupport implements ServletRequestAware{<br />&nbsp;&nbsp;&nbsp;public void setServletRequest(HttpServletRequest request) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.request=request;<br />&nbsp;&nbsp;}<br />&nbsp;然后可以生成的request得到对象，如request.getRemoteAddr()<br />action类实现SessionAware接口，并创建一个MAP对象session<br />public class UserLoginAction extends ActionSupport implements ServletRequestAware,SessionAware{<br />&nbsp;&nbsp;&nbsp;public void setServletRequest(HttpServletRequest request) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.request=request;<br />&nbsp;&nbsp;}<br />public void setSession(Map session) {<br />&nbsp;&nbsp;this.session=session;&nbsp;&nbsp;<br />&nbsp;}<br />非IOC方式<br />非Ioc方式</p>
<div style="TEXT-INDENT: 21.75pt">这种方式主要是利用了<span style="background: red; color: #000000;">com.opensymphony.xwork2.ActionContext</span>类以及<span style="BACKGROUND: red">org.apache.struts2.ServletActionContext</span>类，具体的方法如下所示。</div>
<div style="TEXT-INDENT: 21.75pt">获得request对象：</div>
<div style="TEXT-INDENT: 21.75pt"><span style="color: #000000;">A</span> <span style="color: #000000;">．</span> <span style="color: #000000;">HttpServletRequest request = ServletActionContext.getRequest ();</span> </div>
<div style="TEXT-INDENT: 21.75pt">B．ActionContext ct=<span style="color: #000000;"> ActionContext.<em>getContext</em>()</span></div>
<div style="TEXT-INDENT: 21.75pt"><span style="color: #000000;">&nbsp;&nbsp; </span><span style="color: #000000;">HttpServletRequest&nbsp;request=</span> </div>
<div style="TEXT-INDENT: 30.7pt"><span style="font-size: 10pt; color: #000000;">(HttpServletRequest)ct.get(ServletActionContext.</span> <em><span style="font-size: 10pt; color: #0000c0;">HTTP_REQUEST</span> </em><span style="font-size: 10pt; color: #000000;">);</span> </div>
<div style="TEXT-INDENT: 21.75pt">获得session对象：</div>
<div style="TEXT-INDENT: 21.75pt">在Struts2中底层的session都被封装成了Map类型，我们称之为SessionMap，而平常我们所说的session则是指HttpSession对象，具体的获得方法如下所示。</div>
<div style="TEXT-INDENT: 21.75pt">A．Map session=ActionContext.getSession();</div>
<div style="TEXT-INDENT: 21.75pt">B．Map session=(Map)ActionContext.getContext().get(ActionContext.SESSION);</div>
<div style="TEXT-INDENT: 21.75pt">得到这个SessionMap之后我们就可以对session进行读写了，<span style="background: blue; color: #ffffff;">如果我们想得到原始的</span><span style="background: blue; color: #ffffff;">HttpSession</span><span style="background: blue; color: #ffffff;">可以首先得到</span><span style="background: blue; color: #ffffff;">HttpServletRequest</span><span style="background: blue; color: #ffffff;">对象，然后通过</span><span style="background: blue; color: #ffffff;">request.getSession()</span><span style="background: blue; color: #ffffff;">来取得原始的</span><span style="background: blue; color: #ffffff;">HttpSession</span><span style="background: blue; color: #ffffff;">对象</span>。一般情况下SessionMap已经可以完成所有的工作，我们不必再去碰底层的session了。</div>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/218854#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Jul 2008 10:05:46 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/218854</link>
        <guid>http://wyl232.javaeye.com/blog/218854</guid>
      </item>
      <item>
        <title>srcElement 用法</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/216884" style="color:red;">http://wyl232.javaeye.com/blog/216884</a>&nbsp;
          发表时间: 2008年07月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&lt;div id="div_001"&gt;<br />&nbsp;&lt;form id="form_001"&gt;<br />&nbsp;&nbsp;&lt;input type="button" id="button_001_id" name="button_001_Name" value="单击查看" class="button_001_Class" onclick="Get_srcElement(this)"&gt;<br />&nbsp;&lt;/form&gt;<br />&lt;/div&gt;<br />&lt;script&gt;<br />function Get_srcElement()<br />{<br />var srcElement=""<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.id : " + event.srcElement.id<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.tagName : " + event.srcElement.tagName<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.type : " + event.srcElement.type<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.value : " + event.srcElement.value<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.name : " + event.srcElement.name<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.className : " + event.srcElement.className<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.parentElement.id : " + event.srcElement.parentElement.id<br />srcElement = srcElement + "\n" +&nbsp; "event.srcElement.getattribute : " + event.srcElement.getAttribute<br />alert(srcElement)<br />}</p>
<p>&lt;/script&gt;</p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/216884#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 21 Jul 2008 13:17:01 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/216884</link>
        <guid>http://wyl232.javaeye.com/blog/216884</guid>
      </item>
      <item>
        <title>web.xml 中显示错误页面</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/216140" style="color:red;">http://wyl232.javaeye.com/blog/216140</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>【转】今天遇到一个问题（应该是个老问题，但网上答案各异），记录下来 <br />在<span class="hilite1"><span style="background-color: #ffff00;">web</span></span>.<span class="hilite2"><span style="background-color: #55ff55;">xml</span></span>中配置错误页面跳转如下： <br />&lt;<span class="hilite3"><span style="background-color: #aaffaa;">error-page</span></span>&gt; <br />&lt;exception-type&gt;java.lang.Exception&lt;/exception-type&gt; <br />&lt;location&gt;/err/error.jsp&lt;/location&gt; <br />&lt;/<span class="hilite3"><span style="background-color: #aaffaa;">error-page</span></span>&gt; <br />或者 <br />&lt;<span class="hilite3"><span style="background-color: #aaffaa;">error-page</span></span>&gt; <br />&lt;error-code&gt;500&lt;/error-code&gt; <br />&lt;location&gt;/err/error.jsp&lt;/location&gt; <br />&lt;/<span class="hilite3"><span style="background-color: #aaffaa;">error-page</span></span>&gt; <br />制造空指针异常，启动tomcat服务器发现并不能跳转到error.jsp,而是跳转到IE的错误提示页面 <br /><br />解决方案： <br />1.在IE【工具】-&gt;【Internet选项】-&gt;【高级】中勾掉【显示友好http错误提示】； <br />2.确保error.jsp的大小&gt;1024字节。 </p>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/216140#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 14:36:00 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/216140</link>
        <guid>http://wyl232.javaeye.com/blog/216140</guid>
      </item>
      <item>
        <title>web.xml 字符过滤器</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/216134" style="color:red;">http://wyl232.javaeye.com/blog/216134</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="postText"><a href="http://blog.csdn.net/sskwfnihc/archive/2007/10/08/1815965.aspx">org.springframework.web.filter.CharacterEncodingFilter </a></div>
<div class="postText">web.xml文件<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"<br />&nbsp;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />&nbsp;xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"<br />&nbsp;version="2.4"&gt;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;CharacterEncodingFilter&lt;/filter-name&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-class&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.springframework.web.filter.CharacterEncodingFilter<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/filter-class&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init-param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;encoding&lt;/param-name&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;GB2312&lt;/param-value&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;init-param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;forceEncoding&lt;/param-name&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;true&lt;/param-value&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/init-param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/filter&gt;<br />&lt;!-- 要过滤得类型 --&gt;<br />　　&lt;filter-mapping&gt;<br />　　&lt;filter-name&gt;SetCharacterEncoding&lt;/filter-name&gt;<br />　　&lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;<br />　　&lt;/filter-mapping&gt;<br /><br />&lt;/web-app&gt;<br /><dl><dt>
<pre>public class <strong>CharacterEncodingFilter</strong><dt>extends <a href="http://www.springframework.org/docs/api/org/springframework/web/filter/OncePerRequestFilter.html" title="class in org.springframework.web.filter"><span style="color: #000080;">OncePerRequestFilter</span></a></dt></pre>
</dt></dl>
<pre></pre>
<p>Servlet 2.3/2.4 Filter that allows one to specify a character encoding for requests. This is useful because current browsers typically do not set a character encoding even if specified in the HTML page or form. </p>
<p>This filter can either apply its encoding if the request does not already specify an encoding, or enforce this filter's encoding in any case ("forceEncoding"="true"). In the latter case, the encoding will also be applied as default response encoding on Servlet 2.4+ containers (although this will usually be overridden by a full content type set in the view). </p>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/216134#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 14:23:32 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/216134</link>
        <guid>http://wyl232.javaeye.com/blog/216134</guid>
      </item>
      <item>
        <title>spring 的OpenSessionInViewFilter简介</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/216110" style="color:red;">http://wyl232.javaeye.com/blog/216110</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>[转]假设在你的应用中Hibernate是通过spring 来管理它的session.如果在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterceptor。session会在transaction结束后关闭。<br />如果你采用了spring的声明式事务模式，它会对你的被代理对象的每一个方法进行事务包装（AOP的方式）。如下：</p>
<p>&nbsp;&lt;bean id="txProxyTemplate" abstract="true"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="transactionManager" ref="transactionManager"/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="transactionAttributes"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;props&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="save*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="remove*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/props&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bean id="manager" parent="txProxyTemplate"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="target"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean class="org.appfuse.service.impl.BaseManager"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="dao" ref="dao"/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />目标类org.appfuse.service.impl.BaseManager 的&nbsp; save *方法的事务类型PROPAGATION_REQUIRED&nbsp; ，remove* 方法的事务类型PROPAGATION_REQUIRED<br />其他的方法的事务类型是PROPAGATION_REQUIRED,readOnly。<br />所以给你的感觉是调用这个名为&ldquo;manager&rdquo;的bean的方法之后session就关掉了。<br />如果应用中使用了OpenSessionInViewFilter或者OpenSessionInViewInterceptor，所有打开的session会被保存在一个线程变量里。在线程退出前通过<br />OpenSessionInViewFilter或者OpenSessionInViewInterceptor断开这些session。 为什么这么做？这主要是为了实现Hibernate的延迟加载功能。基于一个请求<br />一个hibernate session的原则。</p>
<p>spring中对OpenSessionInViewFilter的描述如下：<br />它是一个Servlet2.3过滤器，用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。<br />例如： 它允许在事务提交之后延迟加载显示所需要的对象。</p>
<p>这个过滤器和 HibernateInterceptor 有点类似：它是通过线程实现的。无论是没有事务的应用，还是有业务层事务的应用（通过HibernateTransactionManager 或<br />JtaTransactionManager的方式实现）它都适用。在后一种情况下，事务会自动采用由这个filter绑定的Session来进行相关的操作以及根据实际情况完成提交操作。</p>
<p>警告： 如果在你的应用中，一次请求的过程中使用了单一的一个HIbernate Session，在这种情况下，采用这个filter会产生一些以前没遇到的问题。特别需要注意的是通过<br />Hibernate Session重新组织持久化对象之间关系的相关操作需要在请求的最开始进行。以免与已经加载的相同对象发生冲突。</p>
<p>或者，我们可以通过指定"singleSession"="false"的方式把这个过滤器调到延期关闭模式。这样在一次请求的过程中不会使用一个单一的Session.每一次数据访问或事务相关<br />操作都使用属于它自己的session(有点像不使用Open Session in View).这些session都被注册成延迟关闭模式，即使是在这一次的请求中它相关操作已经完成。</p>
<p>"一次请求一个session" 对于一级缓存而言很有效，但是这样可以带来副作用。例如在saveOrUpdate的时候或事物回滚之后，虽然它和&ldquo;no Open Session in View&rdquo;同样安全。<br />但是它却允许延迟加载。</p>
<p>它会在spring的web应用的上下文根中查找Session工厂。它也支持通过在web.xml中定义的&ldquo;SessionFactoryBeanName&rdquo;的init-param元素 指定的Session工厂对应的bean的<br />名字来查找session工厂。默认的bean的名字是"sessionFactory".他通过每一次请求查找一次SessionFactory的方式来避免由初始化顺序引起的问题（当使用ContextLoaderServlet<br />来集成spring的时候 ，spring 的应用上下文是在这个filter 之后才被初始化的）。</p>
<p>默认的情况下，这个filter 不会同步Hibernate Session.这是因为它认为这项工作是通过业务层的事务来完成的。而且HibernateAccessors 的FlushMode为FLUSH_EAGER.如果你<br />想让这个filter在请求完成以后同步session.你需要覆盖它的closeSession方法，在这个方法中在调用父类的关闭session操作之前同步session.此外你需要覆盖它的getSession()<br />方法。返回一个session它的FlushMode 不是默认的FlushMode.NEVER。需要注意的是getSession()和closeSession()方法只有在single session的模式中才被调用。</p>
<p>在myfaces的wiki里提供了OpenSessionInViewFilter的一个子类如下：<br />public class OpenSessionInViewFilter extends org.springframework.orm.hibernate3.support.OpenSessionInViewFilter {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * we do a different flushmode than in the codebase<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * here<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session session = SessionFactoryUtils.getSession(sessionFactory, true);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.setFlushMode(FlushMode.COMMIT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return session;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * we do an explicit flush here just in case<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * we do not have an automated flush<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void closeSession(Session session, SessionFactory factory) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.flush();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.closeSession(session, factory);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />}</p>
<div class="snip-title">
<h1 class="snip-name">OpenSessionInView&nbsp; </h1>
</div>
<div class="snip-content" id="snip-content">
<p class="paragraph">另外，你不愿意你的DAO测试代码每次都打开关系Session，因此，我们一般会采用OpenSessionInView模式。 </p>
<h3 class="heading-1"><a name="0"></a>OpenSessionInViewFilter解决Web应用程序的问题 </h3>
如果程序是在正常的Web程序中运行，那么Spring的OpenSessionInViewFilter能够解决问题，它：
<p class="paragraph">&nbsp;</p>
<div class="code">
<pre><span class="java-keyword">protected</span> void doFilterInternal(HttpServletRequest request, 
             HttpServletResponse response,
	     FilterChain filterChain) <span class="java-keyword">throws</span> ServletException, IOException {
	SessionFactory sessionFactory = lookupSessionFactory();
	logger.debug(<span class="java-quote">"Opening Hibernate Session in OpenSessionInViewFilter"</span>);
	Session session = getSession(sessionFactory);
	TransactionSynchronizationManager.bindResource(sessionFactory, 
             <span class="java-keyword">new</span> SessionHolder(session));
	<span class="java-keyword">try</span> {
		filterChain.doFilter(request, response);
	}
	<span class="java-keyword">finally</span> {
		TransactionSynchronizationManager.unbindResource(sessionFactory);
		logger.debug(<span class="java-quote">"Closing Hibernate Session in OpenSessionInViewFilter"</span>);
		closeSession(session, sessionFactory);
	}
}</pre>
</div>
可以看到，这个Filter在request开始之前，把sessionFactory绑定到TransactionSynchronizationManager，和这个SessionHolder相关。这个意味着所有request执行过程中将使用这个session。而在请求结束后，将和这个sessionFactory对应的session解绑，并且关闭Session。
<p class="paragraph">为什么绑定以后，就可以防止每次不会新开一个Session呢？看看HibernateDaoSupport的情况： </p>
<div class="code">
<pre><span class="java-keyword">public</span> <span class="java-keyword">final</span> void setSessionFactory(SessionFactory sessionFactory) {
    <span class="java-keyword">this</span>.hibernateTemplate = <span class="java-keyword">new</span> HibernateTemplate(sessionFactory);
  }
 <span class="java-keyword">protected</span> <span class="java-keyword">final</span> HibernateTemplate getHibernateTemplate() {
  <span class="java-keyword">return</span> hibernateTemplate;
 }</pre>
</div>
<p class="paragraph">我们的DAO将使用这个template进行操作： </p>
<div class="code">
<pre><span class="java-keyword">public</span> <span class="java-keyword">abstract</span> class BaseHibernateObjectDao
	<span class="java-keyword">extends</span> HibernateDaoSupport
	<span class="java-keyword">implements</span> BaseObjectDao {<p class="paragraph">
	<span class="java-keyword">protected</span> BaseEntityObject getByClassId(<span class="java-keyword">final</span> <span class="java-object">long</span> id) {
		BaseEntityObject obj =
			(BaseEntityObject) getHibernateTemplate()
				.execute(<span class="java-keyword">new</span> HibernateCallback() {</p><p class="paragraph">			<span class="java-keyword">public</span> <span class="java-object">Object</span> doInHibernate(Session session)
				<span class="java-keyword">throws</span> HibernateException {
				<span class="java-keyword">return</span> session.get(getPersistentClass(), 
                                       <span class="java-keyword">new</span> <span class="java-object">Long</span>(id));
			}</p><p class="paragraph">		});
		<span class="java-keyword">return</span> obj;
	}</p><p class="paragraph"> </p><p class="paragraph">	<span class="java-keyword">public</span> void save(BaseEntityObject entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}</p><p class="paragraph">	<span class="java-keyword">public</span> void remove(BaseEntityObject entity) {
		<span class="java-keyword">try</span> {</p><p class="paragraph">			getHibernateTemplate().delete(entity);
		} <span class="java-keyword">catch</span> (Exception e) {
			<span class="java-keyword">throw</span> <span class="java-keyword">new</span> FlexEnterpriseDataAccessException(e);
		}
	}</p><p class="paragraph">	<span class="java-keyword">public</span> void refresh(<span class="java-keyword">final</span> BaseEntityObject entity) {
		getHibernateTemplate().execute(<span class="java-keyword">new</span> HibernateCallback() {</p><p class="paragraph">			<span class="java-keyword">public</span> <span class="java-object">Object</span> doInHibernate(Session session)
				<span class="java-keyword">throws</span> HibernateException {
				session.refresh(entity);
				<span class="java-keyword">return</span> <span class="java-keyword">null</span>;
			}</p><p class="paragraph">		});
	}</p><p class="paragraph">	<span class="java-keyword">public</span> void replicate(<span class="java-keyword">final</span> <span class="java-object">Object</span> entity) {
		getHibernateTemplate().execute(<span class="java-keyword">new</span> HibernateCallback() {</p><p class="paragraph">			<span class="java-keyword">public</span> <span class="java-object">Object</span> doInHibernate(Session session)
				<span class="java-keyword">throws</span> HibernateException {
				session.replicate(entity, 
                                ReplicationMode.OVERWRITE);
				<span class="java-keyword">return</span> <span class="java-keyword">null</span>;
			}</p><p class="paragraph">		});
	}</p></pre>
</div>
而HibernateTemplate试图每次在execute之前去获得Session，执行完就力争关闭Session
<div class="code">
<pre><span class="java-keyword">public</span> <span class="java-object">Object</span> execute(HibernateCallback action) <span class="java-keyword">throws</span> DataAccessException {
	Session session = (!<span class="java-keyword">this</span>.allowCreate ?
		SessionFactoryUtils.getSession(getSessionFactory(), 
                  <span class="java-keyword">false</span>) :
		SessionFactoryUtils.getSession(getSessionFactory(),
                  getEntityInterceptor(),
                  getJdbcExceptionTranslator()));
	<span class="java-object">boolean</span> existingTransaction =  
          TransactionSynchronizationManager.hasResource(getSessionFactory());
	<span class="java-keyword">if</span> (!existingTransaction &amp;&amp; getFlushMode() == FLUSH_NEVER) {
		session.setFlushMode(FlushMode.NEVER);
	}
	<span class="java-keyword">try</span> {
		<span class="java-object">Object</span> result = action.doInHibernate(session);
		flushIfNecessary(session, existingTransaction);
		<span class="java-keyword">return</span> result;
	}
	<span class="java-keyword">catch</span> (HibernateException ex) {
		<span class="java-keyword">throw</span> convertHibernateAccessException(ex);
	}
	<span class="java-keyword">catch</span> (SQLException ex) {
		<span class="java-keyword">throw</span> convertJdbcAccessException(ex);
	}
	<span class="java-keyword">catch</span> (RuntimeException ex) {
		// callback code threw application exception
		<span class="java-keyword">throw</span> ex;
	}
	<span class="java-keyword">finally</span> {
		SessionFactoryUtils.closeSessionIfNecessary(
                    session, getSessionFactory());
	}
}</pre>
</div>
而这个SessionFactoryUtils能否得到当前的session以及closeSessionIfNecessary是否真正关闭session，端取决于这个session是否用sessionHolder和这个sessionFactory在我们最开始提到的TransactionSynchronizationManager绑定。
<div class="code">
<pre><span class="java-keyword">public</span> <span class="java-keyword">static</span> void closeSessionIfNecessary(Session session, 
    SessionFactory sessionFactory)   
    <span class="java-keyword">throws</span> CleanupFailureDataAccessException {
	<span class="java-keyword">if</span> (session == <span class="java-keyword">null</span> || 
	   TransactionSynchronizationManager.hasResource(sessionFactory)) {
		<span class="java-keyword">return</span>;
	}
	logger.debug(<span class="java-quote">"Closing Hibernate session"</span>);
	<span class="java-keyword">try</span> {
		session.close();
	}
	<span class="java-keyword">catch</span> (JDBCException ex) {
		// SQLException underneath
		<span class="java-keyword">throw</span> <span class="java-keyword">new</span> CleanupFailureDataAccessException(
		<span class="java-quote">"Cannot close Hibernate session"</span>, ex.getSQLException());
	}
	<span class="java-keyword">catch</span> (HibernateException ex) {
		<span class="java-keyword">throw</span> <span class="java-keyword">new</span> CleanupFailureDataAccessException(
		<span class="java-quote">"Cannot close Hibernate session"</span>, ex);
	}
}</pre>
</div>
<h3 class="heading-1">HibernateInterceptor和OpenSessionInViewInterceptor的问题 </h3>
<p class="paragraph">使用同样的方法，这两个Interceptor可以用来解决问题。但是关键的不同之处在于，它们的力度只能定义在DAO或业务方法上，而不是在我们的Test方法上，除非我们把它们应用到TestCase的方法上，但你不大可能为TestCase去定义一个接口，然后把Interceptor应用到这个接口的某些方法上。直接使用HibernateTransactionManager也是一样的。因此，如果我们有这样的测试： </p>
<div class="code">
<pre>Category parentCategory  = <span class="java-keyword">new</span> Category ();
	parentCategory.setName(<span class="java-quote">"parent"</span>);
	dao.save(parentCategory);<p class="paragraph">	Category childCategory  = <span class="java-keyword">new</span> Category();
        childCategory.setName(<span class="java-quote">"child"</span>);</p><p class="paragraph">	parentCategory.addChild(childCategory);
	dao.save(childCategory);</p><p class="paragraph">	Category savedParent = dao.getCategory(<span class="java-quote">"parent"</span>);
	Category savedChild = (Category ) savedParent.getChildren().get(0);
	assertEquals(savedChild, childCategory);</p></pre>
</div>
将意味着两件事情： 
<ul class="minus">
<li>每次DAO执行都会启动一个session和关闭一个session </li>
<li>如果我们定义了一个lazy的关系，那么最后的Category savedChild = (Category ) savedParent.getChildren().get(0);将会让hibernate报错。 </li>
</ul>
<h3 class="heading-1">解决方案 </h3>
<p class="paragraph">一种方法是对TestCase应用Interceptor或者TransactionManager，但这个恐怕会造成很多麻烦。除非是使用增强方式的AOP.我前期采用这种方法(Aspectwerkz)，在Eclipse里面也跑得含好。 </p>
<p class="paragraph">另一种方法是在TestCase的setup和teardown里面实现和Filter完全一样的处理，其他的TestCase都从这个TestCase继承，这种方法是我目前所使用的。 </p>
<p class="paragraph"><span style="color: #3333ff;">Jolestar补充:openSessionInView的配置方法:</span></p>
<p class="paragraph">&nbsp;&nbsp; &lt;filter&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;filter-name&gt;opensession&lt;/filter-name&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;init-param&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;param-name&gt;singleSession&lt;/param-name&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;param-value&gt;false&lt;/param-value&gt; <br />&nbsp; &nbsp; &nbsp; &nbsp; &lt;/init-param&gt; <br />&nbsp; &nbsp; &lt;/filter&gt; </p>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/216110#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/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 13:28:14 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/216110</link>
        <guid>http://wyl232.javaeye.com/blog/216110</guid>
      </item>
      <item>
        <title>初识Firebug 全文 — firebug的使用</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/215748" style="color:red;">http://wyl232.javaeye.com/blog/215748</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h2 class="posttitle" id="post-294"><a href="http://www.ooso.net/index.php/archives/294" title="Permanent link to 初识Firebug 全文 &mdash; firebug的使用" rel="bookmark">初识Firebug 全文 &mdash; firebug的使用</a></h2>
<p class="postmeta">2007-05-15 @ 09:54:03 &middot; 作者 <a href="http://www.ooso.net/index.php/archives/author/volcano/" title="Posts by Volcano">Volcano</a> &middot; 归类于 <a href="http://www.ooso.net/index.php/archives/category/firefox" title="View all posts in FIREFOX" rel="category tag">FIREFOX</a> </p>
<div class="postentry">
<div class="related">
<h2>你可能会感兴趣的内容</h2>
<ul>
<li><a href="http://www.ooso.net/index.php/archives/383" title="firebug现在已经可以支持firefox 3">firebug现在已经可以支持firefox 3</a> </li>
<li><a href="http://www.ooso.net/index.php/archives/288" title="初识firebug 发表了">初识firebug 发表了</a> </li>
<li><a href="http://www.ooso.net/index.php/archives/268" title="Firebug 1.0 beta is out">Firebug 1.0 beta is out</a> </li>
<li><a href="http://www.ooso.net/index.php/archives/223" title="我使用的firefox插件">我使用的firefox插件</a> </li>
<li><a href="http://www.ooso.net/index.php/archives/437" title="firebug已经提供中文界面">firebug已经提供中文界面</a> </li>
</ul>
</div>
<p>本文最初发表《程序员》杂志第三期，现将全文贴上，内容已经过编辑修饰了很多:)</p>
<h3>什么是Firebug</h3>
<p>从事了数年的Web开发工作，越来越觉得现在对WEB开发有了更高的要求。要写出漂亮的HTML代码；要编写精致的CSS样式表展示每个页面模块；要调试<a href="http://www.ooso.net/index.php/archives/category/javascript/">javascript</a>给页面增加一些更活泼的要素；要使用Ajax给用户带来更好的体验。一个优秀的WEB开发人员需要顾及更多层面，才能交出一份同样优秀的作业。为帮助广大正处于Web2.0洪流中的开发人员，在这里为大家介绍一款轻巧灵活的辅助开发工具。</p>
<p>Firebug是Firefox下的一款开发类插件，现属于<a href="http://www.ooso.net/index.php/archives/category/firefox/">Firefox</a>的五星级强力推荐插件之一。它集HTML查看和编辑、Javascript控制台、网络状况监视器于一体，是开发JavaScript、CSS、HTML和Ajax的得力助手。Firebug如同一把精巧的瑞士军刀，从各个不同的角度剖析Web页面内部的细节层面，给Web开发者带来很大的便利。这是一款让人爱不释手的插件，如果你以前没有接触过它，也许在阅读本文之后，会有一试的欲望。笔者在撰写此文的时候，正逢Firebug发布1.0正式版，这不能不说是种巧合。</p>
<h3>应用</h3>
<p>Firebug插件虽然功能强大，但是它已经和Firefox浏览器无缝地结合在一起，使用简单直观。如果你担心它会占用太多的系统资源，也可以方便地启用/关闭这个插件，甚至针对特定的站点开启这个插件。</p>
<p>在安装好插件之后，先用Firefox浏览器打开需要测试的页面，然后点击右下方的绿色按钮或使用快捷键F12唤出Firebug插件，它会将当前页面分成上下两个框架，如图1所示。</p>
<p>图1：Firebug插件展开图示<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug1.gif" alt="firebug插件展开图示" /><br />从图1中看到，Firebug有6个主要的Tab按钮，下文将主要介绍介绍这几方面的功能。</p>
<table border="1" cellpadding="4">
<tbody>
<tr>
<td>Console</td>
<td>HTML</td>
<td>CSS</td>
<td>Script</td>
<td>Dom</td>
<td>Net</td>
</tr>
<tr>
<td>控制台</td>
<td>Html查看器</td>
<td>Css查看器</td>
<td>脚本条时期 </td>
<td>Dom查看器</td>
<td>网络状况监视</td>
</tr>
</tbody>
</table>
<h3>Console 控制台</h3>
<p>控制台能够显示当前页面中的javascript错误以及警告，并提示出错的文件和行号，方便调试，这些错误提示比起浏览器本身提供的错误提示更加详细且具有参考价值。而且在调试Ajax应用的时候也是特别有用，你能够在控制台里看到每一个XMLHttpRequests请求post出去的参数、URL，http头以及回馈的内容，原本似乎在幕后黑匣子里运作的程序被清清楚楚地展示在你面前。</p>
<p>象C shell或Python shell一样，你还能在控制台中查看变量内容，直接运行javascript语句，就算是大段的javascript程序也能够正确运行并拿到运行期的信息。</p>
<p>控制台还有个重要的作用就是查看脚本的log, 从前你也许习惯了使用alert来打印变量，但是Firebug给我们带来了一个新朋友 &mdash;&mdash; console.log, 最简单的打印日志的语法是这样的： </p>
<div class="igBar"><span id="lcode-1"><a href="http://wyl232.javaeye.com/admin/#" onclick="showCodeTxt('code-1'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-1">
<div class="code"><ol>
<li style="font-weight: normal; color: #3a6a8b; font-style: normal; font-family: 'Courier New', Courier, monospace;">
<div style="font-weight: normal; font-family: 'Courier New', Courier, monospace;">console.<span>log</span><span style="font-weight: bold; color: #006600;">(</span><span style="color: #cc0000;">"hello world"</span><span style="font-weight: bold; color: #006600;">)</span> </div>
</li>
</ol></div>
</div>
</div>
<p>如果你有一堆参数需要组合在一起输出，可以写成这样：</p>
<div class="igBar"><span id="lcode-2"><a href="http://wyl232.javaeye.com/admin/#" onclick="showCodeTxt('code-2'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-2">
<div class="code"><ol>
<li style="font-weight: normal; color: #3a6a8b; font-style: normal; font-family: 'Courier New', Courier, monospace;">
<div style="font-weight: normal; font-family: 'Courier New', Courier, monospace;">console.<span>log</span><span style="font-weight: bold; color: #006600;">(</span><span style="color: #800000;">2</span>,<span style="color: #800000;">4</span>,<span style="color: #800000;">6</span>,<span style="color: #800000;">8</span>,<span style="color: #cc0000;">"foo"</span>,bar<span style="font-weight: bold; color: #006600;">)</span>. </div>
</li>
</ol></div>
</div>
</div>
<p>Firebug的日志输出有多种可选的格式以及语法，甚至可以定制彩色输出，比起单调的alert，显然更加方便，限于篇幅，这里不做详细说明，但是有志于提高debug效率的读者，可以到Firebug的官方站点（见附录）查看更详细的教程。</p>
<p>图2： 在控制台里调试javascript<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug2.gif" alt="在控制台里调试javascript" /></p>
<h3>查看和修改HTML</h3>
<p>第一次看到Firebug强大的HTML代码查看器，就觉得它与众不同，相比于Firefox自带的HTML查看器，它的功能强大了许多。 HTML</p>
<p>首先你看到的是已经经过格式化的HTML代码，它有清晰的层次，你能够方便地分辨出每一个标签之间的从属并行关系，标签的折叠功能能够帮助你集中精力分析代码。源代码上方还标记出了DOM的层次，如图3所示，它清楚地列出了一个hml元素的parent、child以及root元素，配合Firebug自带的CSS查看器使用，会给div+css页面分析编写带来很大的好处。你还可以在HTML查看器中直接修改HTML源代码，并在浏览器中第一时间看到修改后的效果，光凭这一点就会让许多页面设计师死心塌地地成为Firebug的粉丝了。</p>
<p>有时候页面中的javascript会根据用户的动作如鼠标的onmouseover来动态改变一些HTML元素的样式表或背景色，HTML查看器会将页面上改变的内容也抓下来，并以黄色高亮标记，让网页的暗箱操作彻底成为历史。</p>
<p>利用Inspect检查功能，我们还可以用鼠标在页面中直接选择一些区块，查看相应的HTML源代码和CSS样式表，真正的做到所见即所得，如果你使用了外部编辑器修改了当前网页，可以点击Firebug的reload图片重新载入网页，它会继续跟踪你之前用Inspect选中的区块，方便调试。</p>
<p>图3:：HTML查看器<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug3.gif" alt="HTML查看器" /></p>
<h3>CSS调试</h3>
<p>Firebug的CSS调试器是专为网页设计师们量身定做的。</p>
<p>如今的网页设计言必称div+css，如果你是用table套出来的HTML页面，就得按这规矩重构一遍，否则显得你不够时髦！用div做出来的页面的确能精简HTML代码，HTML标签减肥的结果就是CSS样式表的编写成了页面制作的重头戏。Firebug的CSS查看器不仅自下向上列出每一个CSS样式表的从属继承关系，还列出了每一个样式在哪个样式文件中定义。你可以在这个查看器中直接添加、修改、删除一些CSS样式表属性，并在当前页面中直接看到修改后的结果。</p>
<p>一个典型的应用就是页面中的一个区块位置显得有些不太恰当，它需要挪动几个象素。这时候用CSS调试工具可以轻易编辑它的位置&mdash;&mdash;你可以根据需要随意挪动象素。<br />如图4中正在修改一个区块的背景色。</p>
<p>提示：如果你正在学习CSS样式表的应用，但是总记不住常用的样式表有哪些值，可以尝试在CSS调试器中选中一个样式表属性，然后用上下方向键来改变它的值，它会把可能的值一个个遍历给你看。</p>
<p>图4: CSS查看器，能够直接修改样式表<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug4.gif" alt="图4: CSS查看器，能够直接修改样式表" /></p>
<h3>可视化的CSS尺标</h3>
<p>我们可以利用Firebug来查看页面中某一区块的CSS样式表，如果进一步展开右侧Layout tab的话，它会以标尺的形式将当前区块占用的面积清楚地标识出来，精确到象素，更让人惊讶的是，你能够在这个可视化的界面中直接修改各象素的值，页面上区块的位置就会随改动而变化。在页面中某些元素出现错位或者面积超出预料值时，该功能能够提供有效的帮助，你可以籍此分析offset、margin、padding、size之间的关系，从而找出解决问题的办法。</p>
<p>图5：Firebug中的CSS标尺<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug5.gif" alt="图5：Firebug中的CSS标尺" /></p>
<h3>网络状况监视器</h3>
<p>也许有一天，你的老板或者客户找到你，抱怨你制作的网页速度奇慢，你该如何应对？你或许会说这可能是网络问题，或者是电脑配置问题，或者是程序太慢，或者直说是他们的人品问题？不管怎么说，最后你可能被要求去解决这个有多种可能的问题。</p>
<p>网络状况监视器能帮你解决这个棘手问题。Firebug的网络监视器同样是功能强大的，它能将页面中的CSS、javascript以及网页中引用的图片载入所消耗的时间以矩状图呈现出来，也许在这里你能一把揪出拖慢了你的网页的元凶，进而对网页进行调优，最后老板满意客户欢喜，你的饭碗也因此而牢固。</p>
<p>网络监视器还有一些其它细节功能，比如预览图片，查看每一个外部文件甚至是xmlHttpRequests请求的http头等等。</p>
<p>图6：网络状况监视器<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug6.gif" alt="图6：网络状况监视器" /></p>
<h3>Javascript调试器</h3>
<p>这是一个很不错的javascript脚本调试器，占用空间不大，但是单步调试、设置断点、变量查看窗口一个不少。正所谓麻雀虽小，五脏俱全。</p>
<p>如果你有一个网站已经建成，然而它的javascript有性能上的问题或者不是太完美，可以通过面板上的Profile来统计每段脚本运行的时间，查看到底是哪些语句执行时间过长，一步步排除问题。</p>
<p>图7：javascript调试器<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug7.gif" alt="图7：javascript调试器" /></p>
<h3>DOM查看器</h3>
<p>DOM(Document Object Model)里头包含了大量的Object以及函数、事件，在从前，你要想从中查到需要的内容，绝非易事，这好比你去了一个巨大的图书馆，想要找到几本名字不太确切的小书，众多的选择会让你无所适从。而使用Firebug的DOM查看器却能方便地浏览DOM的内部结构，帮助你快速定位DOM对象。双击一个DOM对象，就能够编辑它的变量或值，编辑的同时，你可能会发现它还有自动完成功能，当你输入document.get之后，按下tab键就能补齐为document.getElementById，非常方便。如果你认为补齐得不够理想，按下shift+tab又会恢复原状。用了Firebug的DOM查看器，你的javascript从此找到了驱使的对象，Web开发也许就成了一件乐事。</p>
<p>图8: Dom查看器<br /><img src="http://www.ooso.net/wp-content/uploads/2007/firebug8.gif" alt="图8: Dom查看器" /></p>
<h3>小结</h3>
<p>Firebug插件提供了一整套web开发所必需的工具。从HTML的编写，到CSS样式表的美化调优，以及用javascript脚本开发，亦或是Ajax应用，Firebug插件都会成为你的得力助手。所谓工欲善其事，必先利其器。在Web2.0的时代，言必称Ajax，动辄就是用户体验提升，如果把Firebug工具用好，必能让你如虎添翼，将HTML、CSS、javascript整理得服服帖帖，从此成为web开发中的专家级人物。</p>
<h3>附作者: <a href="http://www.ooso.net/index.php/archives/author/volcano/" title="Posts by Volcano">Volcano</a> 发表于May 15, 2007 at 9:54 am</h3>
<p><a href="http://creativecommons.org/licenses/by/3.0/deed.zh" target="_blank">版权信息</a>: <strong>可以任意转载, 转载时请务必以超链接形式标明文章<a href="http://www.ooso.net/index.php/archives/294">原始出处</a>和<a href="http://www.ooso.net/">作者信息</a>及此声明</strong></p>
<p class="postfeedback"><a href="http://www.ooso.net/index.php/archives/294" title="永久链接到 初识Firebug 全文 &mdash; firebug的使用" class="permalink" rel="bookmark">永久链接 - http://www.ooso.net/index.php/archives/294</a> </p>
</div>
<h3>Tags: <a href="http://www.ooso.net/index.php/tag/firebug" rel="tag">firebug</a>,<a href="http://www.ooso.net/index.php/tag/firefox" rel="tag">FIREFOX</a>,<a href="http://www.ooso.net/index.php/tag/%e6%8f%92%e4%bb%b6" rel="tag">插件</a></h3>
          <br/>
          <span style="color:red;">
            <a href="http://wyl232.javaeye.com/blog/215748#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jul 2008 13:13:26 +0800</pubDate>
        <link>http://wyl232.javaeye.com/blog/215748</link>
        <guid>http://wyl232.javaeye.com/blog/215748</guid>
      </item>
      <item>
        <title>jQuery中文入门指南，翻译加实例，jQuery的起点教程</title>
        <author>wyl232</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wyl232.javaeye.com">wyl232</a>&nbsp;
          链接：<a href="http://wyl232.javaeye.com/blog/215746" style="color:red;">http://wyl232.javaeye.com/blog/215746</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h1>[转]jQuery中文入门指南，翻译加实例，jQuery的起点教程</h1>
<div>
<h3>中文版译者：<a href="http://keelsike.blogspot.com/">Keel</a></h3>
<p>此文以实例为基础一步步说明了jQuery的工作方式。现以中文翻译（添加我的补充说明）如下。如有相关意见或建议请麻烦到我的 <a href="http://keelsike.blogspot.com/">BLOG</a> 写个回复或者 <a href="mailto:keel.sike(at)gmail.com">EMAIL</a> 告知。</p>
<p>英文原版：<a href="http://jquery.bassistance.de/jquery-getting-started.html">http://jquery.bassistance.de/jquery-getting-started.html</a> ，感谢原文作者 <a href="http://bassistance.de/">J&ouml;rn Zaefferer</a></p>
<p><strong>本文发布已征求原作者同意。</strong> </p>
<p>另外我认为在学习过程中,有两个API文档你要打开随时查看:</p>
<ul>
<li><a href="http://jquery.com/api/">http://jquery.com/api/</a> </li>
<li><a href="http://visualjquery.com/">http://visualjquery.com/</a> </li>
</ul>
</div>
<h4>以下部分为原文翻译:</h4>
<hr />
<div>
<h2>jQuery入门指南教程</h2>
<p>这个指南是一个对jQuery库的说明，要求读者了解HTML(DOM)和CSS的一些常识。它包括了一个简单的Hello World的例子，选择器和事件基础，AJAX、FX的用法，以及如何制作jQuery的插件。 这个指南包括了很多代码，你可以copy它们，并试着修改它们，看看产生的效果。 </p>
<h2>内容提要</h2>
<ol>
<li><a href="../#setup">安装</a> </li>
<li><a href="../#hello">Hello jQuery</a> </li>
<li><a href="../#find">Find me:使用选择器和事件</a> </li>
<li><a href="../#rate">Rate me:使用AJAX</a> </li>
<li><a href="../">Animate me(让我生动起来):使用FX</a> </li>
<li><a href="../#sort">Sort me(将我有序化):使用tablesorter插件(表格排序)</a> </li>
<li><a href="../#plug">Plug me:制作您自己的插件</a> </li>
<li><a href="../#next">Next steps(下一步)</a> </li>
</ol></div>
<div>
<h2 id="setup">安装</h2>
<p>一开始,我们需要一个jQuery的库,最新的下载可以到<a href="http://jquery.com/src/">这里</a>找到。这个指南提供一个基本包含实例的包供下载.</p>
<p>下载：<a href="../jquery-starterkit.zip" class="download">jQuery Starterkit</a></p>
<p class="log">(译者Keel注:一定要下载这个包，光看文章不实践肯定是不行的。) </p>
<p class="instruction">下载后解压缩，然后用你最喜欢的文本编辑器打开starterkit.html和custom.js这两个文件。<span class="log"><span style="color: #008000;">(译者Keel注:这两个就是例子文件,所有的例子都用这两个例子作出,custom.js写jQuery代码,starterkit.html观察效果.建议用editPlus打开) </span></span></p>
<p>现在,我们就已经做好了一切准备来进行这个著名的"Hello world"例子.</p>
<h4>本章的相关链接:</h4>
<ul>
<li><a href="../jquery-starterkit.zip">Starterkit</a> </li>
<li><a href="http://jquery.com/src/">jQuery Downloads</a> </li>
</ul>
</div>
<div>
<h2 id="hello">Hello jQuery</h2>
<p>在做所有事情之前,我们要让jQuery读取和处理文档的DOM,必须尽可能快地在DOM载入后开始执行事件,所以,我们用一个ready事件作为处理HTML文档的开始.看看我们打开的custom.js这个文件,里面已经准备好了:</p>
<pre>$(document).ready(function() {
	// do stuff when DOM is ready
});</pre>
<p>放一个简单的alert事件在需要等DOM完成载入,所以我们把任务稍稍变复杂一点:在点击任何一个链接时显示一个alert.</p>
<pre>$(document).ready(function() {
	$("a").click(function() {
		alert("Hello world!");
	});
});</pre>
<p>这样在你点击页面的一个链接时都会触发这个"Hello world"的提示。</p>
<p class="log">(译者Keel注:请照此代码修改custom.js并保存,然后用浏览器打开starterkit.html观察效果。)</p>
<p>让我们看一下这些修改是什么含义。$("a") 是一个jQuery选择器(selector),在这里，它选择所有的a标签<span class="log"><span style="color: #008000;">（译者Keel注：即&lt;a&gt;&lt;/a&gt;）</span></span>，$号是 jQuery &ldquo;类&rdquo;(jQuery "class")的一个别称，因此$()构造了一个新的jQuery 对象(jQuery object)。函数 click() 是这个jQuery对象的一个方法，它绑定了一个单击事件到所有选中的标签(这里是所有的a标签),并在事件触发时执行了它所提供的alert方法.</p>
<p>这里有一个拟行相似功能的代码:</p>
<pre>&lt;a href="#" onclick="alert('Hello world')"&gt;Link&lt;/a&gt;</pre>
<p>不同之处很明显,用jQuery不需要在每个a标签上写onclick事件,所以我们拥有了一个整洁的结构文档(HTML)和一个行为文档(JS),达到了将结构与行为分开的目的,就像我们使用CSS追求的一样.</p>
<p>下面我们会更多地了解到选择器与事件.</p>
<h4>本章的相关链接:</h4>
<ul>
<li><a href="http://jquery.com/docs/Base/">jQuery Base</a> </li>
<li><a href="http://jquery.com/docs/Base/Expression/">jQuery Expressions</a> </li>
<li><a href="http://jquery.com/docs/Base/Events/">jQuery Basic Events</a> </li>
</ul>
</div>
<div>
<h2 id="find">Find me:使用选择器和事件</h2>
<p>jQuery提供两种方式来选择html的elements，第一种是用CSS和Xpath选择器联合起来形成一个字符串来传送到jQuery的构造器（如：$("div &gt; ul a")）；第二种是用jQuery对象的几个methods(方法)。这两种方式还可以联合起来混合使用。</p>
<p>为了测试一下这些选择器，我们来试着在我们starterkit.html中选择并修改第一个ordered list.</p>
<p>一开始，我们需要选择这个list本身，这个list有一个ID叫&ldquo;orderedlist&rdquo;，通常的javascript写法是document.getElementById("orderedlist").在jQuery中，我们这样做：</p>
<pre>$(document).ready(function() {
	$("#orderedlist").addClass("red");
});</pre>
<p>这里将starterkit中的一个CSS样式red附加到了orderedlist上<span class="log"><span style="color: #008000;">(译者Keel注：参考测试包中的css目录下的core.css，其中定义了red样式)</span></span>。因此，在你刷新了starterkit.html后，你将会看到第一个有序列表(ordered list )背景色变成了红色，而第二个有序列表没有变化.</p>
<p>现在，让我们添加一些新的样式到list的子节点.</p>
<pre>$(document).ready(function() {
	$("#orderedlist &gt; li").addClass("blue");
});</pre>
<p>这样，所有orderedlist中的li都附加了样式"blue"。</p>
<p>现在我们再做个复杂一点的，当把鼠标放在li对象上面和移开时进行样式切换，但只在list的最后一个element上生效。</p>
<pre>$(document).ready(function() {
	$("#orderedlist li:last").hover(function() {
		$(this).addClass("green");
	}, function() {
		$(this).removeClass("green");
	});
});</pre>
<p>还有大量的类似的<a href="http://jquery.com/docs/Base/Expression/CSS/" title="Documentation for CSS selectors" class="doc">CSS</a>和<a href="http://jquery.com/docs/Base/Expression/XPath/" title="Documentation for XPath selectors" class="doc">XPath</a>例子，更多的例子和列表可以在<a href="http://jquery.com/docs/Base/Expression/" title="Documentation for base selectors" class="doc">这里</a>找到。<span class="log"><span style="color: #008000;">（译者Keel注：入门看此文，修行在个人，要想在入门之后懂更多，所以这段话的几个链接迟早是要必看的！不会又要翻译吧...^_^!）</span></span></p>
<p>每一个onXXX事件都有效，如onclick,onchange,onsubmit等，都有jQuery等价表示方法<span class="log"><span style="color: #008000;">（译者Keel注：jQuery不喜欢onXXX，所以都改成了XXX，去掉了on）</span></span>。<a href="http://jquery.com/docs/EventModule/" title="Documentation for advanced events" class="doc">其他的一些事件</a>，如ready和hover,也提供了相应的方法。</p>
<p>你可以在<a href="http://visualjquery.com/">Visual jQuery</a>找到全部的事件列表，在Events栏目下.</p>
<p>用这些选择器和事件你已经可以做很多的事情了，但这里有一个更强的好东东！</p>
<pre>$(document).ready(function() {
	$("#orderedlist").find("li").each(function(i) {
		$(this).html( $(this).html() + " BAM! " + i );
	});
});</pre>
<p>find() 让你在已经选择的element中作条件查找,因此 $("#orderedlist).find("li") 就像 $("#orderedlist li")一样。each()方法迭代了所有的li，并可以在此基础上作更多的处理。 大部分的方法,如addClass(), 都可以用它们自己的 each() 。在这个例子中, html()用来获取每个li的html文本, 追加一些文字，并将之设置为li的html文本。<span class="log"><span style="color: #008000;">（译者Keel注：从这个例子可以看到.html()方法是获取对象的html代码，而.html('xxx')是设置'xxx'为对象的html代码）</span></span></p>
<p>另一个经常碰到的任务是在没有被jQuery覆盖的DOM元素上call一些方法，想像一个在你用AJAX方式成功提交后的reset：</p>
<pre>$(document).ready(function() {
	// use this to reset a single form
	$("#reset").click(function() {
		$("#form")[0].reset();
	});
});</pre>
<p class="log">（译者Keel注：这里作者将form的id也写成了form，源文件有&lt;form id="form"&gt;，这是非常不好的写法，你可以将这个ID改成form1或者testForm，然后用$("#form1")或者$("#testForm")来表示它，再进行测试。）</p>
<p>这个代码选择了所有ID为"form"的元素，并在其第一个上call了一个reset()。如果你有一个以上的form，你可以这样做：</p>
<pre>$(document).ready(function() {
	// use this to reset several forms at once
	$("#reset").click(function() {
		$("form").each(function() {
			this.reset();
		});
	});
});</pre>
<p class="log">（译者Keel注：请注意一定要亲自将这些代码写在custom.js中并在starterkit.html上测试效果才能有所体会！必要时要观察starterkit.html的html代码）</p>
<p>这样你在点击Reset链接后，就选择了文档中所有的form元素，并对它们都执行了一次reset()。</p>
<p>还有一个你可能要面对的问题是不希望某些特定的元素被选择。jQuery 提供了filter() 和not() 方法来解决这个问题。 filter()以过滤表达式来减少不符合的被选择项, not()则用来取消所有符合过滤表达式的被选择项. 考虑一个无序的list，你想要选择所有的没有ul子元素的li元素。</p>
<pre>$(document).ready(function() {
	$("li").not("[ul]").css("border", "1px solid black");
});</pre>
<p>这个代码选择了所有的li元素，然后去除了没有ul子元素的li元素。刷新浏览器后，所有的li元素都有了一个边框，只有ul子元素的那个li元素例外。</p>
<p class="log">（译者Keel注：请注意体会方便之极的css()方法，并再次提醒请务必实际测试观察效果，比方说换个CSS样式呢？再加一个CSS样式呢？像这样：$("li").not("[ul]").css("border", "1px solid black").css("color","red");）</p>
<p>上面代码中的[expression] 语法是从XPath而来，可以在子元素和属性(elements and attributes)上用作过滤器，比如你可能想选择所有的带有name属性的链接:</p>
<pre>$(document).ready(function() {
	$("a[@name]").background("#eee");
});</pre>
<p>这个代码给所有带有name属性的链接加了一个背景色。<span class="log"><span style="color: #008000;">（译者Keel注：这个颜色太不明显了，建议写成$("a[@name]").background("red");）</span></span></p>
<p>更常见的情况是以name来选择链接，你可能需要选择一个有特点href属性的链接，这在不同的浏览器下对href的理解可能会不一致，所以我们的部分匹配("*=")的方式来代替完全匹配("=")：</p>
<pre>$(document).ready(function() {
	$("a[@href*=/content/gallery]").click(function() {
		// do something with all links that point somewhere to /content/gallery
	});
});</pre>
<p>到现在为止，选择器都用来选择子元素或者是过滤元素。另外还有一种情况是选择上一个或者下一个元素，比如一个FAQ的页面，答案首先会隐藏，当问题点击时，答案显示出来，jQuery代码如下：</p>
<pre>$(document).ready(function() {
	$('#faq').find('dd').hide().end().find('dt').click(function() {
         var answer = $(this).next();
         if (answer.is(':visible')) {
             answer.slideUp();
         } else {
             answer.slideDown();
         }
     });
});</pre>
<p>这里我们用了一些链式表达法来减少代码量，而且看上去更直观更容易理解。像'#faq' 只选择了一次，利用end()方法，第一次find()方法会结束(undone)，所以我们可以接着在后面继续find('dt')，而不需要再写$('#faq').find('dt')。</p>
<p>在点击事件中的，我们用 $(this).next() 来找到dt下面紧接的一个dd元素，这让我们可以快