<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>cats_tiger</title>
    <description>日夜编程的猫...
正在使用webwork/jsf/struts + spring + hibernate的猫...</description>
    <link>http://cats-tiger.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>Jquery终于有两个看得过去的Grid插件了</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/200285" style="color:red;">http://cats-tiger.javaeye.com/blog/200285</a>&nbsp;
          发表时间: 2008年06月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          因为喜欢jQuery,所以一直希望整个团队都用jquery，可惜它的UI比较薄弱尤其没有好用的Grid。GT-Grid虽然很好很强大，但可惜不开源（免费但是不开源），而且只有fins大大一个人支撑，令人担心。现在，jquery终于有了两个不错的Grid了。<br />第一个是这个：<a href="http://webplicity.net/flexigrid/" target="_blank">http://webplicity.net/flexigrid/</a>，功能虽然算不上有什么了不起，但是基本的都有了，风格类似于Ext。对我来说，flexgrid是一个够用的grid.<br />另外一个是jqGrid。以前在<a href="http://plugins.jquery.com/" target="_blank">http://plugins.jquery.com/</a>狂找，基本没有发现符合要求的Grid，只有一个jqGrid，但是不支持JSon，只能用XML。刚才去jqGrid的网站上看了，现在3.1版本了，支持Json，还有很多功能，貌似不比Ext Grid差多少。jqGrid发展挺快的，前不久记得还是1.0，现在就3.2了，文档也不错，可是找了半天也没有找到它的许可协议。jqGrid的网站是<a href="http://www.trirand.com/blog/" target="_blank">http://www.trirand.com/blog/</a><br /><br />BTW：很理解GT-Grid不开源，可是不开源的我是不敢放到项目中用的，以前的ECSide俺可是读了一遍代码才用的。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/200285#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 04 Jun 2008 22:54:04 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/200285</link>
        <guid>http://cats-tiger.javaeye.com/blog/200285</guid>
      </item>
      <item>
        <title>新版本will_paginate的安装和使用</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/199684" style="color:red;">http://cats-tiger.javaeye.com/blog/199684</a>&nbsp;
          发表时间: 2008年06月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          SVN方式的安装已经不被推荐了，新的will_paginate采用Gem安装。<br /><pre name="code" class="java">
gem install mislav-will_paginate --source http://gems.github.com 
</pre><br />成功后的提示信息如下：<br /><pre name="code" class="java">
Successfully installed mislav-will_paginate-2.3.2
Installing ri documentation for mislav-will_paginate-2.3.2...
Installing RDoc documentation for mislav-will_paginate-2.3.2...
</pre><br />升级也一样，只需要将上面的install改为update.<br />安装之后需要修改config/environment.rb文件<br /><pre name="code" class="ruby">
RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION
require File.join(File.dirname(__FILE__), 'boot')

Rails::Initializer.run do |config|
  #....
end
require 'will_paginate'
</pre><br /><strong>注意</strong>：必须在Rails::Initializer之后加入will_paginate.<br /><br />这样总是安装最后的版本，如果需要安装指定的版本，可以这样：<br /><pre name="code" class="ruby">
# choose one of the following constraints:
gem 'mislav-will_paginate', '2.1.0'
gem 'mislav-will_paginate', '>=2.1.0'
gem 'mislav-will_paginate', '~>2.1' # this will load any 2.x version (greater or equal to 2.1),
                                    # but not 3.x

# finally, load the library
require 'will_paginate'
</pre><br /><br />在will_paginate的wiki上还介绍了几种安装方法，详情请看<a href="http://github.com/mislav/will_paginate/wikis" target="_blank">http://github.com/mislav/will_paginate/wikis</a>
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/199684#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 03 Jun 2008 12:37:36 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/199684</link>
        <guid>http://cats-tiger.javaeye.com/blog/199684</guid>
      </item>
      <item>
        <title>一劳永逸——让Spring自动加载Hibernate Annotated Classes</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/198525" style="color:red;">http://cats-tiger.javaeye.com/blog/198525</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          通常，spring整合Hibernate的SessionFactory是这样做的:<br /><pre name="code" class="xml">
&lt;property name="annotatedClasses">
   &lt;list>&lt;value>com.systop.common.core.dao.testmodel.TestDept&lt;/value>&lt;/list>
&lt;/property>
&lt;property name="mappingLocations">
     &lt;list>&lt;value>classpath*:org/jbpm/**/*.hbm.xml&lt;/value>&lt;/list>
&lt;/property>
</pre><br />Spring可以根据mappingLocations属性中定义的Path Pattern自动加载hbm文件，但是对于annotatedClasses则只能一个一个的苦恼的写上去。无论是Hibernate还是Spring，都不能自动的加载某个package下的Anntated Classes。这样，一旦项目需要重构或者增加/减少Tables就会带来一些麻烦。尤其是对于那些已经打包的应用来说更是如此。<br />能不能让Spring自动加载AnnotatedClasses呢，我想到了Spring2.5中component-scan，于是便照猫画虎的写了一个AnnotationSessionFactoryBean的子类:<br /><pre name="code" class="java">
package com.systop.common.core.dao.hibernate;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;

import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.hibernate.HibernateException;
import org.hibernate.cfg.AnnotationConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;

import com.systop.common.core.exception.ApplicationException;

@SuppressWarnings("unchecked")
public class AnnotationSessionFactoryBeanEx extends AnnotationSessionFactoryBean {
  private static final Logger logger = LoggerFactory
      .getLogger(AnnotationSessionFactoryBeanEx.class);

  /**
   * The locations of the hibernate enity class files. They are often some of the string with
   * Sping-style resource. A ".class" subfix can make the scaning more precise.
   * &lt;p> example:
   * &lt;pre>
   * classpath*:com/systop/** /model/*.class
   * &lt;/pre>
   */
  private String[] annotatedClassesLocations;

  /**
   * Which classes are not included in the session.
   * They are some of the regular expression.
   */
  private String[] excludedClassesRegexPatterns;  

  /**
   * @param annotatedClassesLocations the annotatedClassesLocations to set
   */
  public void setAnnotatedClassesLocations(String[] annotatedClassesLocations) {
    this.annotatedClassesLocations = annotatedClassesLocations;
  }

  /**
   * @see AnnotationSessionFactoryBean#postProcessAnnotationConfiguration(org.hibernate.cfg.AnnotationConfiguration)
   */
  @Override
  protected void postProcessAnnotationConfiguration(AnnotationConfiguration config)
      throws HibernateException {
    Set&lt;Class> annClasses = scanAnnotatedClasses(); //Scan enity classes.
    // Add entity classes to the configuration.
    if (!CollectionUtils.isEmpty(annClasses)) {
      for (Class annClass : annClasses) {
        config.addAnnotatedClass(annClass);
      }
    }
  }
  
  /**
   * Scan annotated hibernate classes in the locations.
   * @return Set of the annotated classes, if no matched class, return empty Set.
   */
  private Set&lt;Class> scanAnnotatedClasses() {
    ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(
        resourcePatternResolver);
    Set&lt;Class> annotatedClasses = new HashSet&lt;Class>();
    if (annotatedClassesLocations != null) {
      try {
        for (String annClassesLocation : annotatedClassesLocations) {
          //Resolve the resources
          Resource[] resources = resourcePatternResolver.getResources(annClassesLocation);
          for (Resource resource : resources) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            String className = metadataReader.getClassMetadata().getClassName();
            //If the class is hibernate enity class, and it does not match the excluded class patterns.
            if (isEntityClass(metadataReader) && !isExcludedClass(className)) {
              Class clazz = ClassUtils.forName(className);
              annotatedClasses.add(clazz);
              logger.debug("A entity class has been found. \n({})", clazz.getName());
            }
          }

        }
      } catch (IOException e) {
        logger.error("I/O failure during classpath scanning, ({})", e.getMessage());
        e.printStackTrace();
        throw new ApplicationException(e);
      } catch (ClassNotFoundException e) {
        logger.error("Class not found, ({})", e.getMessage());
        e.printStackTrace();
        throw new ApplicationException(e);
      } catch (LinkageError e) {
        logger.error("LinkageError ({})", e.getMessage());
        e.printStackTrace();
        throw new ApplicationException(e);
      }
    }

