<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>hintcnuie</title>
    <description></description>
    <link>http://hintcnuie.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>Web cache 说明</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/213084" style="color:red;">http://hintcnuie.javaeye.com/blog/213084</a>&nbsp;
          发表时间: 2008年07月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="entry-body">
<p>原文（英文）地址： <a href="http://www.mnot.net/cache_docs/">http://www.mnot.net/cache_docs/</a>&nbsp; 版权声明：<a href="http://creativecommons.org/licenses/by-nc-nd/2.0/deed.zh">署名-非商业性使用-禁止演绎 2.0</a></p>
<p>这是一篇知识性的文档，主要目的是为了让Web缓存相关概念更容易被开发者理解并应用于实际的应用环境中。为了简要起见，某些实现方面的细节被简化或省略了。如果你更关心细节实现则完全不必耐心看完本文，后面参考文档和更多深入阅读部分可能是你更需要的内容。</p>
<ol>
<li>什么是Web缓存，为什么要使用它？ </li>
<li>缓存的类型： <ol>
<li>浏览器缓存； </li>
<li>代理服务器缓存； </li>
</ol></li>
<li>Web缓存无害吗？为什么要鼓励缓存？ </li>
<li>Web缓存如何工作： </li>
<li>如何控制（控制不）缓存： <ol>
<li>HTML Meta标签 vs. HTTP头信息； </li>
<li>Pragma HTTP头信息（为什么不起作用）； </li>
<li>使用Expires（过期时间）HTTP头信息控制保鲜期； </li>
<li>Cache-Control（缓存控制） HTTP头信息；<br /></li>
<li>校验参数和校验； </li>
</ol></li>
<li>创建利于缓存网站的窍门； </li>
<li>编写利于缓存的脚本； </li>
<li>常见问题解答； </li>
<li>缓存机制的实现：Web服务器端配置； </li>
<li>缓存机制的实现：服务器端脚本； </li>
<li>参考文档和深入阅读； </li>
<li>关于本文档； </li>
</ol></div>
<div class="entry-more" id="more">
<h3>什么是Web缓存，为什么要使用它？</h3>
Web缓存位于Web服务器之间（1个或多个，内容源服务器）和客户端之间（1个或多个）：缓存会根据进来的请求保存输出内容的副本，例如html页面， 图片，文件（统称为副本），然后，当下一个请求来到的时候：如果是相同的URL，缓存直接使用副本响应访问请求，而不是向源服务器再次发送请求。<br /><br />使用缓存主要有2大理由：<br />
<ul>
<li><strong>减少相应延迟</strong>：因为请求从缓存服务器（离客户端更近）而不是源服务器被相应，这个过程耗时更少，让web服务器看上去相应更快； </li>
<li><strong>减少网络带宽消耗</strong>：当副本被重用时会减低客户端的带宽消耗；客户可以节省带宽费用，控制带宽的需求的增长并更易于管理。 </li>
</ul>
<h3><span style="font-weight: bold;">缓存的类型</span></h3>
<h4>浏览器缓存 </h4>
<p>对于新一代的Web浏览器来说（例如：IE，Firefox）：一般都能在设置对话框中发现关于缓存的设置，通过在你的电脑上僻处一块硬盘空间用于存储你已经看过的网站的副本。浏览器缓存根据非常简单的规则进行工作：在同一个会话过程中（在当前浏览器没有被关闭之前）会检查一次并确定缓存的副本足够新。这个缓存对于用户点击&ldquo;后退&rdquo;或者点击刚访问过的链接特别有用，如果你浏览过程中访问到同一个图片，这些图片可以从浏览器缓存中调出而即时显现。</p>
<h4>代理服务器缓存</h4>
<p>Web代理服务器使用同样的缓存原理，只是规模更大。代理服务器群为成百上千用户服务使用同样的机制；大公司和ISP经常在他们的防火墙上架设代理缓存或者单独的缓存设备；</p>
<p>由于带路服务器缓存并非客户端或者源服务器的一部分，而是位于原网络之外，请求必须路由到他们才能起作用。一个方法是手工设置你的浏览器：告诉浏览器使用 那个代理，另外一个是通过中间服务器：这个中间服务器处理所有的web请求，并将请求转发到后台网络，而用户不必配置代理，甚至不必知道代理的存在；</p>
<p>代理服务器缓存：是一个共享缓存，不只为一个用户服务，经常为大量用户使用，因此在减少相应时间和带宽使用方面很有效：因为同一个副本会被重用多次。</p>
<h4>网关缓存</h4>
<p>也被称为反向代理缓存或间接代理缓存，网关缓存也是一个中间服务器，和内网管理员部署缓存用于节省带宽不同：网关缓存一般是网站管理员自己部署：让他们的网站更容易扩展并获得更好的性能；<br />请求有几种方法被路由到网关缓存服务器上：其中典型的是让用一台或多台负载均衡服务器从客户端看上去是源服务器；<br /><br />网络内容发布商&nbsp; (Content delivery networks CDNs)分布网关缓存到整个（或部分）互联网上，并出售缓存服务给需要的网站，<a href="http://www.speedera.com/">Speedera</a>和<a href="http://www.akamai.com/">Akamai</a>&nbsp;,<a href="http://www.bt285.cn/">BT</a>就是典型的网络内容发布商(下文简称CDN)。<br /><br />本问主要关注于浏览器和代理缓存，当然，有些信息对于网关缓存也同样有效；</p>
<h3>Web缓存无害吗？为什么要鼓励缓存？</h3>
<p>Web缓存在互联网上最容易被误解的技术之一：网站管理员经常怕对网站失去控制，由于代理缓存会&ldquo;隐藏&rdquo;他们的用户，让他们感觉难以监控谁在使用他们的网站。<br />不幸的是：就算不考虑Web缓存，互联网上也有很多网站使用非常多的参数以便管理员精确地跟踪用户如何使用他们的网站；如果这类问题也是你关心的，本文将告诉你如何获得精确的统计而不必将网站设计的非常缓存不友好。<br />另外一个抱怨是缓存会给用户过期或失效的数据；无论如何：本文可以告诉你怎样配置你的服务器来控制你的内容将被如何缓存。<br /><br />CDN是另外一个有趣的方向，和其他代理缓存不同：CDN的网关缓存为希望被缓存的网站服务，没有以上顾虑。即使你使用了CDN，你也要考虑后续的代理服务器缓存和浏览器缓存问题。</p>
<p>另外一方面：如果良好地规划了你的网站，缓存会有助于网站服务更快，并节省服务器负载和互联网的链接请求。这个改善是显著的：一个难以缓存的网站可能需要几秒去载入页面，而对比有缓存的网站页面几乎是即时显现：用户更喜欢速度快的网站并更经常的访问；</p>
<p>这样想：很多大型互联网公司为全世界服务器群投入上百万资金，为的就是让用户访问尽可能快，客户端缓存也是这个目的，只不过更靠近用户一端，而且最好的一点是你甚至根本不用为此付费。</p>
<p>事实上，无论你是否喜欢，代理服务器和浏览器都回启用缓存。如果你没有配置网站正确的缓存，他们会按照缺省或者缓存管理员的策略进行缓存。<br /></p>
<h3>缓存如何工作</h3>
<p>所有的缓存都用一套规则来帮助他们决定什么时候使用缓存中的副本提供服务（假设有副本可用的情况下）；一些规则在协议中有定义（HTTP协议1.0和1.1），一些规则由缓存的管理员设置（浏览器的用户或者代理服务器的管理员）；<br />一般说来：遵循以下基本的规则（不必担心，你不必知道所有的细节，细节将随后说明）</p>
<ol>
<li>如果响应头信息：告诉缓存器不要保留缓存，缓存器就不会缓存相应内容； </li>
<li>如果请求信息是需要认证或者安全加密的，相应内容也不会被缓存； </li>
<li>如果在回应中不存在校验器（ETag或者Last-Modified头信息），缓存服务器会认为缺乏直接的更新度信息，内容将会被认为不可缓存。 </li>
<li>一个缓存的副本如果含有以下信息：内容将会被认为是足够新的 
<ul>
<li>含有完整的过期时间和寿命控制头信息，并且内容仍在保鲜期内； </li>
<li>浏览器已经使用过缓存副本，并且在一个会话中已经检查过内容的新鲜度； </li>
<li>缓存代理服务器近期内已经使用过缓存副本，并且内容的最后更新时间在上次使用期之前； </li>
<li>够新的副本将直接从缓存中送出，而不会向源服务器发送请求； </li>
</ul>
</li>
<li>如果缓存的副本已经太旧了，缓存服务器将向源服务器发出请求校验请求，用于确定是否可以继续使用当前拷贝继续服务； </li>
</ol>总之：<strong><em>新鲜度</em></strong>和<strong>校验</strong>是确定内容是否可用的最重要途径：
<p>&nbsp;</p>
<p>如果副本足够新，从缓存中提取就立刻能用了；<br />而经缓存器校验后发现副本的原件没有变化，系统也会避免将副本内容从源服务器整个重新传输一遍。<br /></p>
<h3>如何控制（控制不）缓存</h3>
<p>有很多工具可以帮助设计师和网站管理员调整缓存服务器对待网站的方式，这也许需要你亲自下手对服务器的配置进行一些调整，但绝对值得；了解如何使用这些工具请参考后面的实现章节；</p>
<h4>HTML meta标签和HTTP 头信息</h4>
<p>HTML的编写者会在文档的&lt;HEAD&gt;区域中加入描述文档的各种属性，这些META标签常常被用于标记文档不可以被缓存或者标记多长时间后过期；<br />META标签使用很简单：但是效率并不高，因为只有几种浏览器会遵循这个标记（那些真正会&ldquo;读懂&rdquo;HTML的浏览器），没有一种缓存代理服务器能遵循这个 规则（因为它们几乎完全不解析文档中HTML内容）；有事会在Web页面中增加：Pragma: no-cache这个META标记，如果要让页面保持刷新，这个标签其实完全没有必要。<br />如果你的网站托管在ISP机房中，并且机房可能不给你权限去控制HTTP的头信息（如：Expires和Cache-Control），大声控诉：这些机制对于你的工作来说是必须的；<br />另外一方面： HTTP头信息可以让你对浏览器和代理服务器如何处理你的副本进行更多的控制。他们在HTML代码中是看不见的，一般由Web服务器自动生成。但是，根据 你使用的服务，你可以在某种程度上进行控制。在下文中：你将看到一些有趣的HTTP头信息，和如何在你的站点上应用部署这些特性。<br /><br />HTTP头信息发送在HTML代码之前，只有被浏览器和一些中间缓存能看到，一个典型的HTTP 1.1协议返回的头信息看上去像这样：</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">HTTP/1.1 200 OK</span><br /><span style="font-style: italic;">Date: Fri, 30 Oct 1998 13:19:41 GMT</span><br /><span style="font-style: italic;">Server: Apache/1.3.3 (Unix)</span><br /><span style="font-style: italic;">Cache-Control: max-age=3600, must-revalidate</span><br /><span style="font-style: italic;">Expires: Fri, 30 Oct 1998 14:19:41 GMT</span><br /><span style="font-style: italic;">Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT</span><br /><span style="font-style: italic;">ETag: "3e86-410-3596fbbc"</span><br /><span style="font-style: italic;">Content-Length: 1040</span><br /><span style="font-style: italic;">Content-Type: text/html</span><br /></div>
<p><br />在头信息空一行后是HTML代码的输出，关于如何设置HTTP头信息请参考实现章节；</p>
<h4>Pragma HTTP头信息 (为什么它不起作用)</h4>
<p>很多人认为在HTTP头信息中设置了Pragma: no-cache后会让内容无法被缓存。但事实并非如此：HTTP的规范中，响应型头信息没有任何关于Pragma属性的说明，而讨论了的是请求型头信息 Pragma属性（头信息也由浏览器发送给服务器），虽然少数集中缓存服务器会遵循这个头信息，但大部分不会。用了Pragma也不起什么作用，要用就使 用下列头信息：</p>
<h4>使用Expires（过期时间）HTTP头信息来控制保鲜期</h4>
<p>Expires（过期时间） 属性是HTTP控制缓存的基本手段，这个属性告诉缓存器：相关副本在多长时间内是新鲜的。过了这个时间，缓存器就会向源服务器发送请求，检查文档是否被修改。几乎所有的缓存服务器都支持Expires（过期时间）属性；<br /><br />大部分Web服务器支持你用几种方式设置Expires属性；一般的：可以设计一个绝对时间间隔：基于客户最后查看副本的时间（最后访问时间）或者根据服务器上文档最后被修改的时间；</p>
<p>Expires头信息：对于设置静态图片文件（例如导航栏和图片按钮）可缓存特别有用；因为这些图片修改很少，你可以给它们设置一个特别长的过期时间，这会使你的网站对用户变得相应非常快；他们对于控制有规律改变的网页也很有用，例如：你每天早上6点更新新闻页，你可以设置副本的过期时间也是这个时间，这样缓存 服务器就知道什么时候去取一个更新版本，而不必让用户去按浏览器的&ldquo;刷新&rdquo;按钮。</p>
<p>过期时间头信息属性值<strong>只能</strong>是HTTP格式的日期时间，其他的都会被解析成当前时间&ldquo;之前&rdquo;，副本会过期，记住：HTTP的日期时间必须是格林威治时间（GMT），而不是本地时间。举例：</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">Expires: Fri, 30 Oct 1998 14:19:41 GMT</span><br /></div>
<p>所以使用过期时间属性一定要确认你的Web服务器时间设置正确，一个途径是通过网络时间同步协议（Network Time Protocol NTP），和你的系统管理员那里你可以了解更多细节。<br />虽然过期时间属性非常有用，但是它还是有些局限，首先：是牵扯到了日期，这样Web服务器的时间和缓存服务器的时间必须是同步的，如果有些不同步，要么是应该缓存的内容提前过期了，要么是过期结果没及时更新。<br />还有一个过期时间设置的问题也不容忽视：如果你设置的过期时间是一个固定的时间，如果你返回内容的时候又没有连带更新下次过期的时间，那么之后所有访问请求都会被发送给源Web服务器，反而增加了负载和响应时间；</p>
<h4>Cache-Control（缓存控制） HTTP头信息</h4>
<p>HTTP 1.1介绍了另外一组头信息属性：Cache-Control响应头信息，让网站的发布者可以更全面的控制他们的内容，并定位过期时间的限制。<br />有用的 Cache-Control响应头信息包括：</p>
<ul>
<li><strong>max-age</strong>=[秒] &mdash; 执行缓存被认为是最新的最长时间。类似于过期时间，这个参数是基于请求时间的相对时间间隔，而不是绝对过期时间，[秒]是一个数字，单位是秒：从请求时间开始到过期时间之间的秒数。 </li>
<li><strong>s-maxage</strong>=[秒] &mdash; 类似于max-age属性，除了他应用于共享（如：代理服务器）缓存 </li>
<li><strong>public </strong>&mdash; 标记认证内容也可以被缓存，一般来说： 经过HTTP认证才能访问的内容，输出是自动不可以缓存的； </li>
<li><strong>no-cache</strong> &mdash; 强制每次请求直接发送给源服务器，而不经过本地缓存版本的校验。这对于需要确认认证应用很有用（可以和public结合使用），或者严格要求使用最新数据的应用（不惜牺牲使用缓存的所有好处）； </li>
<li><strong>no-store</strong> &mdash; 强制缓存在任何情况下都不要保留任何副本 </li>
<li><strong>must-revalidate</strong> &mdash; 告诉缓存必须遵循所有你给予副本的新鲜度的，HTTP允许缓存在某些特定情况下返回过期数据，指定了这个属性，你高速缓存，你希望严格的遵循你的规则。 </li>
<li><strong>proxy-revalidate</strong> &mdash; 和 must-revalidate类似，除了他只对缓存代理服务器起作用 </li>
</ul>
<p>举例:</p>
<div style="margin-left: 40px; font-style: italic;">Cache-Control: max-age=3600, must-revalidate<br /></div>
<p>如果你计划试用Cache-Control属性，你应该看一下这篇HTTP文档，详见参考和深入阅读；<br /></p>
<h4>校验参数和校验</h4>
<p>在Web缓存如何工作： 我们说过：校验是当副本已经修改后，服务器和缓存之间的通讯机制；使用这个机制：缓存服务器可以避免副本实际上仍然足够新的情况下重复下载整个原件。<br />校验参数非常重要，如果1个不存在，并且没有任何信息说明保鲜期（Expires或Cache-Control）的情况下，缓存将不会存储任何副本；<br />最常见的校验参数是文档的最后修改时间，通过最后Last-Modified头信息可以，当一份缓存包含Last-Modified信息，他基于此信息，通过添加一个If-Modified-Since请求参数，向服务器查询：这个副本从上次查看后是否被修改了。<br />HTTP 1.1介绍了另外一个校验参数： ETag，服务器是服务器生成的唯一标识符ETag，每次副本的标签都会变化。由于服务器控制了ETag如何生成，缓存服务器可以通过If-None-Match请求的返回没变则当前副本和原件完全一致。<br />所有的缓存服务器都使用Last-Modified时间来确定副本是否够新，而ETag校验正变得越来越流行；<br />所有新一代的Web服务器都对静态内容（如：文件）自动生成ETag和Last-Modified头信息，而你不必做任何设置。但是，服务器对于动态内容（例如：CGI,ASP或数据库生成的网站）并不知道如何生成这些信息，参考一下编写利于缓存的脚本章节；<br /></p>
<h3>创建利于缓存网站的窍门</h3>
<p>除了使用新鲜度信息和校验，你还有很多方法使你的网站缓存友好。</p>
<ul>
<li><strong>保持URL稳定</strong>： 这是缓存的金科玉律，如果你给在不同的页面上，给不同用户或者从不同的站点上提供相同的内容，应该使用相同的URL，这是使你的网站缓存友好最简单，也是 最高效的方法。例如：如果你在页面上使用 "/index.html" 做为引用，那么就一直用这个地址； </li>
<li><strong>使用一个共用的库</strong>存放每页都引用的图片和其他页面元素； </li>
<li><strong>对于不经常改变的图片/页面启用缓存</strong>，并使用Cache-Control: max-age属性设置一个较长的过期时间； </li>
<li><strong>对于定期更新的内容</strong>设置一个缓存服务器可识别的max-age属性或过期时间； </li>
<li><strong>如果数据源（特别是下载文件）变更，修改名称</strong>，这样：你可以让其很长时间不过期，并且保证服务的是正确的版本；而链接到下载文件的页面是一个需要设置较短过期时间的页面。 </li>
<li><strong>万不得已不要改变文件</strong>，否则你会提供一个非常新的Last-Modified日期；例如：当你更新了网站，不要复制整个网站的所有文件，只上传你修改的文件。 </li>
<li><strong>只在必要的时候使用Cookie</strong>，cookie是非常难被缓存的，而且在大多数情况下是不必要的，如果使用cookie，控制在动态网页上； </li>
<li><strong>减少试用SSL</strong>，加密的页面不会被任何共享缓存服务器缓存，只在必要的时候使用，并且在SSL页面上减少图片的使用； </li>
<li><strong>使用可缓存性评估引擎</strong>，这对于你实践本文的很多概念都很有帮助； </li>
</ul>
<h3>编写利于缓存的脚本</h3>
<p>脚本缺省不会返回校验参数（返回Last-Modified或ETag头信息）或其他新鲜度信息（Expires或Cache-Control），有些动态脚本的确是动态内容（每次相应内容都不一样），但是更多（搜索引擎，数据库引擎网站）网站还是能从缓存友好中获益的。<br />一般说来，如果脚本生成的输出在未来一段时间（几分钟或者几天）都是可重复复制的，那么就是可缓存的。如果脚本输出内容只随URL变化而变化，也是可缓存的；但如果输出会根据cookie，认证信息或者其他外部条件变化，则还是不可缓存的。</p>
<ul>
<li>最利于缓存的脚本就是将内容改变时导出成静态文件，Web服务器可以将其当作另外一个网页并生成和试用校验参数，让一些都变得更简单，只需要写入文件即可，这样最后修改时间也有了； </li>
<li>另外一个让脚本可缓存的方法是对一段时间内能保持较新的内容设置一个相对寿命的头信息，虽然通过Expires头信息也可以实现，但更容易的是用Cache-Control: max-age属性，它会让首次请求后一段时间内缓存保持新鲜； </li>
<li>如果以上做法你都做不到，你可以让脚本生成一个校验属性，并对 If-Modified-Since 和/或If-None-Match请求作出反应，这些属性可以从解析HTTP头信息得到，并对符合条件的内容返回304 Not Modified（内容未改变），可惜的是，这种做法比不上前2种高效； </li>
</ul>
<p>其他窍门： </p>
<ul>
<li>尽量避免使用POST，除非万不得已，POST模式的返回内容不会被大部分缓存服务器保存，如果你发送内容通过URL和查询（通过GET模式）的内容可以缓存下来供以后使用； </li>
<li>不要在URL中加入针对每个用户的识别信息：除非内容是针对每个用户不同的； </li>
<li>不要统计一个用户来自一个地址的所有请求，因为缓存常常是一起工作的； </li>
<li>生成并返回Content-Length头信息，如果方便的话，这个属性让你的脚本在可持续链接模式时：客户端可以通过一个TCP/IP链接同时请求多个副本，而不是为每次请求单独建立链接，这样你的网站相应会快很多； </li>
</ul>
具体定义请参考实现章节。
<h3>常见问题解答</h3>
<h4>让网站变得可缓存的要点是什么？</h4>
<p>好的策略是确定那些内容最热门，大量的复制（特别是图片）并针对这些内容先部署缓存。</p>
<h4>如何让页面通过缓存达到最快相应？</h4>
<p>缓存最好的副本是那些可以长时间保持新鲜的内容；基于校验虽然有助于加快相应，但是它不得不和源服务器联系一次去检查内容是否够新，如果缓存服务器上就知道内容是新的，内容就可以直接相应返回了。</p>
<h4>我理解缓存是好的，但是我不得不统计多少人访问了我的网站！</h4>
<p>如果你必须知道每次页面访问的，选择【一】个页面上的小元素，或者页面本身，通过适当的头信息让其不可缓存，例如： 可以在每个页面上部署一个1x1像素的透明图片。Referer头信息会有包含这个图片的每个页面信息；<br />明确一点：这个并不会给你一个关于你用户精确度很高的统计，而且这对互联网和你的用户这都不太好，消耗了额外的带宽，强迫用户去访问无法缓存的内容。了解更多信息，参考访问统计资料。</p>
<h4>我如何能看到HTTP头信息的内容？</h4>
<p>很多浏览器在页面属性或类似界面中可以让你看到Expires 和Last-Modified信息；如果有的话：你会找到页面信息的菜单和页面相关的文件（如图片），并且包含他们的详细信息；<br />看到完整的头信息，你可以用telnet手工连接到Web服务器；<br />为此：你可能需要用一个字段指定端口（缺省是80），或者链接到<a href="http://www.5a520.cn/">www.5a520.cn:80</a> 或者 <a href="http://www.todou.cn/">www.todou.cn</a> &nbsp;80(注意是空格)，更多设置请参考一下telnet客户端的文档；<br />打开网站链接：请求一个查看链接，如果你想看到http://www.example.com/foo.html 连接到www.example.com的80端口后，键入：</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">GET /foo.html HTTP/1.1 [回车]</span><br /><span style="font-style: italic;">GET /foo.html HTTP/1.1 [return]</span><br /><span style="font-style: italic;">Host: <a href="http://www.5a520.cn/">www.5a520.cn</a>[回车][回车] </span><br /><span style="font-style: italic;">Host: <a href="http://www.todou.cn/">www.todou.cn [return][return</a>] </span><br /></div>
<p>在[回车]处按键盘的回车键；在最后，要按2次回车，然后，就会输出头信息及完整页面，如果只想看头信息，将GET换成HEAD。<br /></p>
<h4>我的页面是密码保护的，代理缓存服务器如何处理他们？</h4>
<p>缺省的，网页被HTTP认证保护的都是私密内容，它们不会被任何共享缓存保留。但是，你可以通过设置Cache-Control: public让认证页面可缓存，HTTP 1.1标准兼容的缓存服务器会认出它们可缓存。<br />如果你认为这些可缓存的页面，但是需要每个用户认证后才能看，可以组合使用Cache-Control: public和no-cache头信息，高速缓存必须在提供副本之前，将将新客户的认证信息提交给源服务器。设置就是这样：</p>
<blockquote><em>Cache-Control: public, no-cache</em><br /></blockquote>
<p>无论如何：这是减少认证请求的最好方法，例如： 你的图片是不机密的，将它们部署在另外一个目录，并对此配置服务器不强制认证。这样，那些图片会缺省都缓存。</p>
<h4>我们是否要担心用户通过cache访问我的站点？</h4>
<p>代理服务器上SSL页面不会被缓存（不推荐被缓存），所以你不必为此担心。但是，由于缓存保存了非SSL请求和从他们抓取的URL，你要意识到没有安全保护的网站，可能被不道德的管理员可能搜集用户隐私，特别是通过URL。<br />实际上，位于服务器和客户端之间的管理员可以搜集这类信息。特别是通过CGI脚本在通过URL传递用户名和密码的时候会有很大问题；这对泄露用户名和密码是一个很大的漏洞；<br />如果你初步懂得互联网的安全机制，你不会对缓存服务器有任何。</p>
<h4>我在寻找一个包含在Web发布系统解决方案，那些是比较有缓存意识的系统？</h4>
<p>这很难说，一般说来系统越复杂越难缓存。最差就是全动态发布并不提供校验参数；你无发缓存任何内容。可以向系统提供商的技术人员了解一下，并参考后面的实现说明。</p>
<h4>我的图片设置了1个月后过期，但是我现在需要现在更新。</h4>
<p>过期时间是绕不过去的，除非缓存（浏览器或者代理服务器）空间不足才会删除副本，缓存副本在过期之间会被一直使用。<br />最好的办法是改变它们的链接，这样，新的副本将会从源服务器上重新下载。记住：引用它们的页面本身也会被缓存。因此，使用静态图片和类似内容是很容易缓存的，而引用他们的HTML页面则要保持非常更新；<br />如果你希望对指定的缓存服务器重新载入一个副本，你可以强制使用&ldquo;刷新&rdquo;（在FireFox中在reload的时候按住shift键：就会有前面提到恶Pragma: no-cache头信息发出）。或者你可以让缓存的管理员从他们的界面中删除相应内容；</p>
<h4>我运行一个Web托管服务，如何让我的用户发布缓存友好的网页？</h4>
<p>如果你使用apahe，可以考虑允许他们使用.htaccess文件并提供相应的文档；<br />另外一方面： 你也可以考虑在各种虚拟主机上建立各种缓存策略。例如： 你可以设置一个目录 /cache-1m 专门用于存放访问1个月的访问，另外一个 /no-cache目录则被用提供不可存储副本的服务。<br />无论如何：对于大量用户访问还是应该用缓存。对于大网站，这方面的节约很明显（带宽和服务器负载）；</p>
<h4>我标记了一些网页是可缓存的，但是浏览器仍然每次发送请求给服务。如何强制他们保存副本？</h4>
<p>缓存服务器并不会总保存副本并重用副本；他们只是在特定情况下会不保存并使用副本。所有的缓存服务器都回基于文件的大小，类型（例如：图片 页面），或者服务器空间的剩余来确定如何缓存。你的页面相比更热门或者更大的文件相比，并不值得缓存。<br />所以有些缓存服务器允许管理员根据文件类型确定缓存副本的优先级，允许某些副本被永久缓存并长期有效；</p>
<h3>缓存机制的实现 - Web服务器端配置</h3>
<p>一般说来，应该选择最新版本的Web服务器程序来部署。不仅因为它们包含更多利于缓存的功能，新版本往往在性能和安全性方面都有很多的改善。</p>
<h4>Apache HTTP服务器</h4>
<p>Apache有些可选的模块来包含这些头信息： 包括Expires和Cache-Control。 这些模块在1.2版本以上都支持；<br />这些模块需要和apache一起编译；虽然他们已经包含在发布版本中，但缺省并没有启用。为了确定相应模块已经被启用：找到httpd程序并运行httpd -l 它会列出可用的模块，我们需要用的模块是mod_expires和mod_headers</p>
<ul>
<li>如果这些模块不可用，你需要联系管理员，重新编译并包含这些模块。这些模块有时候通过配置文件中把注释掉的配置启用，或者在编译的时候增加-enable -module=expires和-enable-module=headers选项（在apache 1.3和以上版本）。 参考Apache发布版中的INSTALL文件； </li>
</ul>
<p>Apache一旦启用了相应的模块，你就可以在.htaccess文件或者在服务器的access.conf文件中通过mod_expires设置副本什 么时候过期。你可设置过期从访问时间或文件修改时间开始计算，并且应用到某种文件类型上或缺省设置，参考<a href="http://httpd.apache.org/docs/1.3/mod/mod_expires.html">模块的文档</a>获得更多信息，或者遇到问题的时候向你身边的apache专家讨教。<br />应用Cache-Control头信息，你需要使用mod_headers,它将允许你设置任意的HTTP头信息，参考<a href="http://httpd.apache.org/docs/1.3/mod/mod_headers.html">mod_headers的文档</a>可以获得更多资料；<br />这里有个例子说明如何使用头信息：</p>
<ul>
<li>.htaccess文件允许web发布者使用命令只在配置文件中用到的命令。他影响到所在目录及其子目录；问一下你的服务器管理员确认这个功能是否启用了。 <br /></li>
</ul>
<div style="margin-left: 40px;"><span style="font-style: italic;">### 启用 mod_expires</span><br /><span style="font-style: italic;">ExpiresActive On</span><br /><span style="font-style: italic;">### 设置 .gif 在被访问过后1个月过期。</span><br /><span style="font-style: italic;">ExpiresByType image/gif A2592000</span><br /><span style="font-style: italic;">### 其他文件设置为最后修改时间1天后过期</span><br /><span style="font-style: italic;">### (用了另外的语法)</span><br /><span style="font-style: italic;">ExpiresDefault "modification plus 1 day"</span><br /><span style="font-style: italic;">### 在index.html文件应用 Cache-Control头属性</span><br /><span style="font-style: italic;">&lt;Files index.html&gt;</span><br /><span style="font-style: italic;">Header append Cache-Control "public, must-revalidate"</span><br /><span style="font-style: italic;">&lt;/Files&gt;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></div>
<ul>
<li>注意： 在适当情况下mod_expires会自动计算并插入Cache-Control:max-age 头信息 </li>
</ul>
<p>Apache 2.0的配置和1.3类似，更多信息可以参考2.0的<a href="http://httpd.apache.org/docs/2.2/mod/mod_expires.html">mod_expires</a>和<a href="http://httpd.apache.org/docs/2.2/mod/mod_headers.html">mod_headers文档</a>；<br /></p>
<h4>Microsoft IIS服务器</h4>
<p>Microsoft的IIS可以非常容易的设置头信息，注意：这只针对IIS 4.0服务器，并且只能在NT服务器上运行。<br />为网站的一个区域设置头信息，先要到管理员工具界面中，然后设置属性。选择HTTP Header选单，你会看到2个有趣的区域：启用内容过期和定制HTTP头信息。头一个设置会自动配置，第二个可以用于设置Cache-Control头信息；<br />设置asp页面的头信息可以参考后面的ASP章节，也可以通过ISAPI模块设置头信息，细节请参考MSDN。<br /></p>
<h4>Netscape/iPlanet企业服务器</h4>
<p>3.6版本以后，Netscape/iPlanet已经不能设置Expires头信息了，他从3.0版本开始支持HTTP 1.1的功能。这意味着HTTP 1.1的缓存（代理服务器/浏览器）优势都可以通过你对Cache-Control设置来获得。<br />使用Cache-Control头信息，在管理服务器上选择内容管理|缓存设置目录。然后：使用资源选择器，选择你希望设置头信息的目录。设置完头信息后，点击&ldquo;OK&rdquo;。更多信息请参考<a href="http://developer.netscape.com/docs/manuals/enterprise/admnunix/content.htm#1006282">Netscape/iPlanet企业服务器的手册</a>。<br /></p>
<h4>缓存机制的实现：服务器端脚本</h4>
<p>需要注意的一点是：也许服务器设置HTTP头信息比脚本语言更容易，但是两者你都应该使用。<br />因为服务器端的脚本主要是为了动态内容，他本身不产生可缓存的文件页面，即使内容实际是可以缓存的。如果你的内容经常改变，但是不是每次页面请求都改变， 考虑设置一个Cache-Control: max-age头信息；大部分用户会在短时间内多次访问同一页面。例如： 用户点击&ldquo;后退&rdquo;按钮，即使没有新内容，他们仍然要再次从服务器下载内容查看。<br /></p>
<h4>CGI程序</h4>
<p>CGI脚本是生成内容最流行的方式之一，你可以很容易在发送内容之前的扩展HTTP头信息；大部分CGI实现都需要你写 Content-Type头信息，例如这个Perl脚本：</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">#!/usr/bin/perl</span><br /><span style="font-style: italic;">print "Content-type: text/html\n";</span><br /><span style="font-style: italic;">print "Expires: Thu, 29 Oct 1998 17:04:19 GMT\n";</span><br /><span style="font-style: italic;">print "\n";</span><br /><span style="font-style: italic;">### 后面是内容体...</span><br /></div>
<p>由于都是文本，你可以很容易通过内置函数生成Expires和其他日期相关的头信息。如果你使用Cache-Control: max-age;会更简单；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">print "Cache-Control: max-age=600\n";</span><br /></div>
<p>这样脚本可以在被请求后缓存10分钟；这样用户如果按&ldquo;后退&rdquo;按钮，他们不会重新提交请求；<br />CGI的规范同时也允许客户端发送头信息，每个头信息都有一个&lsquo;HTTP_&rsquo;的前缀；这样如果一个客户端发送一个If-Modified-Since请求，就是这样的：</p>
<div style="margin-left: 40px; font-style: italic;">HTTP_IF_MODIFIED_SINCE = Fri, 30 Oct 1998 14:19:41 GMT <br /></div>
<p><br />参考一下<a href="http://www.mnot.net/cgi_buffer/">cgi_buffer</a>库，一个自动处理ETag的生成和校验的库，生成Content-Length属性和对内容进行gzip压缩。在Python脚本中也只需加入一行；<br /></p>
<h4>服务器端包含 Server Side Includes</h4>
<p>SSI（经常使用.shtml扩展名）是网站发布者最早可以生成动态内容的方案。通过在页面中设置特别的标记，也成为一种嵌入HTML的脚本；<br />大部分SSI的实现无法设置校验器，于是无法缓存。但是Apache可以通过对特定文件的组执行权限设置实现允许用户设置那种SSI可以被缓存；结合XbitHack调整整个目录。更多文档请参考<a href="http://httpd.apache.org/docs/1.3/mod/mod_include.html">mod_include文档</a>。</p>
<h4>PHP</h4>
<p>PHP是一个内建在web服务器中的服务器端脚本语言，当做为HTML嵌入式脚本，很像SSI，但是有更多的选项，PHP可以在各种Web服务器上设置为CGI模式运行，或者做为Apache的模块；<br />缺省PHP生成副本没有设置校验器，于是也无法缓存，但是开发者可以通过Header()函数来生成HTTP的头信息；<br />例如：以下代码会生成一个Cache-Control头信息，并设置为3天以后过期的Expires头信息；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">&lt;?php</span><br /><span style="font-style: italic;">&nbsp;Header("Cache-Control: must-revalidate");</span><br /><br /><span style="font-style: italic;">&nbsp;$offset = 60 * 60 * 24 * 3;</span><br /><span style="font-style: italic;">&nbsp;$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";</span><br /><span style="font-style: italic;">&nbsp;Header($ExpStr);</span><br /><span style="font-style: italic;">?&gt;</span><br /></div>
<p>记住： Header()的输出必须先于所有其他HTML的输出；<br />正如你看到的：你可以手工创建HTTP日期；PHP没有为你提供专门的函数（新版本已经让这个越来越容易了，请参考PHP的<a href="http://php.net/date">日期相关函数文档</a>），当然，最简单的还是设置Cache-Control: max-age头信息，而且对于大部分情况都比较适用；<br />更多信息，请参考<a href="http://www.php.net/manual/function.header.php3">header相关的文档</a>；<br />也请参考一下<a href="http://www.mnot.net/cgi_buffer/">cgi_buffer</a>库，自动处理ETag的生成和校验，Content-Length生成和内容的gzip压缩，PHP脚本只需包含1行代码；</p>
<h4>Cold Fusion</h4>
<p><a href="http://www.adobe.com/products/coldfusion/">Cold Fusion</a>是Macromedia的商业服务器端脚本引擎，并且支持多种Windows平台，Linux平台和多种Unix平台。Cold Fusion通过CFHEADER标记设置HTTP头信息相对容易。可惜的是：以下的Expires头信息的设置有些容易误导；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">&lt;CFHEADER NAME="Expires" VALUE="#Now()#"&gt;</span><br /></div>
<p>它并不像你想像的那样工作，因为时间（本例中为请求发起的时间）并不会被转换成一个符合HTTP时间，而且打印出副本的Cold fusion的日期/时间对象，大部分客户端会忽略或者将其转换成1970年1月1日。<br />但是：Cold Fusion另外提供了一套日期格式化函数， GetHttpTimeSTring. 结合DateAdd函数，就很容易设置过期时间了，这里我们设置一个Header声明副本在1个月以后过期；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">&lt;cfheader name="Expires" value="#GetHttpTimeString(DateAdd('m', 1, Now()))#"&gt;</span><br /></div>
<p>你也可以使用CFHEADER标签来设置Cache-Control: max-age等其他头信息；<br />记住：Web服务器也会将头信息设置转给Cold Fusion(做为CGI运行的时候)，检查你的服务器设置并确定你是否可以利用服务器设置代替Cold Fusion。 <br /></p>
<h4>ASP和ASP.NET</h4>
<p>在asp中设置HTTP头信息是：确认Response方法先于HTML内容输出前被调用，或者使用 Response.Buffer暂存输出；同样的：注意某些版本的IIS缺省设置会输出Cache-Control: private 头信息，必须声明成public才能被共享缓存服务器缓存。<br />IIS的ASP和其他web服务器都允许你设置HTTP头信息，例如： 设置过期时间，你可以设置Response对象的属性；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">&lt;% Response.Expires=1440 %&gt;</span><br /></div>
<p>设置请求的副本在输出的指定分钟后过期，类似的：也可以设置绝对的过期时间（确认你的HTTP日期格式正确）</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">&lt;% Response.ExpiresAbsolute=#May 31,1996 13:30:15 GMT# %&gt;</span><br /></div>
<p>Cache-Control头信息可以这样设置：</p>
<div style="margin-left: 40px; font-style: italic;">&lt;% Response.CacheControl="public" %&gt;<br /></div>
<p>在ASP.NET中，Response.Expires 已经不推荐使用了，正确的方法是通过Response.Cache设置Cache相关的头信息；</p>
<div style="margin-left: 40px;"><span style="font-style: italic;">Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ;</span><br /><span style="font-style: italic;">Response.Cache.SetCacheability ( HttpCacheability.Public ) ;</span><br /></div>
<p>参考<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspoutputcache.asp">MSDN文档</a>可以找到更多相关新年系；<br /></p>
<h3>参考文档和深入阅读</h3>
<h4><a href="http://www.ietf.org/rfc/rfc2616.txt" target="_blank">HTTP 1.1 规范定义</a></h4>
<p>HTTP 1.1的规范有大量的扩展用于页面缓存，以及权威的接口实现指南，参考章节：13, 14.9, 14.21, 以及 14.25.<br /></p>
<h4><a href="http://www.web-caching.com/" target="_blank">Web-Caching.com</a></h4>
<p>非常精彩的介绍缓存相关概念，并介绍其他在线资源。<br /><a href="http://www.goldmark.org/netrants/webstats/" target="_blank"><br /></a></p>
<h4><a href="http://www.goldmark.org/netrants/webstats/" target="_blank">关于非连续性访问统计</a></h4>
<p>Jeff Goldberg内容丰富的演说告诉你为什么不应该过度依赖访问统计和计数器；<br /></p>
<h4><a href="http://www.mnot.net/cacheability/">可缓存性检测引擎</a></h4>
<p>可缓存的引擎设计，检测网页并确定其如何与Web缓存服务器交互， 这个引擎配合这篇指南是一个很好的调试工具，<br /></p>
<h4><a href="http://www.mnot.net/cgi_buffer/">cgi_buffer库</a></h4>
<p>包含库：用于CGI模式运行的Perl/Python/PHP脚本，自动处理ETag生成/校验，Content-Length生成和内容压缩。正确地。 Python版本也被用作其他大量的CGI脚本。<br /></p>
<h3>关于本文档</h3>
<p>本文版权属于Mark Nottingham &lt;<a href="mailto:mnot@pobox.com">mnot@pobox.com</a>&gt;，本作品遵循<a href="http://creativecommons.org/licenses/by-nc-nd/2.0/deed.zh">创作共用版权</a>。<br />如果你镜像本文，请通过以上邮件告知，这样你可以在更新时被通知；<br />所有的商标属于其所有人。<br />虽然作者确信内容在发布时的正确性，但不保证其应用或引申应用的正确性，如有误传，错误或其他需要澄清的问题请尽快告知作者；<br />本文最新版本可以从 <a href="http://www.mnot.net/cache_docs/">http://www.mnot.net/cache_docs/</a> 获得；<br />翻译版本包括： <a href="http://www.jakpsatweb.cz/clanky/caching-tutorial-czech-translation.html">捷克语版</a>，<a href="http://www.mnot.net/cache_docs/index.fr.html">法语版</a>和<a href="http://www.chedong.com/tech/cache_docs.html">中文版</a>。<br />版本： 1.81 - 2007年3月16日</p>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/213084#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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jul 2008 14:08:45 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/213084</link>
        <guid>http://hintcnuie.javaeye.com/blog/213084</guid>
      </item>
      <item>
        <title>李彦宏在北大2008本科生毕业典礼上的发言(图)</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/212646" style="color:red;">http://hintcnuie.javaeye.com/blog/212646</a>&nbsp;
          发表时间: 2008年07月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>尊敬的闵书记、许校长，各位老师，各位家长，亲爱的学弟学妹们，大家上午好。 <br /><br />今天，站在各位同学毕业典礼的讲台上，我最大的感受就是觉得非常的荣幸，在各位生命中最值得纪念的时刻与你们在一起，让我百感交集。我仿佛找回了十七年前，坐在你们中间，对这个再熟悉不过的校园感到万分的留恋，也对即将展开的新的生活有期待、有迷茫甚至有所畏惧。　　<br /><br />说实话，我今天除了荣幸之外，还有一些紧张。因为我知道，在座的不仅有我十分尊敬的师长，更多的是未来中国最有影响力的一群人。你们中一定会有未来中国最杰出的科学家、最成功的企业家、最优秀的政治家、外交家。 <br /><br />如果我这个曾经住在43楼522的北大男生今天和大家交流的内容，能够为各位即将铺展开的未来有些许帮助的话，那我也会觉得，这是经历了2005年百度在纳斯达克的辉煌上市后，我所经历的又一个光荣时刻。 </p>
