<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>yananay</title>
    <description>学而不思则惘，思而不学而殆</description>
    <link>http://yananay.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>关于dwr的安全性问题</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/211487" style="color:red;">http://yananay.javaeye.com/blog/211487</a>&nbsp;
          发表时间: 2008年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在一些网站中，我们虽然使用了AJAX，但是我们并不希望用户能够私自调用这些AJAX，因为有些AJAX调用会包含对数据的更新操作，即使是只读的操作，也不希望用户能在本地进行直接调用。<br /><br />在 Michael Chen 的这篇文章中 <a href="http://michael.nona.name/archives/142" target="_blank">http://michael.nona.name/archives/142</a> ，提及了ajax应用中的安全问题，并且给出了一个临时的解决方案。虽然我用的不是 Buffalo ，而是 dwr，但是这篇文章对于 dwr 仍然有帮助。<br /><br />不过正如 Michael Chen 在文章中所说，他给出的解决方案没有经过详细的测试，所以我在用了一段时间之后，还真就发现了问题。<br /><br />文中的解决方案的关键是判断 request的Cookie，虽然 dwr 中取得request的方式与 Buffalo不同，但是并不影响，而且经过测试，也确实有效。<br /><br />可是之后网站增加了静态页面的生成功能，这样用户就可以直接访问静态页，而非提交一个请求。结果问题出现了。<br /><br />当在静态页中调用 dwr 的应用时，request的 Cookie 也是空的。这样之前的解决方案就无效了。<br /><br />那么怎么办？或许 http 的 header 中的 referer 能给点帮助！<br /><br /><pre name="code" class="java">
String referer = request.getHeader("referer");
</pre><br /><br />通过这样的方式我们就能得到一个 referer，那么这个 referer是什么呢？就是请求这个AJAX的地址。我想熟悉盗链功能的朋友对它不会陌生。<br /><br />这样，当我们从 www.xxx.com 请求 www.xxx.com/index.html 时，而这个 index.html 中又包含一个 AJAX 的调用的时候，我们就可以这么判断：<br /><br /><pre name="code" class="java">
String referer = request.getHeader("referer");

if(!referer.startsWith("http://www.xxx.com")) {
    throw new Exception();
}
</pre><br /><br />这样就可以保证只允许网站内部的资源访问 AJAX 的应用了。<br /><br />经过测试，可以做到避免使用浏览器的方式从本地私自访问AJAX应用。但是我想这种方式仍然会存在漏洞，希望大家能给出更好的方案。
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/211487#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><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jul 2008 13:14:15 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/211487</link>
        <guid>http://yananay.javaeye.com/blog/211487</guid>
      </item>
      <item>
        <title>再谈应用服务器和web服务器的整合</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/200982" style="color:red;">http://yananay.javaeye.com/blog/200982</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          关于应用服务器和web服务器的整合，有很多的资料了，可是都讲的半生不熟的。根据这几天整合tomcat 和 iis 的经验，再次聊聊这个话题。<br /><br />首先我们应该对应用服务器和web服务器有一个清晰的概念。所谓的应用服务器，就是提供应用的服务器，这里的应用有很多，比如java应用，ruby 应用，或者 c#应用。<br /><br />那么什么是web服务器呢？就是提供了web功能的服务器，主要就是http服务，包括图片的下载，等等一系列和web相关的。<br /><br />好吧，你会问为什么我们不能直接使用应用服务器呢？应用服务器也提供了http服务，比如tomcat。<br /><br />那么我们从实际出发。当你浏览一个网页的时候，什么情况下你会觉得速度很慢？我们仅仅考虑页面本身。那当然是图片越多显示得越慢。<br /><br />好吧，我们至少认识到一点，一些静态资源，例如图片，会严重影响页面打开的速度。当然，这仅仅是一个方面。<br /><br />那么web服务器有什么用呢？web服务器一个优点就是在处理静态信息上。例如一些静态的html，图片，等等其他静态的东西。<br /><br />那为什么tomcat不能具备这些优点？这个问题我们可以换一个说法：为什么会计不能做市场营销呢？<br /><br />所以嘛，大家要分工明确，应用服务器就做好它该做的：如何解释一个jsp，如何处理java文件等等，做好这一点就足够了。而web服务器也做好它该做的：如何快速向浏览器传递信息，如何快速地让浏览器下载图片。<br /><br />那你又问了，那为啥tomcat还提供一个http服务？那不是让你开发方便嘛！千万别把tomcat的http服务当成是一个web服务器。<br /><br />说了这么多，那么我们对应用服务器和web服务器的整合也应该心里有数了。就拿tomcat和iis整合来说事吧！<br /><br />我们到底想干什么呢？很明显，我们想让tomcat 处理对 java应用的请求，而iis应该处理图片，css 等等其他静态资源的事情。<br /><br />具体的细节不谈了，无非就是配置 ispai_redirect 这个东东。因为我们主要说的分工问题，所以还是说说这个 uriworkermap.properties 文件。<br /><br />这个文件就是处理分工的用的。例如我定义成如下这个样子：<br />/www.abc.com/eshop/*.do=ajp13<br />/www.abc.com/eshop/dwr/interface/*=ajp13<br />/www.abc.com/eshop/dwr/*=ajp13<br />/www.abc.com/eshop/js/*=ajp13<br /><br />那么就告诉了 isapi_redirect , 以上4种请求，都交给tomcat处理。<br />那么其他的请求呢？当然是交给 iis了。<br /><br />如果我定义成这个样子：<br />/* = ajp13<br /><br />这下可惨了，iis被你浪费了，就好像你招聘了一个会计和一个推销的人员，但是让会计干财务的活之外，还干了推销。而推销人员给闲置了。<br /><br />至于 uriworkermap.properties  的详细配置，可以参考 tomcat 网站，上面有详细的讲解。<br /><br /><br />两种服务器的整合虽然不难，但是如果不明白其中的意义和原理，一旦项目配置有所变化，那就是没有葫芦就画不出来瓢了。
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/200982#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 06 Jun 2008 15:53:32 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/200982</link>
        <guid>http://yananay.javaeye.com/blog/200982</guid>
      </item>
      <item>
        <title>win2003+IIS6+Tomcat5+jk整合(转)</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/198395" style="color:red;">http://yananay.javaeye.com/blog/198395</a>&nbsp;
          发表时间: 2008年05月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>转一个 win2003+IIS6+Tomcat5+jk 的文档，省得以后到处找 :D </p>