    return annotatedClasses;
  }
  
  /**
   * @return True if the given MetadataReader shows 
   * that the class is annotated by &lt;code>javax.persistence.Enity&lt;/code>
   */
  private boolean isEntityClass(MetadataReader metadataReader) {
    Set&lt;String> annTypes = metadataReader.getAnnotationMetadata().getAnnotationTypes();
    if (CollectionUtils.isEmpty(annTypes)) {
      return false;
    }
    
    return annTypes.contains(Entity.class.getName());
  }
  
  /**
   * 
   * @return True if the given class name match the excluded class patterns. 
   */
  private boolean isExcludedClass(String className) {
    if (excludedClassesRegexPatterns == null) { // All class is included.
      return false;
    }

    PatternCompiler compiler = new Perl5Compiler();
    PatternMatcher matcher = new Perl5Matcher();
    try {
      for (String regex : excludedClassesRegexPatterns) { //Test each patterns.
        logger.debug("Pattern is: {}", regex);
        Pattern pattern = compiler.compile(regex);
        if (matcher.matches(className, pattern)) {
          logger.debug("class [{}], matches [{}], so it is excluded.", className, pattern
              .getPattern());
          return true;
        }
      }
    } catch (MalformedPatternException e) {
      logger.warn("Malformed pattern [{}]", e.getMessage());
    }

    return false;
  }

  /**
   * @param exculdePatterns the exculdePatterns to set
   */
  public void setExcludedClassesRegexPatterns(String[] excludedClassesRegexPatterns) {
    this.excludedClassesRegexPatterns = excludedClassesRegexPatterns;
  }
}
</pre><br />在Spring的配置文件中这样写：<br /><pre name="code" class="xml">
&lt;bean id="sessionFactory" class="com.systop.common.core.dao.hibernate.AnnotationSessionFactoryBeanEx">
        &lt;property name="dataSource" ref="dataSource"/>
        &lt;property name="annotatedClassesLocations">
            &lt;list>
                &lt;value>classpath*:com/systop/**/model/*.class&lt;/value>
            &lt;/list>
        &lt;/property>
        &lt;!--用正则表达式匹配不被scan的类-->
        &lt;property name="excludedClassesRegexPatterns">
            &lt;list>
                &lt;value>&lt;![CDATA[^[\w\.]+Test[\w]+$]]&gt;&lt;/value>
            &lt;/list>
        &lt;/property>
&lt;/bean>
</pre><br />好了，一劳永逸！<br />哦，对了，提醒一下，上述代码使用了Spring2.5中的一些API，另外还有apache oro的正则表达式API。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/198525#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 30 May 2008 09:22:17 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/198525</link>
        <guid>http://cats-tiger.javaeye.com/blog/198525</guid>
      </item>
      <item>
        <title>【转帖】赈灾义演中的“美丽”</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/196203" style="color:red;">http://cats-tiger.javaeye.com/blog/196203</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          赈灾义演，明星捐款，反映了演艺界的爱心。与唱一首歌10万元、出场费可达30万元的“大腕”们相比，令我感动的是87岁的秦怡。因为她捐的20万元，几乎就是这位退休老人的全部积蓄!<br /><br />    秦怡有个重病的儿子需要抚养。还有一个90多岁的姐姐,也要靠她照顾。家里离不开人,秦怡自然不能参加多少演出和活动,每月2000多元的退休工资,基本就是她的全部收入。这样的经济负担，使她平时很节俭。为了省下给儿子打胰岛素要付的30元注射费, ,秦怡就自己学着注射。平时她连出租车都舍不得坐。虽然日子过得紧,秦怡在这次赈灾捐款时,还是捐出了20万元。她说,去年儿子已经病逝了,现在没有太多牵挂了,愿意把些钱拿出来,去帮助灾区那些更需要帮助的人。<br /><br />    这件事让我想起几年前与她的一次交谈。那天我见到秦怡时，她正在一针一线地补袜子。想到如今一些年轻女演员带着保姆带着保镖带着经纪人去拍戏，再看看这位从影70年的艺术家，我只有尊敬。那次我主要是想请她谈谈“艺德”。她告诉我，中国艺术家的品德“要有个基础，那就是对中华民族悲惨历史命运的切身体验。”讲到这里，秦怡的目光变得深邃起来，好像在探视着时光隧道：“日本鬼子打上海时，谢晋元团长带着八百壮士拼命抵抗。我那时还和同学老师到‘四行仓库 ’慰问前方将士呢!经过八年抗战、经过三年内战的中国人，谁能不珍惜新中国、谁能不热爱祖国不热爱人民不热爱为老百姓打江山的人呢?这就是我一切创作表演的基础。像我这样饱经风雨的人，不会飘浮、更不会愧对自己的艺术良心。”<br /><br />    “品德要有个基础，那就是对中华民族悲惨历史命运的切身体验”“ 像我这样饱经风雨的人，不会愧对自己的艺术良心”，老人家的话说到了点子上。这些话大概可以解释她为什么会把自己不多的积蓄献给灾区，因为她是一个懂得苦难的人；这大概也能解释为什么这位87岁的老太太仍能始终保持着一种平静端庄的美丽，因为她有一颗充满大爱的艺术良心。<br />【原帖】http://blog.sina.com.cn/s/blog_475b7ae701009lyy.html
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/196203#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, 23 May 2008 17:52:52 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/196203</link>
        <guid>http://cats-tiger.javaeye.com/blog/196203</guid>
      </item>
      <item>
        <title>【转帖】是人民养育了你们，你们看着办！</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/196200" style="color:red;">http://cats-tiger.javaeye.com/blog/196200</a>&nbsp;
          发表时间: 2008年05月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          默哀！我在这里要说的是，网友对某些明星的捐款金额极度不满，发出了愤怒的声音，有些明星们就像被踩了狗尾巴，立刻就组成一个联盟，众口一辞跳出来：爱心不是用钱多少来衡量的。这句话就是屁话，爱心是可以量化的，一个乞丐倾其所有捐了105元，金额是比那些明星少很多，可是这里包含的爱要比某些明星纯粹的多，高尚的多。四川老百姓遭受这么大的灾难，正是你们这些明星应该做出突出贡献的时候，有什么垃圾足球队义演的时候，你们一个个像打了鸡血一样，上窜下跳。又不用出钱，又得玩了，又被传媒关注了，又博得热心参加慈善活动好名声，你们把好处都算尽，也赚尽了。要你们真金白银的捐款了，你们左顾右盼，5万 10万的捐，跟约好了似的。你们不要跟我们说：我们比你们老百姓捐的多的多。我要正告你们，你们就是应该多捐，捐到我们老百姓认可为止，我不是仇富，而是看透了你们冷血，冷酷自私的内心。四川一直以来是你们商业演出的提款机，选秀活动的大票仓，你们就是这么回报衣食父母的，我套用温总的话：是人民养育了你们，你们自己看着办！四川人民不会计较你们的冷血与吝啬，虽然我不是四川人，但我建议四川人民，我们要感恩，但我们也要学会铭记，铭记那些在最困难的时候某些明星的表现，我相信四川人民的智慧，知道以后该怎么做！我想起了一首歌：朋友来了有好酒，豺狼（白眼狼）来了，迎接他的有。。。。。。<br /><br />原帖：http://blog.tianya.cn/blogger/post_show.asp?BlogID=362739&PostID=13979561&idWriter=0&key=0
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/196200#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 May 2008 17:50:12 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/196200</link>
        <guid>http://cats-tiger.javaeye.com/blog/196200</guid>
      </item>
      <item>
        <title>别了Oracle——JS</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/189020" style="color:red;">http://cats-tiger.javaeye.com/blog/189020</a>&nbsp;
          发表时间: 2008年05月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          从Oracle7.3就用Oracle，那个时候用户自己买的正版Oracle所以基本上没有关心过它的版权问题。2004年，一个客户重要的应用中莫名其妙的丢失了几千行数据，用户毛了，要求Oracle派人来分析日志。但是人家Oracle根本不搭理，还说什么维护人员都出国学习了，什么从离开公司起每小时N美刀。客户急了，一个电话过去把Oracle骂了个狗血淋头，结果Oracle乖乖的来了。BTW，俺们这个客户很牛的。<br />打那起就没有再用过Oracle，一直是MySQL，偶而应客户需要用用SqlServer什么的。<br />最近接了一个项目，是作一个网站，客户很豪爽，要给几十万。一个并不复杂的网站给几十万，俺们再用Mysql就拿不出手了（其实MYSql挺合适，就是客户不认），于是选了Oracle。买的5用户版，俺们采购人员没有弄明白5用户是什么意思，还以为是指可以在5个机器上安装，结果一问才知道，是5个并发连接！多于5个人家就有追究你法律责任的权力！如果买无限用户的版本，光Oracle的价格就顶你真个项目了。<br />JS呀JS...
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/189020#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>Sat, 03 May 2008 10:34:04 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/189020</link>
        <guid>http://cats-tiger.javaeye.com/blog/189020</guid>
      </item>
      <item>
        <title>让ecside2离开prototype.js</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/181714" style="color:red;">http://cats-tiger.javaeye.com/blog/181714</a>&nbsp;
          发表时间: 2008年04月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          虽然fins老大不再维护Ecside，但是俺一直在用着它呀，所以只好自己动手丰衣足食了。Ecside一个不爽的地方是依赖prototype.js，而且（好像）只用到了它的ajax。俺们的项目中底层js框架用的是jquery，而且即便不用jquery，仅仅为了一个ajax而引进50k的prototype.js也是非常不值得的。所以自己修改了一下ecside.js文件：<br /><pre name="code" class="javascript">
//找到Me.ajaxSubmit = function(resfunc, asy, parameter) 函数，注释掉
//Form.request方法的调用，改为:
jQuery.ajax({
        	type: 'POST',
            url: Me.ECForm.action,
            data: jQuery(Me.ECForm).serialize(),
            beforeSend: ECSideUtil.setRequestHeaders,
            async: asy,
            complete: resfunc
        });
//找到ECSideUtil.doAjaxUpdate = function(url, pars, callBack, formid)函数，注释掉
//var myAjax = new Ajax.Request(url, {...，改为：
jQuery.ajax({
        	type: 'POST',
            url: url,
            data: pars,
            beforeSend: ECSideUtil.setRequestHeaders,
            async: true,
            complete: callBack
        });
//为EcSideUtil添加一个函数（从prototype中摘出来的）：
ECSideUtil.setRequestHeaders = function(xhr, extras) {
	var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] &lt; 2005)
            headers['Connection'] = 'close';
    }
     
    for (var i = 0, length = ECSideConstants.AJAX_HEADER.length; i &lt; length; i += 2)
        headers[ECSideConstants.AJAX_HEADER[i]] = ECSideConstants.AJAX_HEADER[i+1];
     
};
</pre><br />OK，搞定。如果不想用jquery，可以使用任何js框架，比如用ExtJS，也可以自己写一个Ajax提交的方法。最后的那个setRequestHeaders可以不要的，有很多方法设置header...<br />BTW:怎么觉得这个文章俺好像写过一次了，汗...
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/181714#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>Fri, 11 Apr 2008 12:14:21 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/181714</link>
        <guid>http://cats-tiger.javaeye.com/blog/181714</guid>
      </item>
      <item>
        <title>SpringSide怎么了？</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/178292" style="color:red;">http://cats-tiger.javaeye.com/blog/178292</a>&nbsp;
          发表时间: 2008年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天上SpringSide，发现已经不能访问了，不知道是维护还是怎么了？SpingSide是我非常喜欢的一个开源项目，从1.0就开始看，我们现在的框架都是参考SpringSide的。但是，自从2.0RC1之后，SpringSide就停止发展了，白衣计划3月份推出SpringSide 3的第一个发布版本，但是愚人节已经到了...<br />并不是埋怨作者们，我还没有这个资格，因为我没有参与过。毕竟开源项目不是只靠热情就可以的。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/178292#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>Tue, 01 Apr 2008 09:32:12 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/178292</link>
        <guid>http://cats-tiger.javaeye.com/blog/178292</guid>
      </item>
      <item>
        <title>[转]金额数字转中文大写</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/176033" style="color:red;">http://cats-tiger.javaeye.com/blog/176033</a>&nbsp;
          发表时间: 2008年03月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文：http://www.blogjava.net/fastunit/archive/2008/03/25/188537.html<br />处理能力：<br />整数部分：9999999999999999(16位长，仟万亿)<br />小数部分：3位，多于3位舍去(不做四舍五入)<br /><br />运行结果：<br />1.23 壹元贰角叁分<br />1234567890123456.123 壹仟贰佰叁拾肆万伍仟陆佰柒拾捌亿玖仟零壹拾贰万叁仟肆佰伍拾陆元壹角贰分叁厘<br />0.0798 柒分玖厘<br />10,001,000.09 壹仟万零壹仟元玖分<br />01.107700 壹元壹角柒厘<br /><pre name="code" class="java">
public class MoneyUtil {

  /** 大写数字 */
  private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
      "柒", "捌", "玖" };
  /** 整数部分的单位 */
  private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰",
      "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" };
  /** 小数部分的单位 */
  private static final String[] DUNIT = { "角", "分", "厘" };

  /**
   * 得到大写金额。
   */
  public static String toChinese(String str) {
    str = str.replaceAll(",", "");// 去掉","
    String integerStr;// 整数部分数字
    String decimalStr;// 小数部分数字

    // 初始化：分离整数部分和小数部分
    if (str.indexOf(".") > 0) {
      integerStr = str.substring(0, str.indexOf("."));
      decimalStr = str.substring(str.indexOf(".") + 1);
    } else if (str.indexOf(".") == 0) {
      integerStr = "";
      decimalStr = str.substring(1);
    } else {
      integerStr = str;
      decimalStr = "";
    }
    // integerStr去掉首0，不必去掉decimalStr的尾0(超出部分舍去)
    if (!integerStr.equals("")) {
      integerStr = Long.toString(Long.parseLong(integerStr));
      if (integerStr.equals("0")) {
        integerStr = "";
      }
    }
    // overflow超出处理能力，直接返回
    if (integerStr.length() > IUNIT.length) {
      System.out.println(str + ":超出处理能力");
      return str;
    }

    int[] integers = toArray(integerStr);// 整数部分数字
    boolean isMust5 = isMust5(integerStr);// 设置万单位
    int[] decimals = toArray(decimalStr);// 小数部分数字
    return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals);
  }

  /**
   * 整数部分和小数部分转换为数组，从高位至低位
   */
  private static int[] toArray(String number) {
    int[] array = new int[number.length()];
    for (int i = 0; i &lt; number.length(); i++) {
      array[i] = Integer.parseInt(number.substring(i, i + 1));
    }
    return array;
  }

  /**
   * 得到中文金额的整数部分。
   */
  private static String getChineseInteger(int[] integers, boolean isMust5) {
    StringBuffer chineseInteger = new StringBuffer("");
    int length = integers.length;
    for (int i = 0; i &lt; length; i++) {
      // 0出现在关键位置：1234(万)5678(亿)9012(万)3456(元)
      // 特殊情况：10(拾元、壹拾元、壹拾万元、拾万元)
      String key = "";
      if (integers[i] == 0) {
        if ((length - i) == 13)// 万(亿)(必填)
          key = IUNIT[4];
        else if ((length - i) == 9)// 亿(必填)
          key = IUNIT[8];
        else if ((length - i) == 5 && isMust5)// 万(不必填)
          key = IUNIT[4];
        else if ((length - i) == 1)// 元(必填)
          key = IUNIT[0];
        // 0遇非0时补零，不包含最后一位
        if ((length - i) > 1 && integers[i + 1] != 0)
          key += NUMBERS[0];
      }
      chineseInteger.append(integers[i] == 0 ? key
          : (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
    }
    return chineseInteger.toString();
  }

  /**
   * 得到中文金额的小数部分。
   */
  private static String getChineseDecimal(int[] decimals) {
    StringBuffer chineseDecimal = new StringBuffer("");
    for (int i = 0; i &lt; decimals.length; i++) {
      // 舍去3位小数之后的
      if (i == 3)
        break;
      chineseDecimal.append(decimals[i] == 0 ? ""
          : (NUMBERS[decimals[i]] + DUNIT[i]));
    }
    return chineseDecimal.toString();
  }

  /**
   * 判断第5位数字的单位"万"是否应加。
   */
  private static boolean isMust5(String integerStr) {
    int length = integerStr.length();
    if (length > 4) {
      String subInteger = "";
      if (length > 8 ) {
        // 取得从低位数，第5到第8位的字串
        subInteger = integerStr.substring(length - 8, length - 4);
      } else {
        subInteger = integerStr.substring(0, length - 4);
      }
      return Integer.parseInt(subInteger) > 0;
    } else {
      return false;
    }
  }

  public static void main(String[] args) {
    String number = "1.23";
    System.out.println(number + " " + MoneyUtil.toChinese(number));
    number = "1234567890123456.123";
    System.out.println(number + " " + MoneyUtil.toChinese(number));
    number = "0.0798";
    System.out.println(number + " " + MoneyUtil.toChinese(number));
    number = "10,001,000.09";
    System.out.println(number + " " + MoneyUtil.toChinese(number));
    number = "01.107700";
    System.out.println(number + " " + MoneyUtil.toChinese(number));
  }

}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/176033#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>Tue, 25 Mar 2008 20:55:03 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/176033</link>
        <guid>http://cats-tiger.javaeye.com/blog/176033</guid>
      </item>
      <item>
        <title>SlashesInActionNames不工作了，难道是struts2的BUG？</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/173408" style="color:red;">http://cats-tiger.javaeye.com/blog/173408</a>&nbsp;
          发表时间: 2008年03月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          strtus2更新为2.0.11.1,发现SlashesInActionNames不起作用了，也就是说我无法使用下面那样的简化配置：<br /><pre name="code" class="xml">
&lt;package name="admin.security" extends="default"
	         namespace="/security">
	    &lt;default-interceptor-ref name="paramsPrepareParamsStack" />
		&lt;action name="*/*" class="{1}Action" method="{2}">
		    &lt;result name="index">/pages/admin/security/{1}/index.jsp&lt;/result>
		    &lt;result name="input">/pages/admin/security/{1}/edit.jsp&lt;/result>
		    &lt;result name="success" type="redirect">{1}/index.do&lt;/result>
		&lt;/action>		
&lt;/package>
</pre><br />检查了所有可能发生错误的位置，没有找到问题，于是跟踪DefaultActionMapper的代码。发现alwaysSelectFullNamespace为true，这个变量我从未动过，它是定义在default.properties中的，并且缺省值是false。于是在struts.xml中重新定义这个值：<br /><pre name="code" class="xml">
&lt;constant name="struts.enable.DynamicMethodInvocation" value="false">&lt;/constant>
	&lt;constant name="struts.enable.SlashesInActionNames" value="true">&lt;/constant>
	&lt;constant name="struts.mapper.alwaysSelectFullNamespace" value="false">&lt;/constant>
	&lt;constant name="struts.mapper.class" value="org.apache.struts2.dispatcher.mapper.DefaultActionMapper">&lt;/constant>
</pre><br />问题解决。<br />但是为什么会这样呢？难道是struts2的BUG？<br />如果真是这样，我也许会用SpringMVC之类的框架了，本来就觉得struts2不太好用。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/173408#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 18 Mar 2008 15:12:31 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/173408</link>
        <guid>http://cats-tiger.javaeye.com/blog/173408</guid>
      </item>
      <item>
        <title>终于发现struts2 Annotation的用处了——验证</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/173295" style="color:red;">http://cats-tiger.javaeye.com/blog/173295</a>&nbsp;
          发表时间: 2008年03月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          struts2提供了annotation来代替配置文件，并且说:"It is great start."。我试用了Annoation风格的Action配置，感觉并不是很好用，尤其在比较复杂的Action中，反而不如XML直观明了。甚至，我不喜欢使用带有{}的简化配置，还是传统的方式更加一目了然。尤其是配置配置Action的时候需要在web.xml中注明packages，简直是...<br />今天终于找到了Struts2 Annotation的用途——验证。<br />下面代码是在一个Action中使用CRUD、ModelDriven的情况下利用Annotation验证的方式，Action使用了springside风格，父类提供了基本的CRUD能力：<br /><br /><pre name="code" class="java">
//这是父类代码
@SuppressWarnings( { "serial", "unchecked" })
public abstract class AbstractCrudAction&lt;T, M extends Manager>
    extends BaseAction implements Preparable, ModelDriven {
  /**
   * 定义显示单个实体的页面
   */
  public static final String VIEW = "view";

  /**
   * 定义显示实体列表的页面
   */
  public static final String INDEX = "index";

  /**
   * Action所使用的Manager类
   */
  private M manager;

  /**
   * Action所管理的Entity
   */
  private T model;

  /**
   * Action所管理的实体的类型
   */
  private Class entityClass;
  
   /**
   * 用于保存查询结果。
   */
  protected Collection&lt;T> items;

  /**
   * 用于对应页面上CheckBox，List等组件的选择值.
   */
  protected Serializable[] selectedItems;

  /**
   * 用于保存分页查询结果
   */
  private Page page;

  /**
   * 创建一个新的实体，如果成功，返回index页面，如果失败，返回输入页面.
   */
  public String create() {
    //代码略
  }

  /**
   * &lt;B>创建或更新&lt;/B>一个实体，如果成功，返回index页面，如果失败，返回输入页面.
   *  &lt;code>save()&lt;/code>相当于调用{@link create()}和{@link update()}，
   * 为了简化jsp编码，可以将新建和编辑页面合二为一，此时，&lt;code>save()&lt;/code>方法.
   * 
   */
  public String save() {
    //代码略
  }

  /**
   * @see {@link #save()}
   */
  public String update() {
    return SUCCESS;
  }

  /**
   * 列出实体
   */
  @SkipValidation
  public String index() {
     //代码略
  }

  /**
   * 根据&lt;code>Id&lt;/code>查询单个&lt;code>model&lt;/code>并定向到显示它的页面.
   */
  @SkipValidation
  public String view() {
    return VIEW;
  }

  /**
   * 重定向到编辑页面。为了简化页面编程，将新建和编辑和为一个页面。
   */
  @SkipValidation
  public String edit() {
    return INPUT;
  }

  /**
   * 重定向到新建页面。为了简化页面编程，将新建和编辑和为一个页面。
   */
  @SkipValidation
  public String editNew() {
    return INPUT;
  }

  /**
   * 如果&lt;code>id != null&lt;/code>,则删除ID所代表的Entity， 否则，如果&lt;code>selectedItems.length > 0&lt;/code>则删除
   * &lt;code>selectedItems&lt;/code>所代表的所有Entities.
   * @return
   */
  @SkipValidation
  public String remove() {
    //代码略
  }

  // Method from Preparable
  /**
   * @see com.opensymphony.xwork2.Preparable#prepare()
   */
  public void prepare() {
    if (model == null || extractId(model) == null) {
      model = (T) ReflectUtil.newInstance(getEntityClass());
    } else {
      model = (T) manager.get(extractId(model));
    }
  }
  
  /**
   * 从{@link #model}中取得ID
   * @param model 给定Model
   * @return 实体对象的ID值
   */
  protected abstract Serializable extractId(T model);
  /**
   * 将{@link #id}转换为实际的类型，子类必须根据持久化标识的类型实现，例如:&lt;br>
   * &lt;pre>
   * protected Serializable convertId(Serializable id) {
   *     return (id == nul) ? null : Integer.valueOf(id.toString());
   * }
   * &lt;/pre> 
   */
  protected abstract Serializable convertId(Serializable id);
  

  // Protected methods

  protected Class getEntityClass() {
    if (entityClass == null) {
      entityClass = GenericsUtil.getGenericClass(getClass(), 0);
    }
    return entityClass;
  }

  
  //Method from ModelDriven
  /**
   * @see com.opensymphony.xwork2.ModelDriven#getModel()
   */
  public T getModel() {
    if(model == null) {
      model = (T) ReflectUtil.newInstance(getEntityClass());
    }
    return model;
  }

  // Getters and setters.
  public void setModel(T model) {
    this.model = model;
  }
  
  public void setManager(M manager) {
    this.manager = manager;
  }
  
  protected M getManager() {
    return manager;
  }
  
  public Collection&lt;T> getItems() {
    return items;
  }

  public Serializable[] getSelectedItems() {
    return selectedItems;
  }
  
  public void setSelectedItems(Serializable[] selectedItems) {
    this.selectedItems = selectedItems;
  }


  public Page getPage() {
    return page;
  }
}
</pre><br />这是子类的代码：<br /><pre name="code" class="java">
//少了中间的DefaultCrudAction
@Validation
public class DeptAction extends DefaultCrudAction&lt;Dept, DeptManager> {
  /**
   * 当前上级部门ID
   */
  private Integer parentId;

  /**
   * 部门序列号管理器
   */
  private DeptSerialNoManager serialNoManager;

  /**
   * 用于查询的部门名称
   */
  private String deptName = StringUtils.EMPTY;

 
  @Override
  @SkipValidation
  public String index() {
    
    return INDEX;
  }


  @Override
  @Validations(requiredStrings = { @RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "model.name", message = "部门名称是必须的.")})
  public String save() {
    
  }

  /**
   * 处理parentDept为null的情况
   */
  @Override
  @SkipValidation
  public String edit() {
    
  }

  /**
   * 重置所有部门编号
   */
  @SkipValidation
  public String updateSerialNo() {
    serialNoManager.updateAllSerialNo();
    return SUCCESS;
  }

  public DeptSerialNoManager getSerialNoManager() {
    return serialNoManager;
  }

  public void setSerialNoManager(DeptSerialNoManager serialNoManager) {
    this.serialNoManager = serialNoManager;
  }
}