<p>今天回忆十多年前，我走入社会的感觉，那是让视野顿时豁然开朗的一步，走出校园后看到的是一个充满机会、日新月异的新天地。大家今天所面对的中国与世界，与十年前我所见到的华尔街和硅谷，当然会有很大的不同。但以我在美国八年、回到中国八年多的经历，我更感受到今天，社会经济文化生活各个方面都充满了活力，你们面对的是更广阔的天地，一定将大有所为。 <br /><br />今天我想给大家分享一些我的经历和对生活的感悟。 <br /><br /><strong>第一，是关于选择的故事 </strong><br /><br />进北大前我就非常喜欢计算机，我相信未来的计算机肯定会被应用广泛，而单纯的学计算机恐怕不如把计算机和某项应用结合起来有前途，于是我选择了北大的信息管理系，而不是计算机系。 <br /><br />我有个姐姐先我五年考上了北大，她告诉我北大的学生出国都很容易，她告诉我外面的世界很精彩。上了北大之后，我却发现我的情报学专业出国并不容易，而最先进的计算机技术那时候在美国。我被迫开始思考自己的下一步，并通过不断参与各种活动来丰富自己的视野。 <br /><br />李彦宏说，自己的火炬手名额是联想推荐的。据说李彦宏陈绍鹏关系不错。 <br /><br />我去学了不少计算机系的课，我翻阅了很多美国有关情报学的论文，希望能够在国际学术期刊上找到自己的机会，我作为那时唯一的理科生参加了学校的五四辩论赛，我听了各种各样的讲座：气功、哲学、电影，我参加了合唱团，还在国庆的时候到天安门广场去跳集体舞，我尽情的享受着北大带给我的各种机会，我接触到了各种各样的人，每个人都有他们自己的思路，每个人都不一样，每个人都很精彩。这让我逐渐形成了不轻信，不跟风的思维方式。对于我未来人生道路的选择，北大四年让我具备了独立思考的能力。 <br /><br />我在美国读计算机的时候，本来是读博士的，后来选择了放弃。原因是发现我更希望我做的东西能够被很多很多人使用，而不喜欢去研究一个别人已经研究了10年的命题。 <br /><br />1997年我离开自己奋斗了三年多的华尔街，前往当时在硅谷很著名的搜索引擎公司Infoseek。在硅谷，我亲见了当时最成功的搜索技术公司如何在股市上呼风唤雨，见识了每天支持上千万流量的大型工业界信息系统是怎样工作运转，我也见证了Infoseek后来的每况愈下和惨淡经营。但最重要的是，在Infoseek，我找到了我一生的兴趣所在&mdash;互联网搜索引擎。那时，是北大所学的信息检索方面的理论，让我比任何计算机系科班出身的工程师都更能够理解普通用户习惯于怎样的信息获取方式。我意识到搜索能让每个人与所需信息的距离只有鼠标的点击一下那么远，这种感觉是那么的美妙。从那以后，我从来没有离开搜索引擎超过24小时，不是因为我是工作狂，而是因为我喜欢。 <br /><br />百度公司走过了8年的历程，今天已经成为一个市值超过100亿美元的公司，为越来越多的人提供服务。我最大的心得就是要选择做自己喜欢做的事情，我们需要从自己真正的心里面去作选择，并不是你认为社会期望你这样做，父母期望你这样做，朋友期望你这样做。只有这样，你才会越工作越开心，在遇到困难遇到挫折的时候，不会被沮丧击败，而全身心的去享受整个过程。<br />&nbsp;<br /><strong>第二，是关于专注的认识 </strong><br /><br />我一生有两个最大的幸运，一是找到我的太太，二是从事一份自己喜欢的工作。但太太与工作唯一的不同就是：太太只有一个，而工作每时每刻都充满了诱惑。很多人都会专注于一个妻子，但很多人都会喜欢上多个不同的工作。 <br /><br />在百度上市之前，百度只做一件事情就是中文搜索。在创业初期，搜索在美国硅谷并不是炙手可热的概念，当时更热的是门户，是电子商务，以及后来在中国火起来的无线、网游等等。百度在招第一批职员的时候，碰到一位我特别希望他能加盟，他技术很好，可惜他对我说如果我们不做e-Commerce他就不来了.。2001年，曾经有一位百度的工程师找到我，很认真地说他想做网上购物，结果被我拒绝了，并为此离开了百度。百度上市后，也有一些共事多年的老同事先后离开了百度去尝试更多的业务。 <br /><br />很多时候，我感到百度能一直坚持做搜索是因为我对专注有宗教一般的信仰。普通人很难想象对于一个有2亿的用户的公司，每天要面对多少诱惑。百度可以做一百件事，最后我们只选择了一件，并一做就是8年，而且还会再做下去。 <br /><br />人一生中可以完成的事情是有限的。只有专注才能让自己变得足够优秀。所以说：&ldquo;有所不为，才能有所为&rdquo;。 <br /><br /><strong>第三，是关于视野的感悟 </strong><br /><br />回头望望自己走过的路，我会发现，这个世界的广阔是自己很难想象的。很多当时觉得非常大的困难，现在看来不过是一些小事，很多当时感觉到很棘手的事，现在也只是茶余饭后的话题罢了。 <br /><br />百度在2000年成立时，并不直接为网民提供搜索服务，我们只为门户网站输出搜索引擎技术，而当时只有门户需要搜索服务。2001年夏天，我做了这样一个决定，从一个藏在门户网站后面技术服务商，转型做一个拥有自己品牌的独立搜索引擎。这是百度发展历程中唯一的一次转型，会得罪几乎所有的客户，所以当时遭到很多投资者反对。但当我把视线投向若干年以后时，我不得不坚持自己的观点。大家知道，后来我说服了投资者，所以才有了大家今天看到的百度。 <br /><br />百度从后台走向了前台，加上我们的专注与努力，今天运营着东半球最大的网站。<br />&nbsp;<br />事实上，从创立百度的第一天，我的理想就是&ldquo;让人们最便捷的获取信息&rdquo;。这个理想不局限于中文，不局限于互联网。做为一名北大信息管理系的学生，我很幸运在前互联网时代，在大学时就理解了信息与人类的关系和重要性。所以，百度从第一天起，就胸怀远大理想：我们希望为所有中国人，以至亚洲，以至全世界的人类，寻求人与信息之间最短的距离，寻求人与信息的相亲相爱。 <br /><br />所以说：视野有多远，世界就有多大。 <br /><br />最后，我在这里衷心祝贺你们顺利完成在北京大学的学习，祝愿你们未来的道路越走越宽广，世界在你手中。也让我们一起祝福我们的母校传承历史、继往开来、再攀高峰。 <br />谢谢大家！<!--
这篇新闻中是否有争论或者观点交锋呢？如果希望读者参与，请点击<a href="http://pkzone.csdn.net/AdminManage/Editor_Apply.aspx">这里</a>，创建一个观点PK
--></p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/212646#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 08 Jul 2008 11:02:52 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/212646</link>
        <guid>http://hintcnuie.javaeye.com/blog/212646</guid>
      </item>
      <item>
        <title>Quartz 文章集锦</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/211225" style="color:red;">http://hintcnuie.javaeye.com/blog/211225</a>&nbsp;
          发表时间: 2008年07月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Quartz简介</p>