<p>原文 [url]http://www.cnrui.cn/blog/article.asp?id=179[/url]</p>
<p>&nbsp;</p>
<p>其中一个问题原文没有说到。当iis与tomcat整合完毕的时候，如果你输入 http://域名 ，会发现你在iis中设置的首页</p>
<p>根本不好使，而是显示了tomcat的管理页面。这可不是我们想要的。要解决这个问题，可以修改iis的默认显示页，把默认</p>
<p>的都删除掉，然后增加一个 index.htm 等等，就好了。</p>
<p><br />1,为IIS写注册表<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开注册表编辑器：regedit，选中"HKEY_LOCAL_MACHINE\SOFTWARE"，新建项 "Apache Software Foundation"，然后选中"Apache Software Foundation"，再新建项 "Jakarta Isapi Redirector"，然后选中"Jakarta Isapi Redirector"，再新建项"1.0"，然后再选中"1.0"，在这一项中新建以下5个字符串值,名称和值分别为（不包括等号分界符，下同）:<br />=========================================================================<br />extension_uri=/jakarta/isapi_redirect.dll<br />worker_file=D:\Tomcat5.0\conf\workers.properties<br />worker_mount_file=D:\Tomcat5.0\conf\uriworkermap.properties<br />log_file=D:\Tomcat5.0\logs\isapi.log<br />log_level=info<br />==========================================================================<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你觉得麻烦,请新建文本文件,输入以下内容,保存并更名为jakarta.reg文件,双击导入注册表,也可以达到和上面一样的效果.<br />===========================================================================<br />Windows Registry Editor Version 5.00</p>
<p>[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation]</p>
<p>[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector]</p>
<p>[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0]<br />"extension_uri"="/jakarta/isapi_redirect.dll"<br />"worker_file"="D:\\Tomcat5.0\\conf\\workers.properties"<br />"worker_mount_file"="D:\\Tomcat5.0\\conf\\uriworkermap.properties"<br />"log_file"="D:\\Tomcat5.0\\logs\\isapi.log"<br />"log_level"="info"<br />=================================================================================</p>
<p><span style="color: #ff0000;">注意在注册表文件中，路径必须是 "\\"</span><br />&nbsp;&nbsp;&nbsp; 2，建立配置文件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 按照注册表里所写的，在D:\Tomcat5.0\conf目录下建立两个配置文件，workers.properties和uriworkermap.properties其内容分别为:<br />workers.properties的内容：<br />===============================================================================<br />worker.list=ajp13</p>
<p>worker.ajp13.type=ajp13<br />worker.ajp13.host=www.crazycow.cn<br />worker.ajp13.port=8009<br />========================================================================<br />uriworkermap.properties的内容：<br />=========================================================================<br />/*.jsp=ajp13<br />/*.do=ajp13<br />==========================================================================</p>
<p><span style="color: #ff0000;">注意： 如果写成 /* = ajp13，那么iis的虚拟目录就无效了！可以自己试验一下效果。</span>&nbsp;&nbsp;&nbsp; </p>
<p><strong><span style="color: #ff0000;">关于这个文件里的内容，最好是参考tomcat网站上的文档，非常详细！因为每个项目都不同，所以不会</span></strong></p>
<p><strong><span style="color: #ff0000;">有一个通用的配置！</span></strong></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 3，为jk建立物理目录<br />从Apache的网站上下载jk的1.2.20版本，实际上现在就只有一个isapi_redirect.dll文件。在 D:\Tomcat5.0\bin目录下建立新目录jakarta，将isapi_redirect.dll复制到里面。<br />&nbsp;&nbsp;&nbsp; 4，建立新网站<br />打开IIS管理器，在左侧网站一栏新建网站:www.crazycow.cn，其目录指向上面提到过的空目录H:\Inetpub\www.crazycow.cn，让网站有执行(如ISAPI应用程序或CGI)的权限<br />&nbsp;&nbsp;&nbsp; 5，设置筛选器<br />在IIS管理器左侧网站下面选中新建的网站<a href="http://www.crazycow.cn">www.crazycow.cn</a>，右键选择属性,在ISAPI筛选器标签页添加筛选器，名字为jakarta，路径为isapi_redirect.dll的路径名，即D:\Tomcat5.0\bin\jakarta\isapi_redirect.dll。如果成功重新进入属性页，则该新建的筛选器会有一个绿色向上箭头，优先级为高，这说明jk模块加载成功。<br />&nbsp;&nbsp;&nbsp; 6，为jk建立虚拟目录<br />选中网站<a href="http://www.crazycow.cn">www.crazycow.cn</a>，新建虚拟目录，别名为jakarta，路径为D:\Tomcat5.0\bin\jakarta，使其有执行(如ISAPI应用程序或CGI)的权限。<br />&nbsp;&nbsp;&nbsp; 7，为自己的应用建立虚拟目录<br />选中网站<a href="http://www.crazycow.cn">www.crazycow.cn</a>，新建虚拟目录，别名为blog，路径为H:\Inetpub\blog.crazycow.cn，使其有执行(如ISAPI应用程序或CGI)的权限。<br />&nbsp;&nbsp;&nbsp; 8，新建应用程序扩展<br />在IIS管理器左侧网站下面选中Web服务扩展，添加一个新的Web服务扩展，扩展名为jakarta,添加要求得文件为D:\Tomcat5.0\bin\jakart\isapi_redirect.dll,并设置扩展状态为允许。<br />&nbsp;&nbsp;&nbsp; 9,测试<br />&nbsp;&nbsp;&nbsp;&nbsp; 打开Tomcat服务器，修改h:\WINDOWS\system32\drivers\etc\hosts文件，让<a href="http://www.crazycow.cn">www.crazycow.cn</a>的域名指向127.0.0.1，打开IE，输入<a href="http://www.craycow.cn/blog/test.jsp">http://www.craycow.cn/blog/test.jsp</a>，回车，如果出现当前时间，那说明你配置已经成功。</p>
<p>注意的问题：<br />&nbsp;&nbsp;&nbsp; 刚才说了，如果你没有配置成功也很正常，看下面的问题你注意了没有。我将对应上面的步骤分别解释<br />&nbsp;&nbsp;&nbsp; 1，应该没有什么问题，以前的版本有直接的安装程序，现在却没有了。手册上还说可以直接写配置文件不写注册表，我没有试，主要是不清楚原理。<br />&nbsp;&nbsp;&nbsp; 2，注意你的两个配置文件workers.properties和uriworkermap.properties中的两个worker是不是都叫 ajp13，有没有拼写错误.还有如果你配置网站时做了主机头设置,那你workers.properties文件中worker.ajp13.host 的值应该是<a href="http://www.crazycow.cn">www.crazycow.cn</a>而不是localhost<br />&nbsp;&nbsp;&nbsp; 3，要注意IIS要对这个jakarta目录有足够的权限.如果你的筛选器添加失败很有可能是权限的原因.<br />&nbsp;&nbsp;&nbsp; 4，应该也没有什么问题，不过你可以测试一下你建立的网站，比如在H:\Inetpub\www.crazycow.cn下放置一个简单的 index.html文件，看能不能正常访问。在这里，我们还可以随便敲一个<a href="http://www.crazyoc.cn/xxx.jsp">http://www.crazyoc.cn/xxx.jsp</a>，然后再看 IIS的访问日志，报的是404.0或者404.3错误，前者说明文件或目录无法找到，后者说明文件或目录无法找到：MIME映射策略禁止该请求。<br />&nbsp;&nbsp;&nbsp; 5，这里有可能出现ISAPI筛选器不能加载的问题，状态一栏是红色箭头。打开系统事件查看器，如果发现"HTTP 筛选器 DLL D:\ Tomcat5.0\bin\jakarta\isapi_redirect.dll 加载失败。数据是错误。"，那加载失败的原因应该是权限问题，特别是NTFS文件系统。因为需要IIS加载isapi_redirect.dll，所以IIS对它要有权限，所以可以对D:\Tomcat5.0\bin目录添加IIS_WPG和IUSR这两个用户(也有可能要对D:\Tomcat5.0\conf添加权限)。再重新加载一边，如果还没有成功，那我也没有办法了，只能换个FAT32系统或者其他jk版本，再或者看事件查看器,到网上搜解决办法。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果筛选器加载成功，到这一步，我们还可以做个小小的测试，随便敲一个<a href="http://www.crazyoc.cn/xxx.jsp">http://www.crazyoc.cn/xxx.jsp</a>，再看IIS日志，这时报报的错是：404.2，文件或目录无法找到：锁定策略禁止该请求。这也说明筛选器已经加载成功，只是没有进一步处理。</p>
<p>&nbsp;&nbsp;&nbsp; <span style="color: #ff0000;">如果之前的注册表内容错了，也会导致加载失败！！</span><br />&nbsp;&nbsp;&nbsp; 6，7，8步也应该没有什么问题，除了添加新的Web 服务扩展jakarta之外还要使它允许。另外同样要注意权限的问题，因为涉及到Internet访问，你的虚拟目录好像也应该有IUSR这个权限。还有就是注意拼写不要写错，比如把jakarta写成了jarkata。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 到了第6步，我们还可以做个实验，在IE里输入<a href="http://www.crazycow.cn/blog/xxx.jsp">http://www.crazycow.cn/blog/xxx.jsp</a>,回车,这是IIS日志报的就是503错误了,服务器错,这说明你已成功了一大半,接下来就只剩下开Tomcat.<br />&nbsp;&nbsp;&nbsp; 9，如果你前面都对,只是你输入<a href="http://www.craycow.cn/blog/test.jsp">http://www.craycow.cn/blog/test.jsp</a>,没有出现当前时间.那么还请查看还有你有没有开启 Tomcat,并在Tomcat引擎中是否加载了和IIS相对应的WEB应用?有的人访问jsp时,Tomcat日志里出现对 /jakart/isapi_redirect.dll的访问或者,直接出现乱码或下载jsp文件,都是这里的原因.<br />&nbsp;&nbsp;&nbsp; 总之大致的解决方法是,结合事件查看器的内容,IIS日志,Tomcat日志,一步步的排错,再到网上搜相关的资料.<br />&nbsp;&nbsp;&nbsp; 还要告诉大家的事,整个过程好像没有怎么重启IIS,也没有设置IIS5.0隔离模式.微软这方面做得确实没话说.</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/198395#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 29 May 2008 17:42:54 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/198395</link>
        <guid>http://yananay.javaeye.com/blog/198395</guid>
      </item>
      <item>
        <title>当在IE中遭遇thead</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/196209" style="color:red;">http://yananay.javaeye.com/blog/196209</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          参考下面的这段html:<br /><pre name="code" class="html">
&lt;table id="t1">
  &lt;thead>
   &lt;td>h1&lt;/td>
   &lt;td>h2&lt;/td>
  &lt;/thead>
  &lt;tbody>
    &lt;tr>
      &lt;td>11&lt;/td>
      &lt;td>12&lt;/td>
    &lt;/tr>
    &lt;tr>
      &lt;td>21&lt;/td>
      &lt;td>22&lt;/td>
    &lt;/tr>
  &lt;/tbody>
&lt;/table>
</pre><br /><br />那么，这个table有多少行呢？当然是两行。<br /><br />可是，可是，如果你使用 document.getElementById("t1").rows.length，<br />在IE中，得到的数字竟然是 3！！哎，IE就是如此的弱智！在firefox下就完全正常！<br /><br />解决的办法是使用 document.getElementsByTagName("tbody")[0].rows.length，这样IE就能得到正确的结果了。
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/196209#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 May 2008 17:58:46 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/196209</link>
        <guid>http://yananay.javaeye.com/blog/196209</guid>
      </item>
      <item>
        <title>DWR中提交Form的问题</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/194410" style="color:red;">http://yananay.javaeye.com/blog/194410</a>&nbsp;
          发表时间: 2008年05月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>DWR中提交form的时候，数据都封装在了Map结构中。这样当提交的内容是数组的时候，就会产生问题。</p>
<p>&nbsp;</p>
<p>例如当提交这样的内容的时候，就无法得到正确的数据：</p>
<pre name="code" class="html">&lt;input type=checkbox name="c1"&gt;
&lt;input type=checkbox name="c1"&gt;
&lt;input type=checkbox name="c1"&gt;</pre>
<p>&nbsp;因此用了一个方法来解决这个问题。在form 中，如果是数组类型的变量，那么必须使用 &ldquo;变量_&rdquo;的方式。</p>
<p>所以，上面的三个checkbox 就变成了这样子：</p>
<pre name="code" class="html">&lt;input type=checkbox name="c1_1"&gt;
&lt;input type=checkbox name="c1_2"&gt;
&lt;input type=checkbox name="c1_3"&gt;</pre>
<p>&nbsp;然后使用一个方法来处理一下DWR提交的Map:</p>
<p>&nbsp;</p>
<pre name="code" class="java">	public static Map transferDWRMap(Map dwrFormMap) {
		
		Map treeMap = new java.util.TreeMap();
		treeMap.putAll(dwrFormMap);
		Map resultMap = new HashMap&lt;String, Object&gt;();
		
		Set set = treeMap.keySet();
		Iterator it = set.iterator();
		
		while(it.hasNext()) {
			String key = (String) it.next();
			logger.debug("transferDWRMap  key = " + key);
			int index = key.indexOf("_");
			if(index &gt;= 0) {
				
				String realKey = key.substring(0, index);
				Object value = resultMap.get(realKey);
				if(value != null) {
					if(value instanceof List) {
						((List)value).add(treeMap.get(key));
						resultMap.put(realKey, value);
					} else {
						List valueList = new ArrayList();
						valueList.add(value);
						valueList.add(treeMap.get(key));
						resultMap.put(realKey, valueList);
					}
				} else {
					List valueList = new ArrayList();
					valueList.add(treeMap.get(key));
					resultMap.put(realKey, valueList);
				}				
			} else {
				
				resultMap.put(key, treeMap.get(key));
			}
		}
		return resultMap;
	}</pre>
<p>&nbsp;</p>
<p>&nbsp;下面的是测试类：</p>
<p>&nbsp;</p>
<pre name="code" class="java">	public void testTransferDWRMap() {
		
		Map dwrFormMap = new HashMap();
		
		dwrFormMap.put("id_1", "id_1_value");
		dwrFormMap.put("id_2", "id_2_value");
		dwrFormMap.put("id_3", "id_3_value");
		dwrFormMap.put("id_4", "id_4_value");
		
		dwrFormMap.put("name_1", "name_1_value");
		dwrFormMap.put("name_2", "name_2_value");
		dwrFormMap.put("name_3", "name_3_value");
		dwrFormMap.put("name_4", "name_4_value");
		
		dwrFormMap.put("newName", "tom");
		
		Map resultMap = EShopUtil.transferDWRMap(dwrFormMap);
		
		List idList = (List) resultMap.get("id");
		assertEquals(4, idList.size());
		int index = 1;
		for(Object value : idList) {
			
			String id = (String) value;
			assertEquals("id_"+index+"_value", id);
			index++;
		}
		
		List nameList = (List) resultMap.get("name");
		assertEquals(4, nameList.size());
		index = 1;
		for(Object value : nameList) {
			
			String id = (String) value;
			assertEquals("name_"+index+"_value", id);
			index++;
		}
		
		assertEquals("tom", resultMap.get("newName"));
	}
	
	public void testTransferDWRMap2() {
		
		Map dwrFormMap = new HashMap();
		
		dwrFormMap.put("id_1", "id_1_value");
		
		dwrFormMap.put("name_1", "name_1_value");
		
		dwrFormMap.put("newName", "tom");
		
		Map resultMap = EShopUtil.transferDWRMap(dwrFormMap);
		
		List idList = (List) resultMap.get("id");
		assertEquals(1, idList.size());
		int index = 1;
		for(Object value : idList) {
			
			String id = (String) value;
			assertEquals("id_"+index+"_value", id);
			index++;
		}
		
		List nameList = (List) resultMap.get("name");
		assertEquals(1, nameList.size());
		index = 1;
		for(Object value : nameList) {
			
			String id = (String) value;
			assertEquals("name_"+index+"_value", id);
			index++;
		}
		
		assertEquals("tom", resultMap.get("newName"));
	}</pre>
<p>&nbsp;</p>
<p>&nbsp;所以，提交form的时候，只要保证数组的变量是&ldquo;变量_&rdquo;的形式就可以了，不是数组的变量不要带下划线。这样就减轻了DWR的提交form的处理。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/194410#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 19 May 2008 13:11:34 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/194410</link>
        <guid>http://yananay.javaeye.com/blog/194410</guid>
      </item>
      <item>
        <title>面向资源的开发？</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/184963" style="color:red;">http://yananay.javaeye.com/blog/184963</a>&nbsp;
          发表时间: 2008年04月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: medium;"><strong>&nbsp;原因</strong></span></p>
<p>当一个人做了几年web项目后，那么一定会对web开发有一些想法，一定会找找是不是有更好的方法来进行开发，来避免加班，来避免过多的新人培训。</p>
<p>&nbsp;</p>
<p>最近帮着另外一个组做一个web项目，使用的是structs。于是java开发web应用的噩梦再次上演了。倒不是说应用有多难，但是对于那些众多的structs-config.xml. applicaitoncontext.xml, web.xml已经够够的了。当我编写一个新的功能的时候，我该做什么呢：创建一个Action，修改structs-config.xml，创建一个business，修改applicaitoncontext.xml，哦，我还需要修改ibatis的配置文件。</p>
<p>&nbsp;</p>
<p>如果我今天有点困的话，精神状态不是很好，可能我完成了这个功能以后，一运行的时候就会出错误，然后我再费尽地查找错误，是不是配置漏了？还是配置写错了？还是哪个层写的不对？甚至当我开始下一个功能的时候，我简直怀疑我从Action入手是不是错误了，我应该从 ibatis的配置开始，还是从哪个地方开始？我不停的尝试，不停的被郁闷。</p>
<p>&nbsp;</p>
<p>为什么会这样呢？当我们面对一个用户管理的页面的时候，我们想的是什么？恐怕都是如何把这个html转换成jsp，如何编写各个层次的各种类，应该操作什么样的表，使用什么样的SQL等等。似乎我们的经验是在太丰富了，一个简单的页面展现在眼前的时候，我们竟然就能思考到如此细节的部分。</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>资源</strong></span></p>
<p><strong></strong></p>
<p>难道真的是我们的经验丰富？我可不这样想。为什么面对一个页面的时候，我们会一头扎进细节中去？好吧，这只是一个简单的页面，所作的也只是对用户信息的读取，创建，修改，删除4种操作。为什么这样一个简单的功能也让我们如此的头疼？</p>
<p>&nbsp;</p>
<p>那么我们换一个思路去考虑这个问题。当我们面对一个用户管理的页面的时候，我们应该认为：这个功能只是对&ldquo;用户&ldquo;这个资源的操作。甚至我们也可以说，整个系统中，我们其实要做的就是对资源的操作。</p>
<p>&nbsp;</p>
<p>客户管理系统中，我们要操作的资源是客户信息；进销存系统中，我们需要操作的资源是仓储，销售信息。</p>
<p>&nbsp;</p>
<p>我们甚至可以说，如果一个系统不操作任何资源，那么这个系统就是一个没有必要存在的系统。</p>
<p>&nbsp;</p>
<p>既然如此，当我们要显示客户的信息的时候，为什么要从一个Action开始？Action是什么？是资源吗？不是，Action仅仅是一个动作，是操作资源的细节而已。那么，当我们要察看用户的信息的时候，是不是可以使用 http://sample/employee/list 来访问呢？而不是使用 http://sample/ViewEmployeeAction.do 呢？同样，创建，修改，删除也是使用同样的方式。</p>
<p>&nbsp;</p>
<p>这算什么？ViewEmployeeAction.do 和 employee/list 有什么区别？换个名字而已，换汤不换药！</p>
<p>&nbsp;</p>
<p>真的是换汤不换药吗？可是在我的体会中他们完全不一样。<strong>一个将注意力集中在动作行为上</strong>，<strong>一个将注意力集中在资源上</strong>。好吧，他们的结果完全相同，都是显示一个jsp页面，但他们的过程是不一样的!从而也就导致开发的过程也是完全不一样的。</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>Controller</strong></span></p>
<p>&nbsp;</p>
<p>怎么个完全不一样法呢？前提我们仍然采用mvc的方式。那么在Controller中我们考虑的是什么呢？在structs中，我们要考虑Action，那么现在我们换成考虑资源。那么最自然的想法就是 employee/list 会调用 employee controller 中的 list 方法。不自然的想法可能就是 employee/list 会调用 AbcEmployee controller 的 doList 方法。好吧，不管自然还是不自然，我们都知道我们最终要干的是什么：就是操作资源。</p>
<p>&nbsp;</p>
<p>然而如果使用 ViewEmployeeAction.do 呢？我们最终要干的是什么？我们身经百战，都知道我们要找 ViewEmployeeBusiness ，然后调用一个 DAO 去操作数据库。</p>
<p>&nbsp;</p>
<p>两者站位已经不同，就决定了思考的方式不同，决定架构的不同。</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>Business</strong></span></p>
<p>&nbsp;</p>
<p>既然我们的系统要操作资源，那么业务逻辑算什么呢?操作资源必然要有业务逻辑，例如检索普通用户和检索管理员用户，就是两个不同的逻辑。我认为逻辑应该是资源操作的&ldquo;附加品&ldquo;。例如我要察看全部用户，如果没有逻辑在里面，那么我要看的就是全部的用户资源；如果有了逻辑，我就按照逻辑来查看用户。</p>
<p>&nbsp;</p>
<p>这样，业务就不是系统的核心了，业务仅仅是资源的附属品。业务应该是可以&ldquo;挂&rdquo;到一个资源上的，也应该可以从一个资源上&ldquo;拿&rdquo;下来。这似乎是大逆不道，如今谁不知道业务才是系统的核心，才是系统的灵魂？可是我现在恰恰认为，资源才是系统的核心，系统的灵魂。业务？如果需要你就把它&ldquo;挂&rdquo;到资源上，如果不需要就把它&ldquo;拿&rdquo;下来。</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>总结</strong></span></p>
<p>&nbsp;</p>
<p>这些仅仅是我的想法，是否是正确的想法不得而知。之前学习过一些REST的资料，当时并不能完全的理解，如今总算在实际中对REST有了深切的体会。只是目前的REST，似乎只是将重点集中在Controller部分，我相信在业务层中，资源早晚会成为主角，就如同今天在Controller中一样。</p>
<p>&nbsp;</p>
<p>不过这些都只是我美好的想法，什么时候能够实现？希望能早点到来吧！</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/184963#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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 21 Apr 2008 14:59:35 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/184963</link>
        <guid>http://yananay.javaeye.com/blog/184963</guid>
      </item>
      <item>
        <title>CT中表达式处理的思考</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/180723" style="color:red;">http://yananay.javaeye.com/blog/180723</a>&nbsp;
          发表时间: 2008年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: x-small">目前的CT中，对于表达式的处理是根据操作符的优先级生成一个二叉树。</span></p><p><span style="font-size: x-small">有兴趣的朋友可以看看ExpressionReducer.java 这个类。这种处理方式可以说是中缀表达式的方式吧。然后到解释模板内容的时候，再遍历这个二叉树。</span></p><p>&nbsp;</p><p><span style="font-size: x-small">那么，是不是可以考虑换一种方式呢？也就是后缀表达式的形式。后缀表达式的最终结果就是一个栈的结构，在Java中就好像是一个List。而当对这个表达式进行解释的时候，只需要对栈进行从上到下的访问就可以了。</span></p><p>&nbsp;</p><p><span style="font-size: x-small">两种方式哪个更好？个人觉得后缀表达式更好一些。原因有以下几点：</span></p><p><span style="font-size: x-small">1、使用中缀表达式需要生成一个树形结构，而模板本身为了缓存，进行了序列化操作，从序列化的角度来看，一个栈的</span></p><p><span style="font-size: x-small">&nbsp;&nbsp;&nbsp;结构应该比一个树的结构要简单。</span></p><p><span style="font-size: x-small">2、复杂度上。后缀表达式生成的栈要更简单，这样也就让测试变得更容易。而且也更直观。</span></p><p>&nbsp;</p><p><span style="font-size: x-small">不过我对CT目前仍然不是彻底的了解，或许我的理解有疏漏的地方。这也仅仅是一个想法而已。待更加深入地了解CT后，再回头看看这个想法是否正确吧！</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/180723#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Apr 2008 10:35:10 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/180723</link>
        <guid>http://yananay.javaeye.com/blog/180723</guid>
      </item>
      <item>
        <title>BNF范式</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/179986" style="color:red;">http://yananay.javaeye.com/blog/179986</a>&nbsp;
          发表时间: 2008年04月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          每一个经历都是一个宝贵的财富。加入CommonTemplate也是如此。通过阅读它的代码，我学习了自动机的知识，看到编译原理这个大门。于是，又勾起了我的另一个兴趣：我想看看门的里面到底有什么东西。听说这个门挺重的，不好开，不过没关系，我每天只开１厘米，开到什么程度算什么程度吧！<br />“龙书”的第一章应该是基础，不过其中的bnf不太好理解，发现下面这个文章写的不错，能够帮助理解书的内容。抄录一下，日后再次温习。<br /><br /><br /><br />什么是BNF范式,什么又是EBNF范式?<br />巴科斯范式及其扩展<br />BNF & Augmented BNF    <br />      <br />     什么是巴科斯范式？ <br />   <br />　　巴科斯范式(BNF: Backus-Naur Form 的缩写)是由 John Backus 和 Peter Naur 首先引入的用来描述计算机语言语法的符号集。<br />　　现在，几乎每一位新编程语言书籍的作者都使用巴科斯范式来定义编程语言的语法规则。    <br />      <br />     巴科斯范式的内容   <br /><br />在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。<br />在双引号外的字（有可能有下划线）代表着语法部分。 <br />尖括号( &lt; > )内包含的为必选项。 <br />方括号( [ ] )内包含的为可选项。 <br />大括号( { } )内包含的为可重复0至无数次的项。 <br />竖线( | )表示在其左右两边任选一项，相当于"OR"的意思。 <br />::= 是“被定义为”的意思。 <br />   <br />     巴科斯范式示例   <br /><br />         这是用BNF来定义的Java语言中的For语句的实例： <br /><br />FOR_STATEMENT ::= <br />      "for" "(" ( variable_declaration | <br />  ( expression ";" ) | ";" ) <br />      [ expression ] ";" <br />      [ expression ] ";" <br />      ")" statement  <br /><br />         这是Oracle packages的BNF定义： <br /><br />package_body ::= "package" package_name "is" <br />package_obj_body { package_obj_body } <br />[ "begin" seq_of_statements ] <br />"end" [ package_name ] ";" <br /><br />package_obj_body ::= variable_declaration <br />| subtype_declaration <br />| cursor_declaration <br />| cursor_body <br />| exception_declaration <br />| record_declaration <br />| plsql_table_declaration <br />| procedure_body <br />| function_body <br /><br />procedure_body ::= "procedure" procedure_name <br />[ "(" argument { "," argument } ")" ] <br />"return" return_type <br />"is" <br />[ "declare" declare_spec ";" { declare_spec ";" } ] <br />"begin" <br />seq_of_statements <br />[ "exception" exception_handler { exception_handler } ] <br />"end" [ procedure_name ] ";" <br /><br />statement ::= comment <br />| assignment_statement <br />| exit_statement <br />| goto_statement <br />| if_statement <br />| loop_statement <br />| null_statement <br />| raise_statement <br />| return_statement <br />| sql_statement <br />| plsql_block <br /> <br /><br />    这是用BNF来定义的BNF本身的例子： <br /><br />syntax     ::=  { rule }<br />rule       ::=  identifier  "::="  expression<br />expression ::=  term { "|" term }<br />term       ::=  factor { factor }<br />factor     ::=  identifier |<br />                quoted_symbol |<br />                "("  expression  ")" |<br />                "["  expression  "]" |<br />                "{"  expression  "}"<br />identifier ::=  letter { letter | digit }<br />quoted_symbol ::= """ { any_character } """<br /> <br /><br />     <br />     扩展的巴科斯范式 Augmented BNF  <br />  <br />　　RFC2234 定义了扩展的巴科斯范式(ABNF)。近年来在Internet的定义中ABNF被广泛使用。ABNF做了更多的改进，比如说，在ABNF中，尖括号不再需要。 <br /><br /> <br /> <br />什么是EBNF?<br />基本 (EBNF) 定义有关 EBNF 协定的详细情况，可以参看 Computing Dictionary. <br />这里是要点一览:   "..." : 术语符号  [...] : 选项:最多出现一次  {...} : 重复项: 任意次数，包括 0 次  (...) : 分组    |   : 并列选项，只能选一个斜体字: 参数，在其它地方有解释<br /> <br /><br /> <br />http://estone.nease.net/sgf/sgf4.html#2 里会给出一个EBNF在棋牌类的应用.<br /> <br />--------------------------------------------------------------------------------------------<br /> <br />&lt;BNF>::=     &lt;非终结符>::=&lt;或项列表>   <br />  &lt;或项列表>::=     &lt;项>     |     &lt;或项列表>|&lt;项>   <br />  &lt;项>::=     &lt;非终结符>     |     &lt;终结符>   |   &lt;项>&lt;非终结符>   |   &lt;项>&lt;终结符>   <br />  &lt;非终结符>::=       &lt;非终结符名>   <br />    <br />  （   但愿能有人看得懂:-)   )   <br />    <br />  BNF就是巴科特·瑙尔式的缩写，   <br />  在计算机的史前时代（1950s)，曾有一位大师，他奠定了现代计算机的基础   <br />  在他老人家的诸多成就之中，包括了对形式语言的研究，和发明了高级语言：   <br />  FORTRAN。   <br />  为了纪念他老人家，我们把他提出的一套描述语言的方法叫做BNF   <br />    <br />  其实BNF很简单::=表示定义   |表示或   尖括号(&lt;>)括起来的是非终结符   <br />  所谓非终结符就是语言中某些抽象的概念，终结符就是可以直接出现在   <br />  语言中的符号   <br />    <br />  比如：C语言的声明语句可以用BNF这样描述：   <br />  &lt;声明语句>   ::=   &lt;类型>&lt;标识符>;   |   &lt;类型>&lt;标识符>[&lt;数字>];   <br />  这一句中&lt;声明语句>这个非终结符被定义成了两种形式（上面用|隔开的两部分）   <br />  在这里引入了三个终结符:   分号;     左右方括号[   ]   <br />    <br />  &lt;类型>   ::=   &lt;简单类型>   |   &lt;指针类型>   |   &lt;自定义类型>   <br />  &lt;指针类型>   ::=   &lt;简单类型>   *   |   &lt;自定义类型>   *   <br />  &lt;简单类型>   ::=   int|char|double|float|long|short|void   <br />  &lt;自定义类型>   ::=   enum&lt;标识符>|struct&lt;标识符>|union&lt;标识符>|&lt;标识符>   <br />  到这里就基本上把&lt;类型>定义清楚了   <br />    <br />  &lt;数字>   ::=   0X&lt;十六进制数字串>   |   0&lt;八进制数字串>   |   &lt;十进制数字串>   <br />  &lt;十六进制数字串>   ::=   &lt;十六进制数字>   |   &lt;十六进制数字串>&lt;十六进制数字>     <br />  &lt;八进制数字串>   ::=   &lt;八进制数字>   |   &lt;八进制数字串>&lt;八进制数字>     <br />  &lt;十进制数字串>   ::=   &lt;十进制数字>   |   &lt;十进制数字串>&lt;十进制数字>     <br />  &lt;十六进制数字>   ::=   &lt;十进制数字>   |   A   |   B   |   C   |   D   |   E   |   F   <br />  &lt;十进制数字>     ::=   &lt;八进制数字>   |   8   |   9     <br />  &lt;八进制数字>   ::=   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   <br />  到这里就把&lt;数字>定义清楚了   <br />    <br />  &lt;标识符>   ::=   &lt;字母>   |   &lt;标识符>   &lt;字母数字串>   <br />  &lt;字母数字串>   ::=   &lt;字母>|&lt;十进制数字>|&lt;字母数字串>&lt;字母>|&lt;字母数字串>&lt;十进制数字>     <br />  &lt;字母>   ::=   _   |   &lt;大写字母>   |   &lt;小写字母>   <br />  &lt;小写字母>   ::=   a|b|c|d|e|f|g|h|i|j   ……   （偷个懒）   <br />  &lt;大写字母>   ::=   A|B|C|D|E|F|G|H|I|J   ……   <br />    <br />  到此为止整个声明语句就定义完了（就是说已经没有非终结符了），虽然看起来很   <br />  繁，但前面定义的各种非终结符都可以很容易的在别的地方重用比如，函数声明   <br />  可以定义成下面的样子：   <br />  &lt;函数声明语句>   ::=   &lt;类型>&lt;标识符>(&lt;形参表>);   <br />  &lt;形参表>   ::=   &lt;类型>&lt;标识符>   |   &lt;形参表>,&lt;形参表>   <br />  只用两句就描述完了，所以BNF实际上比用自然语言要简练得多   <br />  （整个C语言只用一二百句就可以描述清楚）   <br />  而且相当的精确，不会有自然语言中那种模棱两可的表达   <br />  如果你对BNF比较敏感的话，会发现C里面的标识符不能由数字开头   <br />  而且在C里面下划线是被当做字母看待的（也就是说能用字母的地方   <br />  都可以用下划线）比如：（最好用老一点的编译器比如PDP11上的cc）   <br />  #define   ____   main   <br />  #define   ___   for   <br />  typedef   char*   _____;   <br />  int   (*______)(char   *,   ...)   =   printf;   //如果这一句不灵，就用下面这句   <br />  //#define   ______   printf                         //如果你用的是C++可以试一下下面这个   <br />  //int   (*______)(const   char   *,   ...)   =   printf;     <br />    <br />  ____(_,char*   __[])   //要是你编译器不吃，可以改成int   ____(int   _,char*__[])   <br />  {   <br />      ___(   ;   _   ;   _   --)   <br />      {   <br />            ______("%s\n",   __[_]);   <br />      }   <br />  }   <br />    <br />  另外，还有一种EBNF就没有正宗的BNF这么爽了，也有很多人在用，前面的   <br />  那些递归的定义被写成了{}   <br />    <br />  有一段时间PASCAL爱好者们喜欢用一个叫语法图的东西，画出来很难看，但   <br />  功能和BNF差不多，现在好象已经没多少人用了   <br />    <br />  近几年流行另一种东西：   <br />  digit   =   one   of   <br />                  0   1   2   3   4   5   6   7   8   9   <br />  这里非终结符digit用斜体表示，one   of是这种方法里定义的一个量词（常用斜黑体）   <br />  我不喜欢这个，因为我眼神不好，常常分不清那个是斜体，那个是正体
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/179986#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 Apr 2008 09:35:02 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/179986</link>
        <guid>http://yananay.javaeye.com/blog/179986</guid>
      </item>
      <item>
        <title>测试驱动？很傻很天真</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/175499" style="color:red;">http://yananay.javaeye.com/blog/175499</a>&nbsp;
          发表时间: 2008年03月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small; font-family: 宋体">我一直认为测试驱动开发可以保证质量，如果要保证质量也必须实行测试驱动开发。我也确实是这么做的，但是就在上个周末，我辛苦&ldquo;经营&rdquo;的测试驱动的项目已经倒下了。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">就是在上个周五的下午，客户突然说要求改动，好家伙，这个改动实在是太大了，保守的估计也需要3-5天吧。可是客户竟然要求当天晚上必须全部修改完毕！</span></p><p>&nbsp;</p><p><span style="font-family: Simsun"><span style="font-size: small">我简直要崩溃了，我怀疑客户到底是用什么部位在进行思考，看着新的需求，脑袋一团乱，怎么可能一个下午作完3-5天的活？？</span></span></p><p><span style="font-family: Simsun"></span></p><p><span style="font-family: Simsun"><span style="font-size: small">无奈归无奈，活还是要做滴。看着如此多，如此新的需求，我分析了半天，决定从其中一块开始入手。我打开了测试工程，在DataSet中增加了一个新的表，写了一个测试，然后运行测试..............天哪！竟然提示连接数据库错误！</span></span></p><p><span style="font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun">怎么搞滴！赶紧看看吧，发现只有这新增加的表会出这个问题！此时忽然记起曾经有一位同仁修改过测试工程的配置。我的头大了！</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">众所周知，M$的产品一旦出现错误，就是那种千奇百怪，难以发现，折磨死人的错误。我分析，google解药，竟然找不到原因！</span></p><p><span style="font-size: small; font-family: Simsun">客户催得紧，这边VS又偏偏不争气，在我被郁闷了两个小时以后，终于无奈的决定，挥泪斩掉测试工程！</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">速度，客户要求的只有速度，我也一样。质量？见鬼去吧！</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">终于在凌晨12点的时候，我完成了1/3的需求。同时进行了&ldquo;简单&rdquo;的测试。到这个阶段，整个项目的1/3的代码已经被我修改了。我的心理实在没有底，只好请求另一个同仁能周六和我一起加班，他进行测试，我仍然进行修改。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">就这样，目前的这个项目只用了短短的2天，就脱离了测试，脱离了持续集成。而当初，我们可是花了1个月时间来积累它的。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">所以，正所谓形势比人强啊！我无奈了。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">看着机器里的半死的测试工程，想想自己之前还很得意于项目的测试驱动和持续集成，突然觉得&ldquo;很傻很天真&rdquo;这个词是如此的亲切。</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/175499#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 24 Mar 2008 16:58:29 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/175499</link>
        <guid>http://yananay.javaeye.com/blog/175499</guid>
      </item>
      <item>
        <title>测试的粘结度</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/173878" style="color:red;">http://yananay.javaeye.com/blog/173878</a>&nbsp;
          发表时间: 2008年03月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small; font-family: 宋体">最近一直在写操作符处理的单元测试。正如liangfei所说，想要更好的优化表达式，首先得十分了解操作符的功能，而写单元测试就是非常好的一个途径。十分赞同这个观点，所以我最近一直在写测试，也确确实实地了解了操作符的功能。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">在测试类中如何获得操作符对象呢？我参考了一下写完的测试类，发现是 new 出来的。可是在程序中，操作符不是new出来的，而是通过一个IOC容器获得的，而且获得是某一种操作符的handler，例如下面这样：</span></p><p>&nbsp;</p><pre name="code" class="java">Configuration config = PropertiesConfigurationLoader.loadStandardConfiguration();
// 默认会取得 StandardOperatorHandlerProvider
operatorHandlerProvider = config.getOperatorHandlerProvider();
handler = operatorHandlerProvider.getUnaryOperatorHandler(&quot;.&quot;);</pre><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">这个handler就是处理&quot;.&quot;符号的了，通过这个handler，再去调用&quot;.&quot;号操作符。这么做的目的我想是为了实现操作符的重载。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">所以，在CommonTemplate里，是不可能直接得到操作符对象的。因此，在测试类中，我也就使用了这种方式，来获得操作符进行测试。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">不过liangfei并不同意这种方式。他认为测试操作符的时候，应该在测试类中 new 出操作符，然后对操作符进行测试。理由是这样可以把要测试的目标功能分隔开来。我的理解就是降低测试的粘结度。但是这样就产生另外一个问题，如何保证 OperatorHandler的正确性？</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun">或许应该再编写测试类，从 OperatorHandler 开始，测试到每一个操作符。这样确实很麻烦。但是如果不做这种测试的话，又不能保证 OperatorHandler 的正确性。</span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">那么测试的粘合度如何控制比较好？例如一个项目，有业务层，和持久层。那么当对这两个层写测试的时候，改如何进行？</span></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">按照所理解的TDD的方式，在实现持久层的时候，必然会写持久层的测试。在写业务层的时候，再去写业务层的测试，这时，业务层的测试也间接包含了持久层的内容。那我们是不是可以跳过持久层的测试？当然不可以。</span></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">所以问题又回来了，对于CommonTemplate来说，我们是不是可以跳过操作符的测试？当然不可以--事实上我们也确实没有跳过，现在写的就是操作符的测试。那么我们可以不可以跳过 OperatorHandler 的测试？也是不可以。不过，OperatorHandler 中逻辑很少，只是按照责任链的模式把变量分配到正确的操作符上。</span></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">因此，我们是不是可以把 OperatorHandler 的测试和操作符的测试一起做了？虽然这样做测试粘合度比较大，但是 OperatorHandler 的逻辑几乎没有，如果再单独对它进行测试，就和测试操作符完全重复了。</span></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">所以，是不是也可以这样考虑，两个类，虽然有关联，但是其中一个类没有逻辑，或者逻辑非常少，那么可以不考虑粘合度，而直接对这两个类一起进行测试？</span></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p><span style="font-size: small; font-family: Simsun"></span></p><p>&nbsp;</p><p><span style="font-size: small; font-family: Simsun"><span style="font-size: small; font-family: Simsun">这个问题我不知道答案。不过我还是遵从liangfei的意见，按照降低粘合度的方式修改了测试类。希望能在以后的积累中，得到一个满意的答案。</span></span></p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/173878#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/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>Wed, 19 Mar 2008 20:21:27 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/173878</link>
        <guid>http://yananay.javaeye.com/blog/173878</guid>
      </item>
      <item>
        <title>为什么质量会这么差？！</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/173847" style="color:red;">http://yananay.javaeye.com/blog/173847</a>&nbsp;
          发表时间: 2008年03月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small; font-family: 宋体">&nbsp;&nbsp;&nbsp; 为什么质量会这么差？！当非常低级的错误出现了，当客户的指责到来了，当客户严厉的信送到了，我们傻眼了。做外包就是这样，我们处于外包链的底层，只能我们被客户骂。可是，我们的质量真的有问题。</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp;&nbsp;&nbsp; 任务多，时间紧，这当然是原因了，可是除此之外呢？做了这么多项目，为什么还会造成这样的结局？？</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp;&nbsp;&nbsp; 分析一下吧：</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp;&nbsp;&nbsp; 1、设计书理解不充分。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很多bug都是一些极其简单的错误，有些简直就是界面样子的错误。经过了3轮测试，竟然都没发现，不能不说失败。所以，这个错误归根到底就是细节问题没有掌握好。</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp;&nbsp;&nbsp; 2、代码中有很多实现都是不合理的，造成修改的时候很难，也很容易修改一个bug，造成一个新的bug。我想无论什么的高手，都无法避免在代码上犯错误。那么如何解决这个问题？我想只有通过review。间隔时间的反复review，就能找出这样的问题。</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp; 3、测试力度不够。这个是这个项目最严重的问题。其实开发过程中，即使有bug也无所谓，只要在测试环节抓得紧，就没有问题。但是这次的测试力度太差了，时间短，人也少。导致很多bug都没有被发现出来。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个地方，觉得另外一个组的方式很好：强行规定，每天每人必须找到10个bug，不然不能下班。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 人都是有惰性的，这种方式可以弥补这一点。</span></p><p><span style="font-size: small; font-family: 宋体">&nbsp; 以后如何避免？目前能想到的只有加强review和测试力度。<br />&nbsp;&nbsp;&nbsp; review是存在于整个项目中的，时刻需要做的。<br />&nbsp;&nbsp;&nbsp; 测试力度则是验收阶段需要做的。</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/173847#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 19 Mar 2008 17:45:19 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/173847</link>
        <guid>http://yananay.javaeye.com/blog/173847</guid>
      </item>
      <item>
        <title>胡思乱想之坚持</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/170267" style="color:red;">http://yananay.javaeye.com/blog/170267</a>&nbsp;
          发表时间: 2008年03月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small"><span style="font-size: medium; font-family: 宋体">&nbsp;&nbsp;&nbsp; 究竟如何才能获得人生的成功，抑或如何才能实现人生自我的价值？每个人每隔一段时间都会询问自己这样类似的问题。而且往往是心情失落的时候。例如当看到同学取得比自己更多的成就；当看到别人优越的生活水平的时候。往往这个时候，会感叹自己为什么不能像别人一样取得如此的成就呢？与之而来的，是一些宏远的计划：某天某天我要实现什么目标，我也要如何如何等等。可是，当第二天起床的闹钟响起的时候，想的却是&ldquo;能不能再让我多睡5分钟？&rdquo;&nbsp;</span></span></p><p><span style="font-size: small"><br /><span style="font-size: medium; font-family: 宋体">&nbsp;&nbsp;&nbsp; 今天也和同事聊起了类似的事情。目前公司的发展确实不顺利，前景不明朗，而且业务并不是十分的好。我们也经常一起讨论公司的前景，以及我们可以做什么。成功的公司很多，有外包的，有互联网的，等等，每一个都是我们的榜样，都是我们的目标。我们应该如何去做才能实现我们的目标？ <br />昨天中午出去的吃饭的时候，头头领着我们到附近的软件园3期转了转，大连未来的目标是10万IT就业人员，软件园3期也逐渐林立了许多高楼。看着这些高楼，以及一些入住的新的公司，我们现在只有眼馋的份。那么我们怎么才能实现这样的目标？吃饭的时候，大伙又是一顿的讨论，各种方面，各种形式，不过最终也算是讨论出了结果，这就是好事。 <br />&nbsp;&nbsp;&nbsp; 今天，我的同事则提出了另一个观点。其实这也是目前很多人存在的观点。他认为公司应该发展其他方面，例如互联网业务，或者信息安全等。当然，最初的时候这并不会作为公司的主业，连副业都算不上，或许仅仅是一种爱好。如果发展的顺利，那么这种爱好也许会带来利润。 <br />怎么说呢，我并不反对这种方式。不过，我列举了一个相反的例子。就如文章一开始所说的，当你羡慕别人优越的生活条件并且想超越的时候，可能会制定一系列的步骤。例如，每天学习英语3个小时，每天学习技术2个小时等等。当然，你也不知道到底哪条方式是正确的。或许真正的方式应该是去巴结一些人，然后弄到项目做做也说不定--当然这没什么不好。 <br />&nbsp;&nbsp;&nbsp; 但怕就怕在当坚持了一个月以后，你发现还是无法超越对方，那么就决定去研究股票了。之后，可能又会去研究房地产，等等。或许，其中的某一条道路你真的成功了，也或许，你一直失败下去。 <br />谁都渴望成功，但是以我目前的人生经历，觉得成功必备的条件之一就是坚持。这条道路未必成功，但是如果你坚持了，你就知道结果。不过，坚持并不等于盲目的顽固，坚持的同时，也要吸收周围的意见，参考其他人的经验。 <br />&nbsp;&nbsp;&nbsp; 我希望我的同事如果决心做，在吸收各种经验之后，仍然决心做，那么就坚持下去。 <br />&nbsp;&nbsp;&nbsp; 我希望公司的目标既然已经确定，在各种讨论之后仍然确定，那么就坚持下去。 <br />&nbsp;&nbsp;&nbsp; 我希望明年，能看到与今年不同的景色。 <br /></span></span></p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/170267#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Mar 2008 18:08:27 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/170267</link>
        <guid>http://yananay.javaeye.com/blog/170267</guid>
      </item>
      <item>
        <title>请将大部分子查询转换为外部连接</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/160591" style="color:red;">http://yananay.javaeye.com/blog/160591</a>&nbsp;
          发表时间: 2008年01月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp; 今天下午，项目代码的review结果送回来了。一共被指摘了50多条，&nbsp;&nbsp; <img title="redface" src="../../images/smiles/icon_redface.gif" border="0" alt="redface" />。其中有这么一条，指摘的内容是我们在SQL中使用了&ldquo; not in &rdquo;这样的子查询，要求我们改成 join 方式。<br />&nbsp;&nbsp;&nbsp; 这条SQL是这个样子的：<br />&nbsp;&nbsp;&nbsp; <pre name="code" class="sql">select x, y, z from table_a where user_id=xxx and user_name
not in (select user_name from table_b)</pre><p>&nbsp;&nbsp; </p><p>&nbsp;</p>&nbsp;&nbsp;&nbsp; 这条SQL怎么可能转化成join方式呢？再说有什么必要吗？ 一时间大家开始嘲笑指摘的人。不过人家毕竟指摘出来了，所以无论如何也得看看是否可以修改。于是乎，就上网找吧，结果一找还真找到了： <p>&nbsp;</p><pre name="code" class="sql">select a.x, a.y, a.z from table_a as a
left join table_b as b on a.user_name=b.user_name
where a.user_id=xxx and b.user_name is null</pre><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp; 哎，真是无比惭愧啊！平时还以为SQL语句不在话下，结果发现自己是那么的无知。 那么修改成join有什么好处呢？好处就是join可以通过索引来优化，而子查询不可以，差别还是很大的。而且ms的文档也说大部分的子查询其实都可以转换为外部连接的方式。 </p><p>&nbsp;</p>&nbsp;&nbsp;&nbsp; 这次也算是学到了一手，以后要将大部分子查询转换为外部连接。
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/160591#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 30 Jan 2008 18:45:24 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/160591</link>
        <guid>http://yananay.javaeye.com/blog/160591</guid>
      </item>
      <item>
        <title>TDD，让我轻轻地靠近你</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/156920" style="color:red;">http://yananay.javaeye.com/blog/156920</a>&nbsp;
          发表时间: 2008年01月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp; TDD这个东东吵吵嚷嚷好多年，但是实践起来就是那么的难，这也是没办法的事--项目已经很紧张了，我们为什么还要花时间在写测试上面？ <p><br />&nbsp;&nbsp;&nbsp; 这么说吧，TDD就好像是一个美女，看着确实很漂亮，可是追到她却需要很大的本钱。好吧，我也不心急，先让我轻轻地靠近你。<br /><br />&nbsp;&nbsp;&nbsp; 那么在对日项目中实行TDD似乎更是难上加难了？因为对日的项目很注重设计文档，他们称之为&ldquo;详细设计&rdquo;。详细到什么程度？详细到变量的名字都起好了，写代码的时候，只要照着文档写就可以了---这其实是个神话，也确实是个神话。为什么呢？我从来不相信有哪个人能凭空想象就把一个复杂的功能设计的如此完美。事实也确实如此。<br />&nbsp;&nbsp;&nbsp; 问题出现了，你想用测试来描述需求，人家不给你这个机会，设计文档都作好了，还用你来用测试去描述需求？而且那些项目的头头都有10几年的经验，TDD？人家可不管这个，现在这个模式最好了，10几年都没出过错！<br />&nbsp;&nbsp;&nbsp; 好吧，似乎我和TDD的缘分也就到这里了，我一个人力量实在太弱小，难道我要从此随波逐流？不是很甘心，&ldquo;爱美之心，人皆有之&rdquo;，所以我决定换个思路。<br /><br />&nbsp;&nbsp;&nbsp; ok，项目的管理方式早就是定式，既然任何人都难以改变，那么我就遵循他。其实写那个所谓的详细设计也并不是一点好处都没有，至少可以锻炼你的抽象思维。这个时候，我没有和任何人提起过TDD这三个字，更没有向领导强烈要求要实行TDD。<br />&nbsp;&nbsp;&nbsp; 当设计进行到80%左右的时候，我开始编写代码了。同样，我没有告诉他们我正在从测试类写起，虽然测试反映的是详细设计的内容，不过那没有关系，因为详细设计反映的也是需求的内容。这个时候我也没向领导说我已经开使TDD了。<br /><br />&nbsp;&nbsp;&nbsp; 终于，详细设计结束的时候，我的代码也完成50%左右了。我每天都在写代码，领导当然不可能看不到，这个时候过来问我写到什么程度了，我也只是说完成了多少。至于TDD？一个字都没提。</p><p><br />&nbsp;&nbsp;&nbsp; 大伙终于开始全部编码了。因为我是最早开始进入开发环境的，所以这个时候我就需要把开发环境和注意事项给大伙讲一下。我告诉他们如何配置环境，到代码的部分时，对经验还不是很丰富的同事说：<span style="color: #ff0000">一定要先写测试类，这样可以帮助你理清楚逻辑</span>。对于比较有资历的同事说：<span style="color: #ff0000">可以先从测试类写起，你看我们都写这么多了</span>。TDD？一个字都没提。<br /><br />&nbsp;&nbsp;&nbsp; 到项目快结束的时候，我们的测试方法达到了80多个。按照我以往的经验，测试方法在10几个，20几个的时候，测试方法的作用不是很明显。当达到50个以上的时候，其中一个重要的作用就会体现出来了：持续集成。<br /><br />&nbsp;&nbsp;&nbsp; 也就在这个时候，我们需要进行一个大的改动，数据库操作层里的很多方法，都需要修改返回值。这是一个非常大的改动，很多地方都影响了逻辑层里的处理方式。<br /><br />&nbsp;&nbsp;&nbsp; 不过，我一点也不担心。当大伙修改完毕，我跑了一下全部的测试，结果发现有几个case没有通过。赶紧找原因吧。原来是逻辑层里的某个地方在修改的时候出现了空指针的代码。<br /><br />&nbsp;&nbsp;&nbsp; 通过这次的改动，让大伙见识到了TDD的威力，之后，大伙对测试类的维护也很用心。<br /><br />&nbsp;&nbsp;&nbsp; 之后的之后，还有很多次的修改，每一次都是通过测试来发现了一些问题。修改了N次之后，我一点都不担心质量的问题---因为所有的测试都能通过！<br /><br />&nbsp;&nbsp;&nbsp; ok，直到现在，我仍然没有提过TDD的一言半语，只是和领导在项目总结的时候提了一次。而且，到目前为止，代码的质量能够得以保证，对于每个人来说也是一个激励，也为下一个项目能坚持写测试注入了一点的动力。<br /><br />&nbsp;&nbsp;&nbsp; 有一次进行一个比较大的改动，对于其中一个改动，我问一个同事：&ldquo;你这么改难道不会出错吗？&rdquo;那个同事说：&ldquo;如果出错的话测试应该能跑出来吧，现在测试都能跑过去。&rdquo; 我反过来被教育了一次，不过我很高兴。<br /><br />&nbsp;&nbsp;&nbsp; 虽然如此，TDD仍然很难被大部分人接受，我仍然不会提TDD三个字，TDD这个美女太漂亮，提出来难免会激起大家心中的各种波澜。<br />&nbsp;&nbsp;&nbsp; 暂时，还是先让我轻轻地靠近你吧。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/156920#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jan 2008 15:47:45 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/156920</link>
        <guid>http://yananay.javaeye.com/blog/156920</guid>
      </item>
      <item>
        <title>温故而知新-spring 2.0 手册阅读笔记(2)  </title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/137507" style="color:red;">http://yananay.javaeye.com/blog/137507</a>&nbsp;
          发表时间: 2007年11月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp; <strong>AOP<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>AOP是Spring一切应用的基础，没有了AOP，Spring就像没了翅膀的鸟---只能在地上蹦跶了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AOP中有一些基础的概念，需要牢记：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、切面。 用个比喻会更形象一些。可以把切面理解成一把菜刀，而其他方法就好像是黏糕，如果你要把所有的黏糕都在某个<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 位置切断，那么就用这个菜刀就行了。这个菜刀，就是我们需要的切面类。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、切入点。切入点一般是一个表达式。用上面的例子来说，就是我们对哪些黏糕&ldquo;下手&rdquo;。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span><span>execution(*&nbsp;com.xyz.someapp.service.*.*(..))&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个切入点就表示所有在 com.xyz.someapp.service 包下的所有类的，所有的方法，我们都要用切面去切一刀。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、 通知。 通过切入点，我们知道要对哪些黏糕下手，但是，我们还得知道要在黏糕的哪个位置下手，是在头部(Before)，<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 尾部(After)，还是首尾(Around)等等。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然AOP部分的内容不少，但是如果使用spring的话，AOP也大多是应用在事务控制里。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果要单独使用AOP，那么就好像是使用了一个双刃剑，所以，能不用就不用，尽量不用。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>事务控制<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>使用注释的方式会让这个过程变得简单，没有理由不使用它。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/137507#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><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 02 Nov 2007 09:45:04 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/137507</link>
        <guid>http://yananay.javaeye.com/blog/137507</guid>
      </item>
      <item>
        <title>温故而知新-spring 2.0 手册阅读笔记(1)</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/137231" style="color:red;">http://yananay.javaeye.com/blog/137231</a>&nbsp;
          发表时间: 2007年11月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp; 虽然在一些项目中用过几次Spring，但是Spring内容&ldquo;博大精深&rdquo;，而且其配置又是&ldquo;千奇百怪&rdquo;，所以决定重新看看spring2.0<br />
的开发手册，希望可以做到&ldquo;温故而知新&rdquo;。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>控制反转容器</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;&nbsp; <strong>容器和bean的基本原理<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>这部分的内容不是很难理解，毕竟万变不离其宗。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>依赖<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 延迟初始化bean<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong>&nbsp;&nbsp;&nbsp;&nbsp; lazy-load真的好吗？至少目前没发现好的地方。因为在服务器启动的时候把全部bean全部载入进来，至少可以让以后<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 的运行速度加快。启动的速度慢，又有什么关系呢？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>自动装配（autowire）协作者<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>这个特性虽然灵活，可却是一个双刃剑。总的来说，以目前的理解能力，并不推荐使用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>方法注入<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>确实是一个强大的功能，不过仍然觉得不是十分必要的话，就不要去使用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>bean的作用域<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>这个特性非常重要。使用了这个特性，我们就不必再使用 session.getAttribute()了。在今后的应用中，一定要尽力使用这<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 个特性，避免去使用session。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>定制bean特性<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean定义的继承<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 容器扩展点<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>这些应该是比较高级或者灵活的应用，不过目前还想不到需要此应用的场景。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>ApplicationContext<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>这部分的内容仍然非常重要，加强记忆。</p>
<p>控制反转容器可以说是Spring的基础中的基础。理解好这部分内容，有助于其他内容的理解。<br />
不过恐怕多数人更愿意只使用此部分最简单的配置---因为谁也不想陷入bean配置文件的泥潭。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>资源<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>Spring提供了许多手段来访问资源。如果没有特殊原因，还是使用这些方式更好一些，没有必要自己去写。对于路径里的统配<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 符，觉得使用过多会比较乱，能不能尽量不用。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>校验，数据绑定<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>Spring虽然提供了校验功能，不过这部分功能完全可以自己实现，当然，使用Spring的也没什么坏处。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>BeanWrapper与属性编辑器<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>BeanWrapper展示了一个设计思想，我想其价值大于使用的价值。属性编辑器提供了强大的功能，不过，有些功能用属性<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编辑器来做似乎大材小用，完全可以用一个function来实现。</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/137231#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 01 Nov 2007 11:22:41 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/137231</link>
        <guid>http://yananay.javaeye.com/blog/137231</guid>
      </item>
      <item>
        <title>性能的调优，不可忽视的教训</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/135871" style="color:red;">http://yananay.javaeye.com/blog/135871</a>&nbsp;
          发表时间: 2007年10月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp; 有一台服务器，CPU是1G，内存是512M，配置很低了。在上面运行着几个asp的站点，还有一个jboss的应用，此外，在jboss里还运行着一个xplanner。不过jboss的前端没有apache服务器，用户直接访问jboss。就是这么一个服务器，发现jboss的应用访问的时候特别的慢。到底是什么原因？</p>
<ol>
    <li>&nbsp;&nbsp;&nbsp; 有可能是程序的问题。<br />
    &nbsp;&nbsp;&nbsp; 但是程序在开发环境运行的时候，速度没有任何问题。即使在服务器上，通过log也可以看出来，后台的处理速度<br />
    &nbsp;&nbsp;&nbsp; 很快，但是在客户端显示页面却非常慢。 </li>
    <li>&nbsp;&nbsp;&nbsp; 有可能是服务器性能的问题。<br />
    &nbsp;&nbsp;&nbsp; 但是其他的j应用则没有问题。 </li>
</ol>
<p>&nbsp;&nbsp;&nbsp; 经过多次测试发现，程序的处理速度不是问题，问题在于页面显示需要大量的时间。因为在页面中hidden了许多变量，难道是这些hidden变量导致了页面信息过多，所以显示慢？这也很难成立，因为在许多其他的应用了，hidden的信息更多，也没有这么慢的情况。</p>
<p>&nbsp;&nbsp;&nbsp; 最后，推测可能的原因就是缺少apache的缘故。那么前端为什么需要一个apache？在网上找了一些，又问了许多人，都是仅仅知道一个模糊的概念，没有人从根本上说明为什么大部分的应用都需要在前端放置一个apache。</p>
<p>&nbsp;&nbsp;&nbsp; 不过，个人猜测或许jboss提供的http服务性能太差，而apache可以弥补这一点。不管怎么样，还是先试验一下。按照文档，将jboss 和 apache进行了整合。然后测试速度，结果发现：响应时间提高了很多倍！</p>
<p>&nbsp;&nbsp;&nbsp; 因为之前没有真正地架设过站点，所以一直以为有没有apache这样的web服务器是无所谓的，今天终于发现，区别是如此的大。原因还没有从根本上找到答案，但至少可以确定，application server的http服务，是不能用在产品环境里的。</p>
<p>附录一下 jboss 和&nbsp; apache整合的文档：</p>
<div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">本文介绍在</span><span style="FONT-SIZE: 12pt">Win2k</span><span style="FONT-SIZE: 12pt">环境下，用</span><span style="FONT-SIZE: 12pt">modjk1.2.x</span><span style="FONT-SIZE: 12pt">集成</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">、</span><span style="FONT-SIZE: 12pt">Tomcat</span><span style="FONT-SIZE: 12pt">和</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">；文章最后用一</span><span style="FONT-SIZE: 12pt">jsp</span><span style="FONT-SIZE: 12pt">文件测试了该集成环境。</span></div>
<div><strong><font size="5"><span style="FONT-SIZE: 14pt">1.1 主要步骤</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">①</span><span style="FONT-SIZE: 12pt">下载集成</span><span style="FONT-SIZE: 12pt">Tomcat</span><span style="FONT-SIZE: 12pt">的</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">、</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">和</span><span style="FONT-SIZE: 12pt">modjk1.2.x</span><span style="FONT-SIZE: 12pt">。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">②</span><span style="FONT-SIZE: 12pt">修改</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">中的配置文件</span><span style="FONT-SIZE: 12pt">httpd.conf</span><span style="FONT-SIZE: 12pt">。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">③</span><span style="FONT-SIZE: 12pt">在</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">中创建新文件</span><span style="FONT-SIZE: 12pt">workers.properties</span><span style="FONT-SIZE: 12pt">。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">④</span><span style="FONT-SIZE: 12pt">在</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">中创建新文件</span><span style="FONT-SIZE: 12pt">uriworkermap.properties</span><span style="FONT-SIZE: 12pt">。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">⑤</span><span style="FONT-SIZE: 12pt">重新启动</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">⑥</span><span style="FONT-SIZE: 12pt">修改</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">中的</span><span style="FONT-SIZE: 12pt">server.xml</span><span style="FONT-SIZE: 12pt">和</span><span style="FONT-SIZE: 12pt">jboss-service.xml</span><span style="FONT-SIZE: 12pt">文件。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">⑦</span><span style="FONT-SIZE: 12pt">启动</span><span style="FONT-SIZE: 12pt">Jboss Application Server</span><span style="FONT-SIZE: 12pt">。</span></div>
<div><strong><font size="5"><span style="FONT-SIZE: 14pt">1.2 详细说明</span></font></strong></div>
<div><strong><font size="4"><span style="FONT-SIZE: 12pt">1.2.1 软件的下载和安装</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">本文所用的软件版本为：</span><span style="FONT-SIZE: 12pt">j2sdk1.4</span><span style="FONT-SIZE: 12pt">、</span><span style="FONT-SIZE: 12pt">Jboss3.2.7</span><span style="FONT-SIZE: 12pt">、</span><span style="FONT-SIZE: 12pt">Apache2.0</span><span style="FONT-SIZE: 12pt">和</span><span style="FONT-SIZE: 12pt">mod_jk-1.2.14</span><span style="FONT-SIZE: 12pt">。</span><span style="FONT-SIZE: 12pt">jdk</span><span style="FONT-SIZE: 12pt">的下载，安装和配置本文不再多说，用过</span><span style="FONT-SIZE: 12pt">java</span><span style="FONT-SIZE: 12pt">语言的人肯定都知道。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">①</span><span style="FONT-SIZE: 12pt">集成</span><span style="FONT-SIZE: 12pt">Tomcat</span><span style="FONT-SIZE: 12pt">的</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">的下载</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">从</span><span style="FONT-SIZE: 12pt"><a href="http://www.jboss.com/downloads/index"><font color="#355ea0">http://www.jboss.com/downloads/index</font></a></span><span style="FONT-SIZE: 12pt">下载</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">。将</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">安装到</span><span style="FONT-SIZE: 12pt">c:\javaApp</span><span style="FONT-SIZE: 12pt">目录下。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">②</span><span style="FONT-SIZE: 12pt"> Apache</span><span style="FONT-SIZE: 12pt">的下载</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">从</span><span style="FONT-SIZE: 12pt"><a href="http://httpd.apache.org/"><font color="#355ea0">http://httpd.apache.org/</font></a></span><span style="FONT-SIZE: 12pt">下载</span><span style="FONT-SIZE: 12pt">Apache2.0</span><span style="FONT-SIZE: 12pt">。将</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">安装到</span><span style="FONT-SIZE: 12pt">c:\javaApp</span><span style="FONT-SIZE: 12pt">目录下。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">③</span><span style="FONT-SIZE: 12pt"> modjk</span><span style="FONT-SIZE: 12pt">的下载</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">从</span><span style="FONT-SIZE: 12pt"><font size="2" color="#355ea0"><a href="http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/win32/">http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/win32/</a></font></span></div>
<span style="FONT-SIZE: 12pt">下载</span><span style="FONT-SIZE: 12pt">mod_jk</span><span style="FONT-SIZE: 12pt">。把</span><span style="FONT-SIZE: 12pt">mod_jk-1.2.x.so</span><span style="FONT-SIZE: 12pt">文件拷贝到</span><span style="FONT-SIZE: 12pt">Apache2\modules</span><span style="FONT-SIZE: 12pt">目录下。</span>
<div><strong><font size="4"><span style="FONT-SIZE: 12pt">1.2.2 httpd.conf文件的修改</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">打开</span><span style="FONT-SIZE: 12pt">Apache2\conf</span><span style="FONT-SIZE: 12pt">目录下的</span><span style="FONT-SIZE: 12pt">httpd.conf</span><span style="FONT-SIZE: 12pt">文件，找到其中的</span><span style="FONT-SIZE: 12pt">LoadModule</span><span style="FONT-SIZE: 12pt">，然后在</span><span style="FONT-SIZE: 12pt">LoadModule</span><span style="FONT-SIZE: 12pt">的最后一行，加上下面的代码：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Load mod_jk module</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Specify the filename of the mod_jk lib</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">LoadModule jk_module modules/mod_jk-1.2.14.so</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">再在</span><span style="FONT-SIZE: 12pt">httpd.conf</span><span style="FONT-SIZE: 12pt">文件的最后，加上下面的代码：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Where to find workers.properties</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JKWorkersFile conf/workers.properties</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Where to put jk logs</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JKLogFile logs/jk.log</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Set the jk log level [debug/error/info]</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JKLogLevel normal</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Select the log format</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkLogStampFormat&nbsp;&quot;[%a %b %d %H:%M:%S %Y]&quot;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># JkOptions indicates to send SSK KEY SIZE</span></div>
<div><span style="FONT-SIZE: 12pt"><font size="2">#JkOptions+ForwardKeySize+ForwardURICompat-ForwardDirectories</font></span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># JkRequestLogFormat</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkRequestLogFormat &quot;%w %V %T&quot;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Mount your applications</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JKMount /web_application/* node1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkMount /web-console/* node1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkMount /jmx-console/* node1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># You can use external file for mount points.</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># It will be checked for updates each 60 seconds.</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># The format of the file is: /url=worker</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># /examples/*=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkMountFile conf/uriworkermap.properties</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Add shared memory.</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># This directive is present with 1.2.10 and</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># later versions of mod_jk, and is needed for</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># for load balancing to work properly</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># If there&rsquo;s no this file under logs directory, create it manually.</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkShmFile logs/jk.shm </span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Add jkstatus for managing runtime data</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;Location /jkstatus/&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JkMount status</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">Order deny,allow</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">Deny from all</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">Allow from 127.0.0.1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;/Location&gt;&nbsp;&nbsp;&nbsp; </span></div>
<div><strong><font size="4"><span style="FONT-SIZE: 12pt">1.2.3 创建workers.properties文件</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">在</span><span style="FONT-SIZE: 12pt">Apache2\conf</span><span style="FONT-SIZE: 12pt">目录下创建一新文件</span><span style="FONT-SIZE: 12pt">workers.properties</span><span style="FONT-SIZE: 12pt">，文件包含下面的内容：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Define list of workers that will be used</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># for mapping requests</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.list=loadbalancer,status</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Define Node1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node1.port=8009</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># You can modify the Ip address to the actual Ip address</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node1.host=127.0.0.1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node1.type=ajp13</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node1.lbfactor=1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">#worker.node1.local_worker=1 (1)</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node1.cachesize=10</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Define Node2</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node2.port=8009</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># You can modify the Ip address to the actual Ip address</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node2.host= 127.0.0.1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node2.type=ajp13</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node2.lbfactor=1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">#worker.node2.local_worker=1 (1)</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.node2.cachesize=10</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Load-balancing behavior</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.loadbalancer.type=lb</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.loadbalancer.balance_workers=node1, node2</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.loadbalancer.sticky_session=1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.loadbalancer.local_worker_only=1</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.list=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Status worker for managing load balancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">worker.status.type=status</span></div>
<div><strong><font size="4"><span style="FONT-SIZE: 12pt">1.2.4 创建uriworkermap.properties文件</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">在</span><span style="FONT-SIZE: 12pt">Apache2\conf</span><span style="FONT-SIZE: 12pt">目录下创建一新文件</span><span style="FONT-SIZE: 12pt">uriworkermap.properties</span><span style="FONT-SIZE: 12pt">，文件包含下面的内容：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Simple worker configuration file</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># Mount the Servlet context to the ajp13 worker</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/jmx-console=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/jmx-console/*=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/web-console=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/web-console/*=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># You should modify the &ldquo;web_application&rdquo; to</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt"># the real name of the web application</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/ web_application =loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/ web_application /*=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">做完上面的所有步骤后，重新启动</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">。</span></div>
<div><strong><font size="4"><span style="FONT-SIZE: 12pt">1.2.5 修改Jboss中的server.xml和jboss-service.xml文件</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">打开</span><span style="FONT-SIZE: 12pt">jboss-3.2.7\server\default\deploy\jbossweb-tomcat50.sar</span><span style="FONT-SIZE: 12pt">目录下的</span><span style="FONT-SIZE: 12pt">server.xml</span><span style="FONT-SIZE: 12pt">文件。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">把</span><span style="FONT-SIZE: 12pt">&lt;Engine name=&quot;jboss.web&quot; defaultHost=&quot;localhost&quot;&gt;</span><span style="FONT-SIZE: 12pt">修改为：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;Engine name=&quot;jboss.web&quot; defaultHost=&quot;localhost&quot; </span></div>
<div style="TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">jvmRoute=&quot;node1&quot;&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">因为集成</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">后，由</span><span style="FONT-SIZE: 12pt">Apache</span><span style="FONT-SIZE: 12pt">来处理</span><span style="FONT-SIZE: 12pt">Http</span><span style="FONT-SIZE: 12pt">请求，所以可以把下面的代码注释掉：</span></div>
<div><font size="2"><span style="FONT-SIZE: 12pt">&lt;Connector port=&quot;8080&quot; address=&quot;${jboss.bind.address}&quot;</span></font></div>
<div><font size="2"><span style="FONT-SIZE: 12pt">maxThreads=&quot;150&quot; minSpareThreads=&quot;25&quot; maxSpareThreads=&quot;75&quot;</span></font></div>
<div><font size="2"><span style="FONT-SIZE: 12pt">enableLookups=&quot;false&quot; redirectPort=&quot;8443&quot; acceptCount=&quot;100&quot;</span></font></div>
<div><span style="FONT-SIZE: 12pt"><font size="2">connectionTimeout=&quot;20000&quot; disableUploadTimeout=&quot;true&quot;/&gt;</font></span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">打开</span><span style="FONT-SIZE: 12pt">jboss-3.2.7\server\default\deploy\jbossweb-tomcat50.sar\ </span></div>
<div><span style="FONT-SIZE: 12pt">META-INF</span><span style="FONT-SIZE: 12pt">目录下的</span><span style="FONT-SIZE: 12pt">jboss-service.xml</span><span style="FONT-SIZE: 12pt">文件。</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">把</span><span style="FONT-SIZE: 12pt">&lt;attribute name=&quot;UseJK&quot;&gt;false&lt;/attribute&gt;</span><span style="FONT-SIZE: 12pt">修改为：</span></div>
<div><span style="FONT-SIZE: 12pt">&lt;attribute name=&quot;UseJK&quot;&gt;true&lt;/attribute&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">启动</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">，在</span><span style="FONT-SIZE: 12pt">IE</span><span style="FONT-SIZE: 12pt">浏览器中输入</span><span style="FONT-SIZE: 12pt"><a href="http://127.0.0.1/web-console"><font color="#355ea0">http://127.0.0.1/web-console</font></a></span><span style="FONT-SIZE: 12pt">，如果配置成功，将显示</span><span style="FONT-SIZE: 12pt">Jboss</span><span style="FONT-SIZE: 12pt">的</span><span style="FONT-SIZE: 12pt">web</span><span style="FONT-SIZE: 12pt">管理页面。</span></div>
<div><strong><font size="5"><span style="FONT-SIZE: 14pt">1.3 测试jsp文件</span></font></strong></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">在</span><span style="FONT-SIZE: 12pt">jboss-3.2.7\server\default\deploy</span><span style="FONT-SIZE: 12pt">目录下新建一个</span><span style="FONT-SIZE: 12pt">helloworld</span><span style="FONT-SIZE: 12pt">目录，然后在</span><span style="FONT-SIZE: 12pt">helloworld</span><span style="FONT-SIZE: 12pt">目录下新建一个</span><span style="FONT-SIZE: 12pt">hello.war</span><span style="FONT-SIZE: 12pt">目录。在</span><span style="FONT-SIZE: 12pt">hello.war</span><span style="FONT-SIZE: 12pt">目录下创建一个</span><span style="FONT-SIZE: 12pt">test.jsp</span><span style="FONT-SIZE: 12pt">文件，文件代码如下：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;HEAD&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;TITLE&gt;test.jsp&lt;/TITLE&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;/HEAD&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;BODY topMargin=0 marginheight=&quot;0&quot;&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;DIV align=center&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;%</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">String helloworld = &quot;Hello world!&quot;;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">out.println(helloworld);</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">%&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;/DIV&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;/BODY&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">&lt;/HTML&gt;</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">修改</span><span style="FONT-SIZE: 12pt">uriworkermap.properties</span><span style="FONT-SIZE: 12pt">文件，添加下面的代码：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/hello=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">/hello/*=loadbalancer</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">修改</span><span style="FONT-SIZE: 12pt">httpd.conf</span><span style="FONT-SIZE: 12pt">文件，添加下面的代码：</span></div>
<div style="TEXT-INDENT: 12pt"><span style="FONT-SIZE: 12pt">JKMount /hello/* node1</span></div>
<div style="TEXT-INDENT: 10.5pt"><span style="FONT-SIZE: 12pt">打开IE，输入</span><span style="FONT-SIZE: 12pt"><a href="http://127.0.0.1/hello/test.jsp"><font color="#355ea0">http://127.0.0.1/hello/test.jsp</font></a></span><span style="FONT-SIZE: 12pt">，页面将显示出</span><br />
Hello world!<br />
<br />
</div>
<div><span style="FONT-SIZE: 12pt">作者：蔡晓均</span></div>
<div><span style="FONT-SIZE: 12pt">E-mail</span><span style="FONT-SIZE: 12pt">地址：</span><span style="FONT-SIZE: 12pt"><a href="mailto:neptunecai@yahoo.com.cn"><font color="#355ea0">neptunecai@yahoo.com.cn</font></a></span></div>
<span style="FONT-SIZE: 12pt">版权所有，转摘请注明：摘自</span><span style="FONT-SIZE: 12pt"><a href="http://www.blogjava.net/neptune/archive/2005/neptune"><font color="#355ea0">www.blogjava.net/neptune</font></a></span></div>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/135871#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 27 Oct 2007 13:45:27 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/135871</link>
        <guid>http://yananay.javaeye.com/blog/135871</guid>
      </item>
      <item>
        <title>link tips</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/133206" style="color:red;">http://yananay.javaeye.com/blog/133206</a>&nbsp;
          发表时间: 2007年10月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><font face="Arial">&quot;<font face="Arial"><a href="http://trans.hiragana.jp/ruby/">http://trans.hiragana.jp/ruby/</a>+日文网站地址</font>&quot; 可以在页面上标注假名。<br />
例如&ldquo;<font face="Arial">http://trans.hiragana.jp/ruby/http://dailynews.yahoo.co.jp/fc/science/alien_species/?1192688012</font>&rdquo;<br />
</font><font face="Arial"><a href="http://trans.hiragana.jp/ruby/">http://trans.hiragana.jp/ruby/</a></font></p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://yananay.javaeye.com/blog/133206#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 18 Oct 2007 15:08:48 +0800</pubDate>
        <link>http://yananay.javaeye.com/blog/133206</link>
        <guid>http://yananay.javaeye.com/blog/133206</guid>
      </item>
      <item>
        <title>css tips</title>
        <author>yananay</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yananay.javaeye.com">yananay</a>&nbsp;
          链接：<a href="http://yananay.javaeye.com/blog/133120" style="color:red;">http://yananay.javaeye.com/blog/133120</a>&nbsp;
          发表时间: 2007年10月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong><font size="3">id 和 class</font></strong></p>
<p>id 用 &ldquo;.&ldquo; 来表示，例如<br />
</p>
<pre><code> .bar {} </code></pre>
<p>&nbsp;</p>
<p>class 用 &ldquo;#&rdquo;来表示，例如<br />
</p>
<pre><code>  #bar {} </code></pre>
<pre><code><strong><font size="3">布局需要注意的问题</font></strong></code></pre>
<pre><code><code>float:none|left|right<br />取值：<br />none:　默认值。对象不飘浮<br />left:　文本流向对象的右边<br />right:　文本流向对象的左边 <br />它是怎样工作的，看个一行两列的例子<br />xhtml:</code></code></pre>
<pre><code><code><br /><div class="code_title">xml 代码</div><div class="dp-highlighter"><div class="bar"></div><ol class="dp-x