</pre><br />这是Struts的配置文件<br /><pre name="code" class="xml">
&lt;package name="admin.dept" extends="struts-default" namespace="/admin/dept">
		 &lt;action name="index" class="deptAction" method="index">
		     &lt;result name="index" type="dispatcher">/pages/admin/dept/index.jsp&lt;/result>
		 &lt;/action>
		 &lt;action name="editNew" class="deptAction" method="editNew">
		     &lt;result name="input">/pages/admin/dept/edit.jsp&lt;/result>
		 &lt;/action>
		 &lt;action name="edit" class="deptAction" method="edit">
		     &lt;result name="input">/pages/admin/dept/edit.jsp&lt;/result>
		 &lt;/action>
		 &lt;action name="remove" class="deptAction" method="remove">
		     &lt;result name="success" type="redirect">index.do&lt;/result>
		 &lt;/action>
		 &lt;action name="save" class="deptAction" method="save">
		     &lt;result name="success" type="redirect">index.do&lt;/result>
		     &lt;result name="input">/pages/admin/dept/edit.jsp&lt;/result>
		 &lt;/action>
		 &lt;action name="updateDeptSerialNo" class="deptAction" method="updateSerialNo">
		     &lt;result name="success" type="redirect">index.do&lt;/result>
		 &lt;/action>
	&lt;/package>