<p><a href="http://www.onjava.com/pub/a/onjava/2004/03/10/quartz.html">http://www.onjava.com/pub/a/onjava/2004/03/10/quartz.html</a></p>
<p><a href="http://www.onjava.com/pub/a/onjava/2005/09/28/what-is-quartz.html">http://www.onjava.com/pub/a/onjava/2005/09/28/what-is-quartz.html</a></p>
<p>Quartz配置</p>
<p><a href="http://www.opensymphony.com/quartz/wikidocs/Configuration.html">http://www.opensymphony.com/quartz/wikidocs/Configuration.html</a></p>
<p>Quartz代码cookbook：</p>
<p><a href="http://www.opensymphony.com/quartz/wikidocs/Cookbook.html">http://www.opensymphony.com/quartz/wikidocs/Cookbook.html</a></p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/211225#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jul 2008 18:21:28 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/211225</link>
        <guid>http://hintcnuie.javaeye.com/blog/211225</guid>
      </item>
      <item>
        <title> OutOfMemoryException when running mvn</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/208724" style="color:red;">http://hintcnuie.javaeye.com/blog/208724</a>&nbsp;
          发表时间: 2008年06月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h1><a name="MavenTipsAndTricks-MAVENOPTS"></a>MAVEN_OPTS</h1>
<p>The MAVEN_OPTS environment variable defines options for the JVM that executes Maven.</p>
<p>Set it according to your platform, i.e. <tt>export MAVEN_OPTS=...</tt> on unixish systems or <tt>set MAVEN_OPTS=...</tt> on Windows.</p>
<h2><a name="MavenTipsAndTricks-IncreaseJVMmemoryifneeded"></a>Increase JVM memory if needed</h2>
<p>If getting an OutOfMemoryException when running mvn, try setting</p>
<div class="preformatted">
<div class="preformattedContent">
<pre>MAVEN_OPTS="-Xmx256M"
</pre>
</div>
</div>
<p>to allocate 256MB of RAM to Maven</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/208724#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 27 Jun 2008 16:09:28 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/208724</link>
        <guid>http://hintcnuie.javaeye.com/blog/208724</guid>
      </item>
      <item>
        <title>关于Facebook app有意思的数据</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/208316" style="color:red;">http://hintcnuie.javaeye.com/blog/208316</a>&nbsp;
          发表时间: 2008年06月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>上周xiaonei推出开放平台后，相比较早之前宣布开放的myspace.cn，51，xiaonei在业界的影响力还是有不少震动，谁让他们的用户很值钱呢,同时有不少国内开发者都自发组织在上海、北京聚会。从与这些开发者的沟通交流，以及之前对app的一些研究，整理一下关于Facebook app有意思的数据：</p>