&lt;!--如果使用{},这个配置文件会更简单一些.-->
</pre><br />说明一下：<br />1.不必在web.xml的添加任何代码，struts会自动根据Annotation进行验证。<br />2.在<strong>不</strong>需要验证的方法前加@SkipValidation，如果你采用了SpringSide风格的Action，那么在父类的方法前加@SkipValidation即可。但是如果子类覆盖了父类的方法，子类方法前也需要用@SkipValidation标注。感觉Struts2好像弄反了，实际应用中，需要验证的方法要少于不需要验证的方法，如果缺省的方法都不验证，只有标注了@Validations的方法验证就更好了。<br />3.一直感觉struts2 的XML验证方式比较难以维护，Annotation的使用解决了这个问题。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/173295#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>Tue, 18 Mar 2008 11:08:40 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/173295</link>
        <guid>http://cats-tiger.javaeye.com/blog/173295</guid>
      </item>
      <item>
        <title>扩展Dojo 1.0——完整版</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/160169" style="color:red;">http://cats-tiger.javaeye.com/blog/160169</a>&nbsp;
          发表时间: 2008年01月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          以前贴过扩展Dojo的几个Wedgets，今天把完整的代码上传上来。主要Features包括：<br /><ul><li>一个简单的不能再简单的Grid，支持列排序，但是不支持调整列宽。</li><li>一个简单的不能再简单的分页Widget，可以和Grid结合使用</li><li>美化了原版dojo floating pane.</li><li>支持Resizing的模式Dialog</li><li>Tree Widget，以及Tree Select(Tree ComboBox)</li><li>重写了ArrayList</li><li>一些帮助函数</li><li>完整的示例代码</li></ul><br />把Jsam放在Dojo目录下，与dojox等平级即可。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/160169#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 29 Jan 2008 17:05:06 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/160169</link>
        <guid>http://cats-tiger.javaeye.com/blog/160169</guid>
      </item>
      <item>
        <title>Struts2 + ECSide解决“查询-&gt;更新-&gt;回到原查询状态”的问题</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/148354" style="color:red;">http://cats-tiger.javaeye.com/blog/148354</a>&nbsp;
          发表时间: 2007年12月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          经常有这样的情况：用户千辛万苦的查询数据，并且翻页呀翻页的找到一条，然后修改它，保存成功以后，查询结果和页数都不见了！下次修改不得不重复上述操作。<br />使用Struts2的Chain Result可以实现多个Action的连续执行，但是，上述场景中需要跨越两次以上的Requests，很多parameters都无法保留，入下图：<br />查询＝>分页＝>编辑(查询参数和分页参数丢失)＝>保存＝>查询(没有参数的查询)<br />解决的办法是保留parameters，可以写一个taglib来实现这个目的：<br /><pre name="code" class="java">