<p>　　1、Facebook插件中紅的，都是在『三天內』做出來的</p>
<p>　　2、不要问app的盈利模式是什么，因为大家都在赚钱</p>
<p>　　3、前10名的app，基本都是专业的公司在制作，如slide、rockyou、Social Gaming Network等</p>
<p>　　4、Facebook上50名以后，200名之前的app多数都是台湾、香港的小团队在制作</p>
<p>　　5、Facebook宣布开放平台后，ilike在两周内获得200万用户(当时FB也就2000多万用户)，成为推广F8最好的公关</p>
<p>　　6、where i have been 一个展示用户曾经去过哪、想去哪、现在在哪的应用。两个月后，被一家旅游公司收购。</p>
<p>　　7、frined for sales是一个好应用，抄一个，火一个。该应用解决了人性的三个需求：展示财富--〉应用财富--〉赚取财富。这其中的点又是奴隶一词，来源于生活。</p>
<p>　　8、开心网的新应用争车位也将是一个好应用。你想开好车--〉贴条赚钱--〉保持高频率上线观察好友行踪</p>
<p>　　9、Facebook不是一家社交网站，它的定位是做一个影响所有网站的平台，它所有的功能包括自己开发都是基于app应用，如note、photo、video等(当然除了关系链与feed)</p>
<p>　　10、QQ是最像&ldquo;中国Facebook&rdquo;的平台</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/208316#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/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, 26 Jun 2008 18:12:19 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/208316</link>
        <guid>http://hintcnuie.javaeye.com/blog/208316</guid>
      </item>
      <item>
        <title>把一个java web应用包装成桌面应用的简单做法</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/207031" style="color:red;">http://hintcnuie.javaeye.com/blog/207031</a>&nbsp;
          发表时间: 2008年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <ul>
<li>昨天玩h2的时候想起来的， 这年头把在线应用报装成桌面应用是越来越流行了，几年前做过类似的事情，简单介绍一下。<br /><br /><strong><span style="font-size: small;">1. 选择一个嵌入的web 服务器和 数据库</span></strong><br />web服务器我选择的是jetty，虽然tomcat也有类似的嵌入版本，但是体积和性能都还是有点差距。 如果你的应用使用了大量的ajax效果，建议选择6的版本，对并发支持更好。<br />数据库方面我原来用的是hsql，现在可以选择h2. 两者的sql 兼容性都比较好，扩展功能也比较强。如果原来的应用在mysql上进行开发，则基本不用做修改， h2现在有mysql兼容模式，如果原来应用使用的是db2或者oracle，则你可能需要把一些函数和过程改用java实现，h2提供了这方面的支持。 数据问题方面也不用担心，h2目前比较成熟了，而且最大可以提供256g的文件支持。我做过一些测试，关机，死机，都还可以恢复的比较好。<br /><br />h2的一个特性是支持只读数据库，所以你也可以选择将数据库备份成zip文件以后，以光盘的方式发布应用，很适合做大量分发的演示光盘，比较酷吧。<br /><br />jetty+h2的组合占用系统资源非常少，而且速度极快， 在我成功移植以后，我的一个同事吃惊的发现速度要比原来的online版本提高了很多。一般用户几乎感觉不到在线操作的那种停顿。<br /><br />java6自带的那个java数据库就不要考虑了，速度慢，体积大，兼容问题多多。<br /><br /><span style="font-size: small;"><strong>2. 使用JDIC或者java6提供的一些native特性和桌面进行整合</strong></span><br /><br />主要使用诸如系统托盘来提供一些控制操作和辅助功能， 打开浏览器或者将浏览器嵌入到swing应用等等。我的做法是将浏览器嵌入到swing应用中，并做了一些小手脚，保证用户不能使用浏览器直接访问，这样看起来更安全，更象桌面应用。<br /><br />java6在这些方面有比较好的支持，6以前的版本可以使用JDIC，反正都是一回事。 另外可以选择jgoodie之类的扩展包，让你的桌面看起来更骚包一些。<br /><br />当然，使用6的话启动要快一些，特别是重复启动的时候，java6还有的一个特性是splash的支持， 这样在启动的时候可以自然一些。<br /><br /><span style="font-size: small;"><strong>3.&nbsp; 对配置文件进行适当精简，使用混淆工具编译关键包</strong></span><br /><br />发布到桌面以后就意味着受攻击指数增加了，增加适当的防范也是必要的，此处如果不怕麻烦，可以使用gcj来编译。<br /><br /><strong><span style="font-size: small;">4.&nbsp; 将执行包编译成exe文件， 使用安装工具打包</span></strong><br /><br />把java启动类编译成可执行文件的工具很多，我经过比较，使用的是launch4j，主要是支持的特性多一些，对linux也提供支持。<br />然后再把jre和应用整理规划好目录，使用安装工具打包， 我选择的是nsis， 也是免费的东西， nisi如果不想深入研究的话，建议找supertoy开发的一个脚本生成向导工具，很好用。<br /><br /><span style="font-size: small;"><strong>5. 其他</strong></span><br /><br />&nbsp; * 需要考虑数据的备份和交换操作， 我一般使用dbunit来干这个事， 因为导出导入都可以是完整的xml文件，比较方便。<br />&nbsp; * 如果要制作光盘版本，再配置一个auto run 就可以自动启动了。<br />&nbsp;&nbsp;* 要防止应用多次启动， 实现思路有2种，一个是使用一个端口来检测， 另外一个就是使用文件锁。 我使用的是后者，盗用了hsql的部分代码。<br /><br />基本思路很简单，工作量也不大， 呵呵，反正当初用户是看不出来这是java 做得，还误以为我们是用delphi之类重新开发的。<br /></li>
</ul>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/207031#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/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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jun 2008 10:52:59 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/207031</link>
        <guid>http://hintcnuie.javaeye.com/blog/207031</guid>
      </item>
      <item>
        <title>关于一些Linux SVN的安装使用 </title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/206631" style="color:red;">http://hintcnuie.javaeye.com/blog/206631</a>&nbsp;
          发表时间: 2008年06月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong>SVN简介</strong>
 <br />
<br />
The goal of the Subversion project is to build a 
<strong>version control system</strong>
 that is a compelling replacement for CVS 
in the open source community. The software is released under an <a href="http://subversion.tigris.org/project_license.html">Apache/BSD-style</a>
 
open source 
license.<br />
<br />
SVN是一个版本控制软件，类似CVS，但是SVN的的有点是开源的，而且SVN的版本控制能力给CVS还要强多。<br />
<br />
SVN可以用于项目管理，还可以用于版本同步，功能可是十分强呢：）<br />
<br />
下载：<a href="http://subversion.tigris.org/">http://subversion.tigris.org</a>
<br />
<br />
当前日期稳定版SVN1.32<a href="http://subversion.tigris.org/downloads/subversion-1.3.2.tar.gz">http://subversion.tigris.org/downloads/subversion-1.3.2.tar.gz</a>
<br />
<br />
<strong>安装：</strong>
<br />
<br />
解压：#: 
tar zxvf subversion-1.3.2.tar.gz<br />
<br />
依次输入./configure , make , make install 
进行编译安装完成。<br />
<br />
开启SVN服务：svnserve -d <br />
记住，一定要把SVN的项目的home 
路径在启动时候加上，不然启动还是不能用的。参数如下<br />
svnserve -d -r 
/home/svnserve<br />
<br />
<br />
检测服务是否开启：netstat 
-ntlp如果看到3690的端口正常开放了，证明SVN启动了。<br />
<br />
<strong>正式使用：<br />
</strong>
首先我们得建立一个SVN的项目，一般人都认为建立项目就只需要一个文件，在我第一次使用SVN之前都有这样的看法，SVN建立项目需要建立文件夹<br />
<br />
建立项目命令：svnadmin 
create project_name&nbsp;&nbsp;&nbsp; project_name 
为你的project名字，可以任意取。<br />
建立完毕后，project_name是一个文件夹，进入文件夹，可以看到一个conf的文件夹。进入文件夹可以看到2个文件（如果没有passwd文件，可以用vi创建），编辑 
<span lang="EN-US" style="font-size: 12pt; color: red; font-family: Times;"><span style="color: #000000;">svnserve.conf</span>
&nbsp; <span style="color: #000000;">把anon-access = read 
,auth_access = write<br />
</span>
</span>
还有password-db = passwd 
的注释去掉，还有[general]的注释也要去掉。<br />
vi passwd文件，如果是新文件，则输入:<br />
[user]<br />
your_name = 
your_password<br />
这里设置的your_name是你的用户名，your_password是你的密码，这个是访问SVN必要的通行证。<br />
<br />
<br />
好了，现在终于把准备功夫做完了，下面可以正是使用了。<br />
简历一个临时文件夹，在里面建立三个文件夹，用于装载SVN 
Project的版本信息，或者分支版本<br />
mkdir temp<br />
mkdir temp/trunk<br />
mkdir 
temp/tags<br />
mkdir temp/branches<br />
建立好后<br />
输入命理 svn import temp/ svn: 
//localhost/projectname -m &quot;Hello world!&quot;;<br />
<br />
首先找到你的项目源代码文件夹，使用下面命令：<br />
cd 
your project<br />
in your project dircetory<br />
use：svn co /home/project_name 
--username = your_name 
--password=your_password<br />
<br />
好了，现在你可以在客户机上使用以下命令获得你想要的项目源代码文件<br />
svn co 
svn://home/project_name --username=your_name --password = 
your_password<br />
<br />
把增加的svn文件添加入svn库：<br />
svn add /home/your_project/*.* 
--username=your_name --password = your_password<br />
<br />
提交文件：<br />
svn commit 
/home/your_project/*.* --username=your_name 
--password=your_password<br />
<br />
更新文件：svn update /home/your_project/*.* 
--username=your_name 
--password=your_password<br />
<br />
当然你可以编辑一个脚本文件来一次完成所有的操作：<br />
vi 
svnupdate.sh<br />
<br />
#!/bin/sh<br />
svn add /home/your_project/*.* 
--username=your_name --password = your_password<br />
svn commit 
/home/your_project/*.* --username=your_name --password=your_password<br />
svn 
update /home/your_project/*.* --username=your_name 
--password=your_password<br />
<br />
<br />
chmod +x svnupdate.sh<br />
<br />
Finish</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/206631#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/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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 21 Jun 2008 13:24:42 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/206631</link>
        <guid>http://hintcnuie.javaeye.com/blog/206631</guid>
      </item>
      <item>
        <title>Wget使用详解</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/206629" style="color:red;">http://hintcnuie.javaeye.com/blog/206629</a>&nbsp;
          发表时间: 2008年06月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>wget是在Linux下开发的开放源代码的软件，作者是Hrvoje Niksic，后来被移植到包括Windows在内的各个平台上。它有以下功能和特点：
</p>
<p>　　（1）支持断点下传功能；这一点，也是网络蚂蚁和FlashGet当年最大的卖点，现在，Wget也可以使用此功能，那些网络不是太好的用户可以放心了； <br />
　　（2）同时支持FTP和HTTP下载方式；尽管现在大部分软件可以使用HTTP方式下载，但是，有些时候，仍然需要使用FTP方式下载软件； <br />
　　（3）支持代理服务器；对安全强度很高的系统而言，一般不会将自己的系统直接暴露在互联网上，所以，支持代理是下载软件必须有的功能； <br />
　　（4）设置方便简单；可能，习惯图形界面的用户已经不是太习惯命令行了，但是，命令行在设置上其实有更多的优点，最少，鼠标可以少点很多次，也不要担心是否错点鼠标； <br />
　　（5）程序小，完全免费；程序小可以考虑不计，因为现在的硬盘实在太大了；完全免费就不得不考虑了，即使网络上有很多所谓的免费软件，但是，这些软件的广告却不是我们喜欢的； </p>
<p>&nbsp;&nbsp;&nbsp; wget虽然功能强大，但是使用起来还是比较简单的，基本的语法是：wget [参数列表] URL。下面就结合具体的例子来说明一下wget的用法。<br />
&nbsp;&nbsp;&nbsp; 1、下载整个http或者ftp站点。<br />
&nbsp;&nbsp;&nbsp; wget <a href="http://place.your.url/here">http://place.your.url/here</a>
<br />
&nbsp;&nbsp;&nbsp; 这个命令可以将<a href="http://place.your.url/here">http://place.your.url/here</a>
 首页下载下来。使用-x会强制建立服务器上一模一样的目录，如果使用-nd参数，那么服务器上下载的所有内容都会加到本地当前目录。</p>
<p>&nbsp;&nbsp;&nbsp; wget -r <a href="http://place.your.url/here">http://place.your.url/here</a>
<br />
&nbsp;&nbsp;&nbsp;
这个命令会按照递归的方法，下载服务器上所有的目录和文件，实质就是下载整个网站。这个命令一定要小心使用，因为在下载的时候，被下载网站指向的所有地址
同样会被下载，因此，如果这个网站引用了其他网站，那么被引用的网站也会被下载下来！基于这个原因，这个参数不常用。可以用-l
number参数来指定下载的层次。例如只下载两层，那么使用-l 2。</p>
<p>&nbsp;&nbsp;&nbsp; 要是您想制作镜像站点，那么可以使用－m参数，例如：wget -m <a href="http://place.your.url/here">http://place.your.url/here</a>
<br />
&nbsp;&nbsp;&nbsp; 这时wget会自动判断合适的参数来制作镜像站点。此时，wget会登录到服务器上，读入robots.txt并按robots.txt的规定来执行。</p>
<p>&nbsp;&nbsp;&nbsp; 2、断点续传。<br />
&nbsp;&nbsp;&nbsp; 当文件特别大或者网络特别慢的时候，往往一个文件还没有下载完，连接就已经被切断，此时就需要断点续传。wget的断点续传是自动的，只需要使用-c参数，例如：<br />
&nbsp;&nbsp;&nbsp; wget -c <a href="http://the.url.of/incomplete/file">http://the.url.of/incomplete/file</a>
<br />
&nbsp;&nbsp;&nbsp; 使用断点续传要求服务器支持断点续传。-t参数表示重试次数，例如需要重试100次，那么就写-t 100，如果设成-t 0，那么表示无穷次重试，直到连接成功。-T参数表示超时等待时间，例如-T 120，表示等待120秒连接不上就算超时。</p>
<p>&nbsp;&nbsp;&nbsp; 3、批量下载。<br />
&nbsp;&nbsp;&nbsp; 如果有多个文件需要下载，那么可以生成一个文件，把每个文件的URL写一行，例如生成文件download.txt，然后用命令：wget -i download.txt<br />
这样就会把download.txt里面列出的每个URL都下载下来。（如果列的是文件就下载文件，如果列的是网站，那么下载首页）</p>
<p>&nbsp;&nbsp;&nbsp; 4、选择性的下载。<br />
&nbsp;&nbsp;&nbsp; 可以指定让wget只下载一类文件，或者不下载什么文件。例如：<br />
&nbsp;&nbsp;&nbsp; wget -m --reject=gif <a href="http://target.web.site/subdirectory">http://target.web.site/subdirectory</a>
<br />
&nbsp;&nbsp;&nbsp; 表示下载<a href="http://target.web.site/subdirectory">http://target.web.site/subdirectory</a>
，但是忽略gif文件。--accept=LIST 可以接受的文件类型，--reject=LIST拒绝接受的文件类型。</p>
<p>&nbsp;&nbsp;&nbsp; 5、密码和认证。<br />
&nbsp;&nbsp;&nbsp; wget只能处理利用用户名/密码方式限制访问的网站，可以利用两个参数：<br />
&nbsp;&nbsp;&nbsp; --http-user=USER设置HTTP用户<br />
&nbsp;&nbsp;&nbsp; --http-passwd=PASS设置HTTP密码<br />
&nbsp;&nbsp;&nbsp; 对于需要证书做认证的网站，就只能利用其他下载工具了，例如curl。</p>
<p>&nbsp;&nbsp;&nbsp; 6、利用代理服务器进行下载。<br />
&nbsp;&nbsp;&nbsp; 如果用户的网络需要经过代理服务器，那么可以让wget通过代理服务器进行文件的下载。此时需要在当前用户的目录下创建一个.wgetrc文件。文件中可以设置代理服务器：<br />
&nbsp;&nbsp;&nbsp; http-proxy = 111.111.111.111:8080<br />
&nbsp;&nbsp;&nbsp; ftp-proxy = 111.111.111.111:8080<br />
&nbsp;&nbsp;&nbsp; 分别表示http的代理服务器和ftp的代理服务器。如果代理服务器需要密码则使用：<br />
&nbsp;&nbsp;&nbsp; --proxy-user=USER设置代理用户<br />
&nbsp;&nbsp;&nbsp; --proxy-passwd=PASS设置代理密码 <br />
&nbsp;&nbsp;&nbsp; 这两个参数。<br />
&nbsp;&nbsp;&nbsp; 使用参数--proxy=on/off 使用或者关闭代理。<br />
&nbsp;&nbsp;&nbsp; wget还有很多有用的功能，需要用户去挖掘。</p>
<p>附录：</p>
<p>命令格式：<br />
　　wget [参数列表] [目标软件、网页的网址]</p>
<p>　　-V,--version 显示软件版本号然后退出；<br />
　　-h,--help显示软件帮助信息；<br />
　　-e,--execute=COMMAND 执行一个 &quot;.wgetrc&quot;命令</p>
<p>　　-o,--output-file=FILE 将软件输出信息保存到文件；<br />
　　-a,--append-output=FILE将软件输出信息追加到文件；<br />
　　-d,--debug显示输出信息；<br />
　　-q,--quiet 不显示输出信息；<br />
　　-i,--input-file=FILE 从文件中取得URL；</p>
<p>　　-t,--tries=NUMBER 是否下载次数（0表示无穷次）<br />
　　-O --output-document=FILE下载文件保存为别的文件名<br />
　　-nc, --no-clobber 不要覆盖已经存在的文件<br />
　　-N,--timestamping只下载比本地新的文件<br />
　　-T,--timeout=SECONDS 设置超时时间<br />
　　-Y,--proxy=on/off 关闭代理</p>
<p>&nbsp;&nbsp;&nbsp; -nd,--no-directories 不建立目录<br />
　　-x,--force-directories 强制建立目录</p>
<p>&nbsp;&nbsp;&nbsp; --http-user=USER设置HTTP用户<br />
　　--http-passwd=PASS设置HTTP密码<br />
　　--proxy-user=USER设置代理用户<br />
　　--proxy-passwd=PASS设置代理密码</p>
<p>&nbsp;&nbsp;&nbsp; -r,--recursive 下载整个网站、目录（小心使用）<br />
　　-l,--level=NUMBER 下载层次</p>
<p>&nbsp;&nbsp;&nbsp; -A,--accept=LIST 可以接受的文件类型<br />
　　-R,--reject=LIST拒绝接受的文件类型<br />
　　-D,--domains=LIST可以接受的域名<br />
　　--exclude-domains=LIST拒绝的域名<br />
　　-L,--relative 下载关联链接<br />
　　--follow-ftp 只下载FTP链接<br />
　　-H,--span-hosts 可以下载外面的主机<br />
　　-I,--include-directories=LIST允许的目录<br />
　　-X,--exclude-directories=LIST 拒绝的目录</p>
<p>&nbsp;&nbsp;&nbsp; 中文文档名在平常的情况下会被编码， 但是在 --cut-dirs 时又是正常的，<br />
&nbsp;&nbsp;&nbsp; wget -r -np -nH --cut-dirs=3 <a href="ftp://host/test/">ftp://host/test/</a>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 测试.txt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; wget -r -np -nH -nd <a href="ftp://host/test/">ftp://host/test/</a>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %B4%FA%B8%D5.txt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; wget &quot;<a href="ftp://host/test/">ftp://host/test/</a>
*&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %B4%FA%B8%D5.txt</p>
<p>&nbsp;&nbsp;&nbsp; 由於不知名的原因，可能是为了避开特殊档名， wget 会自动将抓取档名的部分用 encode_string 处理过， 所以该
patch 就把被 encode_string 处理成 &quot;%3A&quot; 这种东西， 用 decode_string 还原成
&quot;:&quot;，并套用在目录与档案名称的部分，decode_string 是 wget 内建的函式。</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/206629#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/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/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 21 Jun 2008 13:12:28 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/206629</link>
        <guid>http://hintcnuie.javaeye.com/blog/206629</guid>
      </item>
      <item>
        <title>如何去除WAS数据源中类似的警告信息</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/205850" style="color:red;">http://hintcnuie.javaeye.com/blog/205850</a>&nbsp;
          发表时间: 2008年06月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h3><a href="http://ricky-love.javaeye.com/blog/47032"><br />
</a>
</h3>
<p>在基于WAS开发的系统中，SystemOut.log中经常出现如下信息：<br />
如何解决这个警告:<br />
[3/29/06
14:10:12:015 CST] 00000025 ConnectionFac W&nbsp;&nbsp; J2CA0294W: Deprecated
usage of direct JNDI lookup of resource jdbc/whaty.&nbsp; The following
default values are used: [Resource-ref settings]<br />
&nbsp;<br />
&nbsp;res-auth:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 (APPLICATION)<br />
&nbsp;res-isolation-level:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 (TRANSACTION_NONE)<br />
&nbsp;res-sharing-scope:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true (SHAREABLE)<br />
&nbsp;loginConfigurationName:&nbsp;&nbsp; null<br />
&nbsp;loginConfigProperties:&nbsp;&nbsp;&nbsp; null<br />
[Other attributes]<br />
&nbsp;<br />
&nbsp;res-resolution-control:&nbsp;&nbsp; 999 (undefined)<br />
isCMP1_x:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false (not CMP1.x)<br />
isJMS:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false (not JMS)<br />
&nbsp;<br />
这是怎么回事呢？<br />
其实这个警告信息并不影响应用的运行，主要是开发人员没有严格遵守J2EE规范引起的。通过如下方法来解决：<br />
1，在程序中这样改lookup的参数：<br />
javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup(&quot;java:comp/env/jdbc/ecommDB&quot;);<br />
&nbsp;<br />
2，web.xml中包含类似信息：<br />
&nbsp;&lt;resource-ref id=&quot;ResourceRef_1089625098453&quot;&gt;<br />
&nbsp; &lt;res-ref-name&gt;jdbc/ecommDB&lt;/res-ref-name&gt;<br />
&nbsp; &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />
&nbsp; &lt;res-auth&gt;Container&lt;/res-auth&gt;<br />
&nbsp; &lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;<br />
&nbsp;&lt;/resource-ref&gt;</p>
<p>
3，ibm-web-bnd.xmi文件增加类似语句：<br />
&nbsp; &lt;resRefBindings xmi:id=&quot;ResourceRefBinding_1089625098453&quot; jndiName=&quot;jdbc/ecommDB&quot;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;bindingResourceRef href=&quot;WEB-INF/web.xml#ResourceRef_1089625098453&quot;/&gt;<br />
&nbsp; &lt;/resRefBindings&gt;</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/205850#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/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>Thu, 19 Jun 2008 16:10:07 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/205850</link>
        <guid>http://hintcnuie.javaeye.com/blog/205850</guid>
      </item>
      <item>
        <title>java汉化教程 和所需软件可用版连接 </title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/201580" style="color:red;">http://hintcnuie.javaeye.com/blog/201580</a>&nbsp;
          发表时间: 2008年06月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>java的开发建议使用jbuilder、eclipse或是netbeans <br />eclipse在这里免费下载：<a href="http://www.eclipse.org/downloads/" target="_blank">http://www.eclipse.org/downloads/</a> <br />netbeans在这里免费下载：<a href="http://dlc.sun.com.edgesuite.net/netbeans/6.0/final/" target="_blank">http://dlc.sun.com.edgesuite.net/netbeans/6.0/final/</a> <br /><br />教程的话，你可以看看这个： <br />精通JBuilder 2005 中文版 高清PDF+随书光盘 <br /><a href="http://bbs.topsage.com/dispbbs_121_172861_1.html" target="_blank">http://bbs.topsage.com/dispbbs_121_172861_1.html</a> <br /><br />是中文版，也有随书光盘中的实例。 <br /><br />下面还有一些好的资料和视频供你参考一下： <br /><br />Java 编程初步 傻瓜书 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159167" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159167</a> <br />数据结与算法 Java语言版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160250" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160250</a> <br />精通JBuilder 2005 中文版 高清PDF+随书光盘 <br /><a href="http://bbs.topsage.com/dispbbs_121_172861_1.html" target="_blank">http://bbs.topsage.com/dispbbs_121_172861_1.html</a> <br />JSF JavaServer Faces in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160229" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160229</a> <br />Spring in Action (第二版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146170" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146170</a> <br />Manning jQuery in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174769" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174769</a> <br />Spring In Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174107" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174107</a> <br />AspectJ in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174106" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174106</a> <br />Hibernate In Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174105" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174105</a> <br />Struts in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174005" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174005</a> <br />Lucene in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=173991" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=173991</a> <br />Java Extreme Programming Cookbook <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174729" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174729</a> <br />Java Programming Cookbook <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=173667" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=173667</a> <br />Beginning Java Objects <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174685" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174685</a> <br />Building Java Enterprise App <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174684" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174684</a> <br />Ant: The Definitive Guide <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174683" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174683</a> <br />Better Faster Lighter Java <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174681" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174681</a> <br />Hibernate Reference 3.1 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174674" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174674</a> <br />Pragmatic Version Control using CVS <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174479" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174479</a> <br />Pragmatic Project Automation <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174476" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174476</a> <br />jQuery Reference Guide <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174411" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174411</a> <br />Java 2 核心技术 卷1&amp;卷2 CHM版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174123" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174123</a> <br />Wrox Professional Java JDK 6 Edition <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163451" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163451</a> <br />Java 2 宝典 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159154" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159154</a> <br />侯捷java编程思想 PDF中文版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163902" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163902</a> <br />Learning Java (第三版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146869" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146869</a> <br />Beginning Java Programming for Dummies 第二版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163923" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163923</a> <br />Java 2 核心编程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146174" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146174</a> <br />Java How to Program (第六版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146371" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146371</a> <br />Java All-In-One案头参考傻瓜书 (第二版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152871" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152871</a> <br />21天自学 Java 6 (2007年5月更新出版) PDF <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159315" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159315</a> <br />Java咖啡馆 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151447" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151447</a> <br />Thinking in Java(第四版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152053" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152053</a> <br />深入学习JFC SWING - Java基础类组件集 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152049" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152049</a> <br />J2EE全实例教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158057" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158057</a> <br />Java信息系统设计与开发实例(第二版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151993" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151993</a> <br />Java优化编程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151994" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151994</a> <br />Java信息系统设计与开发实例(第二版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151993" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151993</a> <br />Tricks of the Java Programming <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159305" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159305</a> <br />Wrox Professional Java Native Interfaces with SWT JFace <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159290" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159290</a> <br />Java Swing 第二版 PDF文字版 O'Relliy出版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159158" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159158</a> <br />O'Reilly - Java Database Programming with JDBC <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159292" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159292</a> <br />JDBC与Java数据库程序设计 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151448" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151448</a> <br />Learning JQurey (2007年7月最新出版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159652" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159652</a> <br />J2EE设计开发编程指南 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159288" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159288</a> <br />Java Web Services简明教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159159" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159159</a> <br />O'Reilly Java and XML (第二版PDF) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146231" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146231</a> <br />O'Reilly Java and XML (第三版PDF) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=167584" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=167584</a> <br />Java技术XML高级编程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=147800" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=147800</a> <br />Expert One-on-One J2EE Design and Development <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160652" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160652</a> <br />Expert One-on-One J2EE Development without EJB <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160653" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160653</a> <br />JBoss - A Developer's Notebook <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146179" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146179</a> <br />The Java Programming Language (第四版) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=147095" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=147095</a> <br />Professional Java Development with the Spring Framework <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159303" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159303</a> <br />Core Java Server Faces 第二版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=145549" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=145549</a> <br />精通Enterprise JavaBeans <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146018" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146018</a> <br />Enterprise JavaBeans EJB 第四版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159166" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159166</a> <br />J2EE应用与BEA WebLogic Server (第二版PDF) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146227" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146227</a> <br />O'Reilly Java Web Services <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146377" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=146377</a> <br />Ant权威指南 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=148383" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=148383</a> <br />Ajax和Java框架高级编程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=148371" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=148371</a> <br />Java Web Services简明教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159159" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159159</a> <br />Cross-Platform Web Services Using C# and Java <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160472" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160472</a> <br />O'Reilly Ajax on Java <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160600" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160600</a> <br />O'Reilly Java and XSLT <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149585" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149585</a> <br />O'Reilly Java and XML Binding <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149583" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149583</a> <br />O'Reilly Java and SOAP <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149581" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149581</a> <br />Design Patterns Java Companion <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163920" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=163920</a> <br />J2EE Java黑客大曝光 开发安全的Java应用程序 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151446" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151446</a> <br />J2ME API 速查手册 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158248" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158248</a> <br />精通J2ME无线编程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152047" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152047</a> <br />J2ME开发大全 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151987" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151987</a> <br />Java网页开发的艺术 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151991" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151991</a> <br />Java编程高手 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151990" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151990</a> <br />Java 5.0 Tiger程序高手秘笈 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151989" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151989</a> <br />Java2网络协议技术内幕(附源码) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151988" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151988</a> <br />Using Enterprise JavaBeans 2 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166051" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166051</a> <br />Java技术实用教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158244" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158244</a> <br />企业级Java安全性(构建安全的J2EE应用) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152048" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=152048</a> <br />Java语言集成开发环境Eclipse中文教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158237" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158237</a> <br />NetBeans IDE 5.5 企业版高级开发教程 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159653" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=159653</a> <br />Using Enterprise JavaBeans 2 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166051" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166051</a> <br />Borland JBuilder Developer's Guide <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166294" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=166294</a> <br />Eclipse精要与高级开发技术 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151986" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=151986</a> <br />Code Generation in Action <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174722" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=174722</a> <br />Java 6 3D游戏开发 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160251" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=160251</a> <br /><br /><br /><br /><br />Java视频教程 孙鑫Java无难事 (全12CD) <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=154630" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=154630</a> <br />J2EE开发IDE Eclipse视频教程 全9CD 完整版 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158075" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=158075</a> <br />Java视频教程 即学即会java <br /><a href="http://bbs.topsage.com/dispbbs_121_156264_6.html" target="_blank">http://bbs.topsage.com/dispbbs_121_156264_6.html</a> <br />J2EE高级开发视频教程第01讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149010" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149010</a> <br />J2EE高级开发视频教程第02讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149011" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149011</a> <br />J2EE高级开发视频教程第03讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149012" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149012</a> <br />J2EE高级开发视频教程第04讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149113" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149113</a> <br />J2EE高级开发视频教程第05讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149209" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149209</a> <br />J2EE高级开发视频教程第06讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149211" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149211</a> <br />J2EE高级开发视频教程第07讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149212" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149212</a> <br />J2EE高级开发视频教程第08讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149214" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149214</a> <br />J2EE高级开发视频教程第09讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149215" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149215</a> <br />J2EE高级开发视频教程第10讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149216" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149216</a> <br />J2EE高级开发视频教程第11讲 <br /><a href="http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149217" target="_blank">http://bbs.topsage.com/dispbbs.asp?boardID=121&amp;ID=149217</a></p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/201580#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 09 Jun 2008 22:17:29 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/201580</link>
        <guid>http://hintcnuie.javaeye.com/blog/201580</guid>
      </item>
      <item>
        <title>log4j.properties备用</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/199583" style="color:red;">http://hintcnuie.javaeye.com/blog/199583</a>&nbsp;
          发表时间: 2008年06月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">log4j.rootLogger=debug, stdout, R


log4j.appender.stdout
=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L)
 - %m%n

log4j.appender.R
=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB

# Keep one backup file
log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN

</pre>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://hintcnuie.javaeye.com/blog/199583#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/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 03 Jun 2008 00:33:18 +0800</pubDate>
        <link>http://hintcnuie.javaeye.com/blog/199583</link>
        <guid>http://hintcnuie.javaeye.com/blog/199583</guid>
      </item>
      <item>
        <title>Spring Batch HelloWorld 例子</title>
        <author>hintcnuie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hintcnuie.javaeye.com">hintcnuie</a>&nbsp;
          链接：<a href="http://hintcnuie.javaeye.com/blog/198673" style="color:red;">http://hintcnuie.javaeye.com/blog/198673</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>
This is an introductory tutorial to Spring Batch. It does not aim to
provide a complete guide to the framework but rather to facilitate the
first contact. Spring Batch is quite rich in functionalities, and this
is basically how I started learning it.
Keep in mind that we will only be scratching the surface.
</p>
<h4>Before we start</h4>
<p>All the examples will have the lofty task of printing &quot;Hello World!&quot;
though in different ways. They were developed with Spring Batch 1.0.
I'll provide a Maven 2 project and I'll run the examples with Maven but
of course it is not a requirement to work with Spring Batch.
</p>
<h4>Spring Batch in 2 Words</h4>
<p>Fortunately, Spring Batch model objects have self-explanatory names.
Let's try to enumerate the most important and to link them together:
</p>
<p>
A batch <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/Job.html">Job</a>
 is composed of one or more <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/Step.html">Step</a>
s.  A <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobInstance.html">JobInstance</a>
 represents a given <span class="codeword">Job</span>
, parametrized with a set of typed properties called <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobParameters.html">JobParameters</a>
. Each run of of a <span class="codeword">JobInstance</span>
 is a <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/JobExecution.html">JobExecution</a>
.
Imagine a job reading entries from a data base and generating an xml
representation of it and then doing some clean-up. We have a <span class="codeword">Job</span>
composed of 2 steps: reading/writing and clean-up. If we parametrize
this job by the date of the generated data then our Friday the 13th job
is a <span class="codeword">JobInstance</span>
. Each time we run this instance (if a failure occurs for instance) is a <span class="codeword">JobExecution</span>
. 
This model gives a great flexibility regarding how jobs are launched and run.
This naturally brings us to launching jobs with their job parameters, which is the responsibility of <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/launch/JobLauncher.html">JobLauncher</a>
. Finally, various objects in the framework require a <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/repository/JobRepository.html">JobRepository</a>
to store runtime information related to the batch execution. In fact,
Spring Batch domain model is much more elaborate but this will suffice
for our purpose.
</p>
<p>Well, it took more than 2 words and I feel compelled to make a joke about it, but I won't. So let's move to the next section.</p>
<h4>Common Objects</h4>
<p>For each job, we will use a separate xml context definition file.
However there is a number of common objects that we will need
recurrently. I will group them in an applicationContext.xml which will
be imported from within job definitions. Let's go through these common
objects:
</p>
<h5>JobLauncher</h5>
<p><span class="codeword">JobLauncher</span>
s are responsible for starting a Job with a given job parameters. The provided implementation, <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/launch/support/SimpleJobLauncher.html">SimpleJobLauncher</a>
, relies on a <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/core/task/TaskExecutor.html">TaskExecutor</a>
 to launch the jobs. If no specific <span class="codeword">TaskExecutor</span>
 is set then a <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/core/task/SyncTaskExecutor.html">SyncTaskExecutor</a>
 is used. 
</p>
<h5>JobRepository</h5>
<p>We will use the <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/repository/support/SimpleJobRepository.html">SimpleJobRepository</a>
 implementation which requires a set of execution Daos to store its information.
</p>
<h5>JobInstanceDao, JobExecutionDao, StepExecutionDao</h5>
<p>These data access objects are used by <span class="codeword">SimpleJobRepository</span>
to store execution related information. Two sets of implementations are
provided by Spring Batch: Map based (in-memory) and Jdbc based. In a
real application the Jdbc variants are more suitable but we will use
the simpler in-memory alternative in this example.
</p>
<p>Here's our applicationContext.xml:</p>
<pre name="code" class="xml:nogutter:nocontrols">&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&quot;&gt;

  &lt;bean id=&quot;jobLauncher&quot; class=&quot;org.springframework.batch.core.launch.support.SimpleJobLauncher&quot;&gt;
      &lt;property name=&quot;jobRepository&quot; ref=&quot;jobRepository&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;jobRepository&quot; class=&quot;org.springframework.batch.core.repository.support.SimpleJobRepository&quot;&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapJobInstanceDao&quot;/&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapJobExecutionDao&quot; /&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapStepExecutionDao&quot;/&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt;

&lt;/beans&gt;
</pre>
<pre name="code" class="java">&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd&quot;&gt;

  &lt;bean id=&quot;jobLauncher&quot; class=&quot;org.springframework.batch.core.launch.support.SimpleJobLauncher&quot;&gt;
      &lt;property name=&quot;jobRepository&quot; ref=&quot;jobRepository&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;jobRepository&quot; class=&quot;org.springframework.batch.core.repository.support.SimpleJobRepository&quot;&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapJobInstanceDao&quot;/&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapJobExecutionDao&quot; /&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
          &lt;bean class=&quot;org.springframework.batch.core.repository.dao.MapStepExecutionDao&quot;/&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt;

&lt;/beans&gt;
</pre>
&nbsp;
<h4>Hello World with Tasklets</h4>
<p>A tasklet is an object containing any custom logic to be executed as a part of a job. Tasklets are built by implementing the <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/step/tasklet/Tasklet.html">Tasklet</a>
 interface. Let's  implement a simple tasklet that simply prints a message:</p>
<pre name="code" class="java:nogutter:nocontrols">public class PrintTasklet implements Tasklet{

  private String message;

  public void setMessage(String message) {
      this.message = message;
  }
    
  public ExitStatus execute() throws Exception {
      System.out.print(message);
      return ExitStatus.FINISHED;
  }
}
</pre>
<pre name="code" class="java">public class PrintTasklet implements Tasklet{

  private String message;

  public void setMessage(String message) {
      this.message = message;
  }
    
  public ExitStatus execute() throws Exception {
      System.out.print(message);
      return ExitStatus.FINISHED;
  }
}
</pre>
&nbsp;
<p>Notice that the <span class="codeword">execute</span>
 method returns an <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/repeat/ExitStatus.html">ExitStatus</a>
 to indicate the status of the execution of the tasklet.</p>
<p>We will define our first job now in a simpleJob.xml application context. We will use the <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/job/SimpleJob.html">SimpleJob</a>
 implementation which executes all of its steps sequentailly. In order to plug a tasklet into a job, we need a <a href="http://static.springframework.org/spring-batch/apidocs/org/springframework/batch/core/step/tasklet/TaskletStep.html">TaskletStep</a>
. I also added an abstract bean definition for tasklet steps in order to simplify the configuration:</p>
<pre name="code" class="xml:nogutter:nocontrols">&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&quot;&gt;
                                
  &lt;import resource=&quot;applicationContext.xml&quot;/&gt;
    
  &lt;bean id=&quot;hello&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot;Hello&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;space&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot; &quot;/&gt;
  &lt;/bean&gt;
   
  &lt;bean id=&quot;world&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot;World!&quot;/&gt;
  &lt;/bean&gt;

  &lt;bean id=&quot;taskletStep&quot; abstract=&quot;true&quot;
      class=&quot;org.springframework.batch.core.step.tasklet.TaskletStep&quot;&gt;
      &lt;property name=&quot;jobRepository&quot; ref=&quot;jobRepository&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;simpleJob&quot; class=&quot;org.springframework.batch.core.job.SimpleJob&quot;&gt;
      &lt;property name=&quot;name&quot; value=&quot;simpleJob&quot; /&gt;
      &lt;property name=&quot;steps&quot;&gt;
          &lt;list&gt;
              &lt;bean parent=&quot;taskletStep&quot;&gt;
                  &lt;property name=&quot;tasklet&quot; ref=&quot;hello&quot;/&gt;
              &lt;/bean&gt;
              &lt;bean parent=&quot;taskletStep&quot;&gt;
                  &lt;property name=&quot;tasklet&quot; ref=&quot;space&quot;/&gt;
              &lt;/bean&gt;
              &lt;bean parent=&quot;taskletStep&quot;&gt;;
                  &lt;property name=&quot;tasklet&quot; ref=&quot;world&quot;/&gt;
              &lt;/bean&gt;
          &lt;/list&gt;
      &lt;/property&gt;
      &lt;property name=&quot;jobRepository&quot; ref=&quot;jobRepository&quot;/&gt;
  &lt;/bean&gt;
&lt;/beans&gt;
</pre>
<pre name="code" class="java">&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd&quot;&gt;
                                
  &lt;import resource=&quot;applicationContext.xml&quot;/&gt;
    
  &lt;bean id=&quot;hello&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot;Hello&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;space&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot; &quot;/&gt;
  &lt;/bean&gt;
   
  &lt;bean id=&quot;world&quot; class=&quot;helloworld.PrintTasklet&quot;&gt;
      &lt;property name=&quot;message&quot; value=&quot;World!&quot;/&gt;
  &lt;/bean&gt;

  &lt;bean id=&quot;taskletStep&quot; abstract=&quot;true&quot;
      class=&quot;org.springframework.batch.core.step.tasklet.TaskletStep&quot;&gt;
      &lt;property name=&quot;jobRepository&quot; ref=&quot;jobRepository&quot;/&gt;
  &lt;/bean&gt;
    
  &lt;bean id=&quot;simpleJob&quot; class=&quot;org.springframework.batch.core.job.SimpleJob&quot;&gt;
      &lt;property name=&quot;name&quot; value=&quot;simpleJob&quot; /&gt;
      &lt;property name=