public class ParametersTag extends BodyTagSupport {
  private static Log log = LogFactory.getLog(ParametersTag.class);
  /** 输出为input tag */
  public static final String TYPE_INPUT_TAG = "inputTag";
  /** 输出为query string */
  public static final String TYPE_QUERY_STRING = "queryString";
  
  /**
   * 指定包含的parameters，如果没有指定，则包含全部。可以使用*、?作为通配符。
   */
  private String includes;
  /**
   * @see #TYPE_INPUT_TAG
   * @see #TYPE_QUERY_STRING
   */
  private String type;

  /**
   * @see javax.servlet.jsp.tagext.BodyTagSupport#release()
   */
  @Override
  public void release() {
    includes = null;
    type = null;
    super.release();
  }

  /**
   * @see javax.servlet.jsp.tagext.BodyTagSupport#doEndTag()
   */
  @Override
  public int doEndTag() throws JspException {    
    Enumeration&lt;String> keys = pageContext.getRequest().getParameterNames();
    String str = "";    
    if(StringUtils.isBlank(type) || StringUtils.equals(TYPE_INPUT_TAG, type)) {
      log.debug("Build Input Tags.");
      str = buildInputTags(keys);
    } else {
      log.debug("Build query string.");
      str = buildQueryString(keys);
    }
    try {
      pageContext.getOut().write(str);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return BodyTagSupport.EVAL_PAGE;
  }
  
  /**
   * 根据参数构造queryString
   * @param keys 参数名称
   */
  private String buildQueryString(Enumeration&lt;String> keys) {
    StringBuffer buf = new StringBuffer();
    while(keys.hasMoreElements()) {
      String key = keys.nextElement();
      String value = pageContext.getRequest().getParameter(key);
      if(StringUtils.isBlank(value)) {
        continue;
      }
      buf.append(key)
      .append("=")
      .append(value);
      if(keys.hasMoreElements()) {
        buf.append("&");
      }
    }
    return buf.toString();
  }

  /**
   * 根据参数构造Input
   * @param keys 参数名称
   */
  private String buildInputTags(Enumeration&lt;String> keys) {
    StringBuffer buf = new StringBuffer();
    while(keys.hasMoreElements()) {
      String key = keys.nextElement();
      if(!isInclude(key)) {
        continue;
      }
      String value = pageContext.getRequest().getParameter(key);
      buf.append("&lt;input type='hidden' name='")
      .append(key) 
      .append("' value='")
      .append((value == null) ? StringUtils.EMPTY : value)
      .append("'/>");
    }
    
    return buf.toString();
  }
  
  /**
   * 判断某个参数是否可以包含。
   */
  private boolean isInclude(String target) {
    if(StringUtils.isBlank(includes)) {
      return true;
    }
    PathMatcher matcher = new AntPathMatcher();
    Set&lt;String> incs = StringUtil.parseCommaSplitedString(includes);
    for(String inc : incs) {
      if(matcher.match(inc, target)) {
        return true;
      }
    }
    
    return false;
  }
  
  
  /**
   * @return the includes
   */
  public String getIncludes() {
    return includes;
  }

  /**
   * @param includes the includes to set
   */
  public void setIncludes(String includes) {
    this.includes = includes;
  }

  /**
   * @return the type
   */
  public String getType() {
    return type;
  }

  /**
   * @param type the type to set
   */
  public void setType(String type) {
    this.type = type;
  }
}
</pre><br />jsp页面中这样使用：<br /><pre name="code" class="xml">
&lt;s:form theme="simple" action="create" id="saveForm">
	&lt;jsam:params includes="ec*,query*" type="inputTag">&lt;/jsam:params>
&lt;/s:form>
</pre><br />或者：<br /><pre name="code" class="xml">
  &lt;a href='edit.do?id=${item.id}&&lt;jsam:params includes="ec*,query*" type="queryString"/>'>edit&lt;/a>
</pre><br />在Struts2的配置文件中和chain一起使用：<br /><pre name="code" class="xml">
  &lt;action name="preStorageQuery" class="preStorageAction" method="pageQuery">
	&lt;interceptor-ref name="chain">&lt;/interceptor-ref>
        &lt;interceptor-ref name="basicStack"/>
	    &lt;result name="success">list.jsp&lt;/result>
  &lt;/action>
  &lt;!-- 使用chain，可以回到原来的查询状态 -->
  &lt;action name="save" class="preStorageAction" method="save">		   
	&lt;result name="success" type="chain">		    
	    &lt;param name="actionName">preStorageQuery&lt;/param>
	    &lt;param name="method">pageQuery&lt;/param>
	    &lt;param name="namespace">/admin/drugstorage/pre&lt;/param>
	 &lt;/result>		   
	 &lt;result name="input">list.jsp&lt;/result>
	 &lt;interceptor-ref name="params" />
	 &lt;interceptor-ref name="model-driven" />
         &lt;interceptor-ref name="validationWorkflowStack" />
  &lt;/action>
</pre><br />上面的代码中省略了.tld中的内容，而且taglib只有includes属性，没有excludes属性。<br />使用taglib应该算是比较丑陋的做法，但是一时也想不到更好的方法，Ajax当然可以解决，可是我这个项目是改造遗留系统，总不能都改成Ajax的。其实这个taglib用起来还算方便，各位如果有更好的办法请多赐教，这篇博文权当抛砖。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/148354#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, 14 Dec 2007 15:00:57 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/148354</link>
        <guid>http://cats-tiger.javaeye.com/blog/148354</guid>
      </item>
      <item>
        <title>Hibernate 隐含关联（implicit joins）的变化</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/146106" style="color:red;">http://cats-tiger.javaeye.com/blog/146106</a>&nbsp;
          发表时间: 2007年12月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前一个关于这个问题的帖子被隐藏了，这次说明确些。<br />例如有两个类，员工TestEmployee 和部门TestDept，它们是ManyToOne关系：<br /><pre name="code" class="java">
@Entity
@Table(name = "test_employees", uniqueConstraints = { })
public class TestEmployee extends BaseModel implements Serializable {
  private Integer id;
  private TestDept dept;

  @Id
  @GeneratedValue(generator = "hilo")
  @GenericGenerator(name = "hilo", strategy = "hilo")
  @Column(name = "ID", unique = true, nullable = false)
  public Integer getId() {
    return this.id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  @ManyToOne(cascade = { }, fetch = FetchType.LAZY)
  @JoinColumn(name = "dept_id")
  public TestDept getDept() {
    return this.dept;
  }

  public void setDept(TestDept dept) {
    this.dept = dept;
  }
}
@Entity
@Table(name = "test_depts", uniqueConstraints = { })
public class TestDept extends BaseModel implements Serializable {
  
  private Integer id;
  private String name;
  private Set&lt;TestEmployee> employees = new HashSet&lt;TestEmployee>(0);

  @Id
  @GeneratedValue(generator = "hibseq")
  @GenericGenerator(name = "hibseq", strategy = "hilo")
  @Column(name = "ID", unique = true, nullable = false)
  public Integer getId() {
    return this.id;
  }

  public void setId(Integer id) {
    this.id = id;
  }


  @Column(name = "name")
  public String getName() {
    return this.name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @OneToMany(cascade = { }, fetch = FetchType.LAZY, mappedBy = "dept")
  public Set&lt;TestEmployee> getEmployees() {
    return this.employees;
  }

  public void setEmployees(Set&lt;TestEmployee> employees) {
    this.employees = employees;
  }
}
</pre><br />现在我要查询员工A所在的部门，使用隐含关联：<br /><pre name="code" class="java">
getHibernateTemplate().find(
        "from TestDept d where d.employees.name = 'A'");
</pre><br />如果使用Hibernate3.2.3以后的版本，会出现一个异常illegal attempt to dereference collection。这个问题比较容易解决，只需要明确的关联上employees即可：<br /><pre name="code" class="java">
getHibernateTemplate().find(
        "from TestDept d inner join d.employees e where e.name = 'A'");
</pre><br />可是，如果使用Hibernate3.2.2，即使使用隐含关联也不会有问题。我的问题是：现在升级为Hibernate3.2.5，以前的代码怎么办？这是Hibernate的Bug吗？<br />从Hibnerate的Jira上终于得到了答案：<br />对于implicit joins，Hibernate3.2.2会自动生成inner join，这样，被关联对象如果为null，就不会查出任何结果。这使得隐含关联更具确定性（原文：This makes implicit joins more deterministic. ）。<br />Hibernate3.2.2之后如果隐含关联的是一个Collection，那么Hibernate就会抛出那个异常。这会提醒用户，使用更加明确的关联。<br />终于弄清问题所在了，可是以前的代码都得改，JUnit测出了40多个Bugs，郁闷呀！
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/146106#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 05 Dec 2007 10:03:22 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/146106</link>
        <guid>http://cats-tiger.javaeye.com/blog/146106</guid>
      </item>
      <item>
        <title>Hibernate再次紧急求助</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/145926" style="color:red;">http://cats-tiger.javaeye.com/blog/145926</a>&nbsp;
          发表时间: 2007年12月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          现在有两个Domain类，User和Dept，是ManyToOne关系，我查询某个Dept中所有的Users。<br />Hibernate3.2.2之前，我可以这样写：from User u where u.dept.name=?,根据u.dept.name，Hibernate可以自动关联Dept。<br />使用Hibernate3.2.5之后，出现“illegal attempt to dereference collection”异常。将SQL改为from User u join u.dept d where d.name=?即可。但是这样我不但要修改很多以前的代码，而且HQL也变得冗长。<br />我现在已经退回使用3.2.2了，都不知道Hibernate是否还继续升级。最可怕的是，Hibenrate已经发现了这个Issue：<br />http://opensource.atlassian.com/projects/hibernate/browse/HHH-2667;jsessionid=agpgVonKic_6nRkp6m<br />但是却没有fix！<br />对Hibernate没有信心了，我是否该使用IBatis？请问各位如何解决这个问题的？
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/145926#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Dec 2007 17:02:44 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/145926</link>
        <guid>http://cats-tiger.javaeye.com/blog/145926</guid>
      </item>
      <item>
        <title>Windows下Apache2.2 + Tomcat5.5 + Apr配置备忘录</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/135782" style="color:red;">http://cats-tiger.javaeye.com/blog/135782</a>&nbsp;
          发表时间: 2007年10月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          首先从apache下载最新的Apache源代码，然后安装Visual C++6.0。打开VC，打开Apache.dsw文件。从菜单中选择Build&gt;Set Active Configuration，选择一个Release，我选的是Install Bin Win32 Release，然后开始编译。此时会出现3个错误：<br />
error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.<br />
找到apr_ldap.h，将这个error的宏定义删除，然后找到apr_ldap_init.h，找到183行（LDAP_VENDOR_NAME），将它也注释掉。<br />
将附件awk.zip中的exe和dll复制到VC98\bin目录下，然后再编译就可以了。此时会生成一个Apache22的目录，这就是你的Apache了。很奇怪，我在apache上找不到它的bin下载。<br />
上述过程参考自：http://download.csdn.net/source/218091<br />
<br />
编辑apache下的httpd.conf：<br />
<br />
<br />
&nbsp;&nbsp; 1. AddDefaultCharset UTF-8 &nbsp;<br />
&nbsp;&nbsp; 2. Listen 80 &nbsp;<br />
&nbsp;&nbsp; 3. ServerName 192.168.1.59:80 &nbsp;<br />
&nbsp;&nbsp; 4. #IP自己换 &nbsp;<br />
&nbsp;&nbsp; 5. ProxyPass / ajp://192.168.1.59:8009/ &nbsp;<br />
&nbsp;&nbsp; 6.&nbsp; &nbsp;<br />
&nbsp;&nbsp; 7. LoadModule proxy_module modules/mod_proxy.so &nbsp;<br />
&nbsp;&nbsp; 8. LoadModule proxy_ajp_module modules/mod_proxy_ajp.so &nbsp;<br />
&nbsp;&nbsp; 9. LoadModule proxy_balancer_module modules/mod_proxy_balancer.so &nbsp;<br />
&nbsp; 10. LoadModule proxy_connect_module modules/mod_proxy_connect.so &nbsp;<br />
&nbsp; 11. LoadModule proxy_http_module modules/mod_proxy_http.so &nbsp;<br />
&nbsp; 12. LoadModule imagemap_module modules/mod_imagemap.so &nbsp;<br />
&nbsp; 13. LoadModule include_module modules/mod_include.so &nbsp;<br />
&nbsp; 14. LoadModule isapi_module modules/mod_isapi.so &nbsp;<br />
&nbsp; 15. LoadModule log_config_module modules/mod_log_config.so &nbsp;<br />
&nbsp; 16. LoadModule mime_module modules/mod_mime.so &nbsp;<br />
&nbsp; 17. LoadModule negotiation_module modules/mod_negotiation.so &nbsp;<br />
&nbsp; 18. LoadModule setenvif_module modules/mod_setenvif.so &nbsp;<br />
&nbsp; 19. LoadModule userdir_module modules/mod_userdir.so &nbsp;<br />
&nbsp; 20.&nbsp; &nbsp;<br />
&nbsp; 21. Include conf/extra/httpd-languages.conf &nbsp;<br />
&nbsp; 22.&nbsp; &nbsp;<br />
&nbsp; 23. ThreadsPerChild 250 &nbsp;<br />
&nbsp; 24. MaxRequestsPerChild&nbsp; 0 &nbsp;<br />
<br />
<br />
然后启动httpd.exe<br />
将附件tcnative-1.dll复制到CATALINA_HOME下的任意目录，我是将它放在apr下。打开catalina.bat，加入一行：<br />
set CATALINA_OPTS=&quot;-Djava.library.path=../apr&quot;<br />
<br />
然后启动startup.bat<br />
<br />
试试访问http://localhost/<br />
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/135782#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 26 Oct 2007 17:26:15 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/135782</link>
        <guid>http://cats-tiger.javaeye.com/blog/135782</guid>
      </item>
      <item>
        <title>推荐一个超强的日期js控件,My97</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/129709" style="color:red;">http://cats-tiger.javaeye.com/blog/129709</a>&nbsp;
          发表时间: 2007年10月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://blog.csdn.net/my97/">blog.csdn.net/my97/</a><br />
My97是我见过的最强的js calendar，个头不大但是支持的功能非常多，并且是国产的。<br />
强烈推荐。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/129709#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>Mon, 08 Oct 2007 14:11:19 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/129709</link>
        <guid>http://cats-tiger.javaeye.com/blog/129709</guid>
      </item>
      <item>
        <title>恐怖的TurboGrid Widgets！</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/125211" style="color:red;">http://cats-tiger.javaeye.com/blog/125211</a>&nbsp;
          发表时间: 2007年09月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          10月份dojo将推出1.0版本，其中包括一个Grid Widgets，了解了一下，居然是<a href="http://www.turboajax.com/index-turboajax.html">TurboGrid</a>，这个是收费的呀？而且价格超高。不过Turbo Grid的功能是我见过的最强的一个。看看例子吧。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/125211#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/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 19 Sep 2007 10:20:18 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/125211</link>
        <guid>http://cats-tiger.javaeye.com/blog/125211</guid>
      </item>
      <item>
        <title>在igoogle中使用GoogleCalendarViewer</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/124920" style="color:red;">http://cats-tiger.javaeye.com/blog/124920</a>&nbsp;
          发表时间: 2007年09月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><font size="-1"><font color="#cc0033">iGoogle</font> 就是性化的Google 网页。可以在自己的网页上添加资讯、照片、天气及网上的各种内容。Google Calendar是一个用于个人或组织时间管理的在线工具，这个工具可以通过Rss的方式共享。可以使用<font size="2" face="Arial">GoogleCalendarViewer将Calendar在iGoogle主页上显示，这样，每天打开fireFox，就可以看到当天或最近几天的日程了。</font></font></p>
<p><a href="http://www.javaeye.com/topics/download/50e21654-8354-48cd-919a-71307bfcc983"><img src="http://www.javaeye.com/topics/download/50e21654-8354-48cd-919a-71307bfcc983" height="317" alt="" style="WIDTH: 634px; HEIGHT: 326px" width="556" /></a></p>
<p><font size="2">首先要申请一个google账户，然后在<a href="http://www.google.com/calendar/">www.google.com/calendar/</a>上创建一个Calendar，选中创建的Calendar，进入日立管理页面。并复制&quot;私人网址&quot;中的XML网址。</font></p>
<p><font size="2">然后进入<a href="http://www.google.com/ig">www.google.com/ig</a>，选中&ldquo;添加内容&rdquo;，然后找到google calendar viewer，将她加入主页。这里最好是先预览再添加，我曾经用&ldquo;立即添加&rdquo;，但是没有成功。</font></p>
<p><font size="2">回到主页，点击Calendar Veiwer的编辑按钮，calendar feed输入刚才的私人网址。然后把ig设置成主页，这样每次打开浏览器就可以方便的查看日程了。</font></p>
<p><font size="2"></font></p>
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/124920#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 18 Sep 2007 11:03:43 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/124920</link>
        <guid>http://cats-tiger.javaeye.com/blog/124920</guid>
      </item>
      <item>
        <title>扩展Dojo 0.9之Grid</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/124660" style="color:red;">http://cats-tiger.javaeye.com/blog/124660</a>&nbsp;
          发表时间: 2007年09月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          grid是最常用的widget之一，ext和ecside都提供了超强的grid，<br />
dojo0.9中的grid功能弱化了许多（听说1.0要加强），由于等不及1.0的推出，所以自己做了一个grid。<br />
features：<br />
可以使用json的数据。<br />
<ul>
    <li>方便的定义css。</li>
    <li>排序。</li>
    <li>分页。</li>
    <li>行选择。</li>
</ul>
本来还要加入调整列宽，但是时间不够了。目前功能还比较简单，但是以后会加入更多features。<br />
例子在tests目录下，注意要把jsam目录放在和dojox、dijit等目录同级目录下才可以正常运行。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/124660#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 17 Sep 2007 10:26:57 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/124660</link>
        <guid>http://cats-tiger.javaeye.com/blog/124660</guid>
      </item>
      <item>
        <title>Web应用程序布署时遇到的奇怪问题</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/121599" style="color:red;">http://cats-tiger.javaeye.com/blog/121599</a>&nbsp;
          发表时间: 2007年09月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          目前正在做一个新的项目，采用和springside类似的架构，MVC框架用Struts2。开发环境使用Eclipse3.3 Europa + subclipse + springide-2.0。开发的时候web服务器采用tomcat5.5，生产环境中可能会使用JBoss或Weblogic等。本来打算使用 jetty作为开发用jsp容器的，但是eclipse3.3对jetty的支持不够，所以放弃了。<br />
但是eclipse3.3对tomcat的支持也非常凑合，经常在修改文件之后，tomcat中的内容不变必须重新启动才会有效果。如果修改的是class，那么还得重新布署，超麻烦。于是开始怀念使用jetty 的日子，那时候用bea workshop for jsp3.3(eclipse 3.2.2)，它对jetty的支持非常好。<br />
能不能在eclipse3.3下使用jetty呢，好办，写一个jetty的配置文件，然后在eclipse中加入jetty/lib下的3个jar文件和start.jar，然后运行org.mortbay.start.Main这个类就可以了www.javaeye.com/topic/1630有详细的说明（它是运行jetty.jar下的一个类）。配置完成后，开始运行。控制台输出的信息说明布署成功了，但是，奇怪的现象发生了，所有使用EL表达式的页面都报异常。为了查明原因，我用ant为web目录打了一个war包，布署到jetty/webapps下，运行java -jar start.jar启动jetty，还是不行。布署到jboss4.2下，丫的根本就不能编译带有EL表达式的页面。只有在tomcat5.5下可以正常运行。<br />
为了查明是项目本身的问题，还是开发环境的问题。我启动了bea workshop for jsp3.3（ws3.3），从svn重新下载项目，然后布署到jetty。KAO，居然成功了。用同样的ant任务打war包，分别布署到jboss和 tomcat、jetty下，都OK。<br />
我于是参考ws3.3的布署方式，在eclipse3.3中重新启动jetyy，问题依旧。<br />
最奇怪的是，我升级ws3.3到ws101，结果101下布署也不行，而且ws101的布署方式很BT，居然是布署war包到jetty下。怎么越升级越差劲了？<br />
<br />
最后总结一下：<br />
<br />
&nbsp;&nbsp; 1. 一个很正常的Web项目，在bea workshop for jsp3.3(build 608)下，布署或打包后布署，无论web server是什么，都OK。<br />
&nbsp;&nbsp; 2. 在Eclipse3.3 Europa下，布署到Tomcat5.5下OK，但是其他web server(主要测试了jetty和jboss)，都出现EL不能解析或不能编译的问题。<br />
&nbsp;&nbsp; 3. 在bea workshop for jsp10.1下，与Eclipse3.3 Europa的情况类似。但是报的异常不同。<br />
&nbsp;&nbsp; 4. 最奇怪的是，不同开发环境下执行同样的ant命令，打成的war包，ws3.3下打包可以成功布署，其他都失败。<br />
<br />
最后只能决定使用WS3.3，但是为什么会出现这些问题呢？
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/121599#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>Fri, 07 Sep 2007 11:38:04 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/121599</link>
        <guid>http://cats-tiger.javaeye.com/blog/121599</guid>
      </item>
      <item>
        <title>扩展Dojo 0.9之Paginator</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/120594" style="color:red;">http://cats-tiger.javaeye.com/blog/120594</a>&nbsp;
          发表时间: 2007年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          表格分页是十分常用的功能，ExtJs的分页做的非常Cool，但是，由于更欣赏dojo按需装载的机制和扩展性，所以决定在dojo0.9的基础上做一个Paginator widget。<br />
下面是截图，没有和table相结合的。<br />
<table cellspacing="1" border="1" align="" summary="" cellpadding="1" width="98%">
    <tbody>
        <tr>
            <td><img src="http://www.javaeye.com/topics/download/8558fad6-eb8e-4c12-839a-517be8e1eb79" alt="" /></td>
        </tr>
    </tbody>
</table>
<br />
这个widget在使用上是非常灵活的：<br />
1.告诉Paginator查询函数：<br />
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c" start="1">
    <li class="alt"><span><span class="keyword">var</span><span>&nbsp;paginator&nbsp;=&nbsp;dijit.byId('rolesPaginator');&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(paginator)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paginator.pagingFunction&nbsp;=&nbsp;<span class="keyword">function</span><span>(args)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserManager.queryRoles(UserManager.userId,&nbsp;args.pageNo);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
2.然后在查询函数中更新Paginator的参数：<br />
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c" start="1">
    <li class="alt"><span><span>UserManager.queryRoles&nbsp;=&nbsp;</span><span class="keyword">function</span><span>(userId,&nbsp;pageNo)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;UserRoleAction.getRolesOfUser(userId,&nbsp;pageNo,&nbsp;UserManager.pageSize,&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">function</span><span>(page)&nbsp;{&nbsp;</span><span class="comment">//Dwr&nbsp;will&nbsp;call&nbsp;this&nbsp;function&nbsp;when&nbsp;query&nbsp;roles&nbsp;successfully.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;paginator&nbsp;=&nbsp;dijit.byId('rolesPaginator');&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//refresh&nbsp;paginator.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(paginator)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paginator.setParams({&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageNo&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;page.pageNo,&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;totalCount:&nbsp;page.rows,&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pageSize&nbsp;&nbsp;:&nbsp;UserManager.pageSize&nbsp;});&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;</span></li>
    <li class=""><span>};&nbsp;&nbsp;</span></li>
</ol>
</div>
这样Paginator就可以工作了，你可以在查询函数中同时更新Table或其他显示查询结果的节点。<br />
Paginator的功能比较简单，但是，可以很轻易根据需要添加更多的功能。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/120594#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 05 Sep 2007 12:03:58 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/120594</link>
        <guid>http://cats-tiger.javaeye.com/blog/120594</guid>
      </item>
      <item>
        <title>Hibernate的一个bug，怎么还没有fix呀</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/119690" style="color:red;">http://cats-tiger.javaeye.com/blog/119690</a>&nbsp;
          发表时间: 2007年09月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2667;jsessionid=agpgVonKic_6nRkp6m">opensource.atlassian.com/projects/hibernate/browse/HHH-2667;jsessionid=agpgVonKic_6nRkp6m</a><br />
如果没有显式的join一个集合，则不能引用这个集合中的属性。<br />
比如&quot;from User u where u.roles.id=?&quot;是不行的，而&ldquo;select u from User u join u.roles r where r.id=?&rdquo;是可以的。但是，3.2.2以前的版本可以。现在升级到3.2.5ga，出现了&ldquo;Illegal attempt to reference collection&rdquo;的异常。<br />
在Hibernate的Issue上找到了这个Bug，已经close了，但是fix version是none，也就是说还没有修复。这样我就不能升级了呀。
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/119690#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Sep 2007 09:52:12 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/119690</link>
        <guid>http://cats-tiger.javaeye.com/blog/119690</guid>
      </item>
      <item>
        <title>扩展Dojo 0.9之Resizable Dialog</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/116186" style="color:red;">http://cats-tiger.javaeye.com/blog/116186</a>&nbsp;
          发表时间: 2007年08月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          虽然对dojo的诟病多多，但是我还是选择了Dojo，原因就是它的扩展性很好。我可以在它的基础之上编写高品质的js代码。Ext虽然cool毙，但是别说扩展，即使要修改它的css也是困难多多，再有就是它那480多k的js文件也让人头痛。dojo最新的0.9版本的体积比以前(150多k)小了很多(50k)，作者还声称性能也大大提高了，考虑到以前在dojo上的投入，本人决定仍然使用dojo。<br />
但是dojo0.9的向上兼容性很差，底层的API好像重写了。而且目录的结构也大为不同，唉，没办法谁让俺上了贼船了，改吧。<br />
对于Dojo的widgets，用的最多的是Dialog和FilteringTable，新版的这两个widget弱化了很多，尤其是FilteringTable。今天就先修改Dialog。<br />
dojo分为4个目录：<br />
dojo-是dojo的底层API<br />
dojox-扩展API，包括一些widget，比较有用的是FloatingPane。<br />
dijit-提供了一些widget，新版的dialog就在这个目录下，除了一般的Dialog功能外，还提供了ToolTipDialog，效果还是很cool的。BTW，dojo的作者是一个美工盲，做的例子毫无吸引力，难怪粉丝们都跑到Ext那边了。但是，新版的Dialog缺少了一个最重要的功能：resizable，好吧，就给他加上这个功能，顺便美化美化。其实dojo0.9有ResizeHandle这个widget，位于dojox.layout下，同一个包中的FloatingPane.js演示了如何使用ResizeHandle，把Dialog和FloatingPane结合一下就搞定了。<br />
首先在dojox目录下新建一个sam目录，作为扩展文件的目录。然后在Sam下新建一个Dialog.js文件：<br />
<div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-c" start="1">
    <li class="alt"><span><span class="keyword">if</span><span>(!dojo._hasResource[</span><span class="string">&quot;dojox.sam.Dialog&quot;</span><span>]){&nbsp;</span><span class="comment">//_hasResource&nbsp;checks&nbsp;added&nbsp;by&nbsp;build.&nbsp;Do&nbsp;not&nbsp;use&nbsp;_hasResource&nbsp;directly&nbsp;in&nbsp;your&nbsp;code.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>dojo._hasResource[<span class="string">&quot;dojox.sam.Dialog&quot;</span><span>]&nbsp;=&nbsp;</span><span class="keyword">true</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>dojo.provide(<span class="string">&quot;dojox.sam.Dialog&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>dojo.require(<span class="string">&quot;dojo.dnd.move&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>dojo.require(<span class="string">&quot;dojo.fx&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>dojo.require(<span class="string">&quot;dijit._Widget&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>dojo.require(<span class="string">&quot;dijit._Templated&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>dojo.require(<span class="string">&quot;dijit.Dialog&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>dojo.require(<span class="string">&quot;dijit.layout.ContentPane&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>dojo.require(<span class="string">&quot;dijit.form.Form&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>dojo.require(<span class="string">&quot;dojox.layout.ResizeHandle&quot;</span><span>);&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>dojo.declare(&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;dojox.sam.DialogUnderlay&quot;</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;[dijit.DialogUnderlay],&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>dojo.declare(&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;dojox.sam.Dialog&quot;</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;[dijit.Dialog,&nbsp;dijit._Templated,&nbsp;dijit.form._FormMixin],&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;SAM:&nbsp;add&nbsp;resizeHandle&nbsp;node.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;templateString:&nbsp;<span class="keyword">null</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;templateString:<span class="string">&quot;很长，看附件吧&quot;</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">//&nbsp;resizable:&nbsp;Boolean</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// allow&nbsp;resizing&nbsp;of&nbsp;pane&nbsp;true/false</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//SAM:add&nbsp;resizable&nbsp;property</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizable:&nbsp;<span class="keyword">false</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;resizeAxis:&nbsp;String</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;|&nbsp;xy&nbsp;|&nbsp;y&nbsp;to&nbsp;limit&nbsp;pane's&nbsp;sizing&nbsp;direction</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//SAM:add&nbsp;resizeAxis</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizeAxis:&nbsp;<span class="string">&quot;xy&quot;</span><span>,&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postCreate:&nbsp;<span class="keyword">function</span><span>(){&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dojox.sam.Dialog.superclass.postCreate.apply(<span class="keyword">this</span><span>,&nbsp;arguments);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//SAM:&nbsp;Display&nbsp;resizeHandle&nbsp;or&nbsp;not</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(!</span><span class="keyword">this</span><span>.resizable){&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.resizeHandle.style.display&nbsp;=&nbsp;</span><span class="string">&quot;none&quot;</span><span>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//SAM:override&nbsp;super's&nbsp;method,&nbsp;enable&nbsp;resize&nbsp;handle.</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startup:&nbsp;<span class="keyword">function</span><span>(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dojox.sam.Dialog.superclass.startup.call(<span class="keyword">this</span><span>);&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(</span><span class="keyword">this</span><span>.resizable)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.containerNode.style.overflow&nbsp;=&nbsp;</span><span class="string">&quot;auto&quot;</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">var</span><span>&nbsp;tmp&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;dojox.layout.ResizeHandle({&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//targetContainer:&nbsp;this.containerNode,&nbsp;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetId:&nbsp;<span class="keyword">this</span><span>.id,&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizeAxis:&nbsp;<span class="keyword">this</span><span>.resizeAxis&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<span class="keyword">this</span><span>.resizeHandle);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>});&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
这个Dialog.js继承了dijit.Dialog，所以只写了很少代码。<br />
下面是美化，在dojox/sam下建resources/images目录，用于存放dialog的化妆品。打开ff的Dom查看器(或者看<span>templateString</span>)，挨个找到所需的css的名字，然后自己建css，需要注意的是，dojo0.9中实现模式对话框的背景的css位于dijit/themes/dijit.css下，找了很久才找到。把这些css整合到一起，然后按着Ext的样子重写就OK了。<br />
呵呵，现在的dojo修改样式实在是简单多了，0.4以前css是写在js文件中的，修改起来那叫一个费尽，还要提防它升级。<br />
这样，我们就完成对Dialog的升级，效果可以看附件中的tests，记着把附件中的sam目录放到dojo的dojox目录下。<br />
下一次要做一个独立的Widget&mdash;&mdash;Paginator
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/116186#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 24 Aug 2007 15:57:38 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/116186</link>
        <guid>http://cats-tiger.javaeye.com/blog/116186</guid>
      </item>
      <item>
        <title>struts2文件上传</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://cats-tiger.javaeye.com/blog/110878" style="color:red;">http://cats-tiger.javaeye.com/blog/110878</a>&nbsp;
          发表时间: 2007年08月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.javaeye.com/topic/106139" target="_blank">http://www.javaeye.com/topic/106139</a>
          <br/>
          <span style="color:red;">
            <a href="http://cats-tiger.javaeye.com/blog/110878#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>Fri, 10 Aug 2007 14:57:44 +0800</pubDate>
        <link>http://cats-tiger.javaeye.com/blog/110878</link>
        <guid>http://cats-tiger.javaeye.com/blog/110878</guid>
      </item>
  </channel>
</rss>