<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>JBoss SEAM</title>
    <description>学习和研究JBoss SEAM框架的使用及其背后所依托的思想，欢迎感兴趣的朋友加入。</description>
    <link>http://seam.group.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>Hibernate Dialect for SqlServer2005</title>
        <author>cats_tiger</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://cats-tiger.javaeye.com">cats_tiger</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/218981" style="color:red;">http://seam.group.javaeye.com/group/blog/218981</a>&nbsp;
          发表时间: 2008年07月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Hibernate一直没有提供针对SqlServer2005的Dialect，原有的SqlServerDialect不支持物理分页查询。最近经常使用SqlServer2005，所以就很想写一个使用SqlServer2005 ROW_NUMBER()函数实现limit查询的Dialect类。<br />下面这个类是使用ROW_NUMBER()函数分页的Dialect，开始是从NHibernate移植的，后来又参考了Hibernate的Jira(<a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2655" target="_blank">http://opensource.atlassian.com/projects/hibernate/browse/HHH-2655</a>)。不知道为什，Jira上的那个有BUG类可以很简单的修改，但是却没人理会。所以我感觉下面这个类可能也存在问题，有兴趣的朋友帮忙测测。<br /><pre name="code" class="java">
public class SQLServer2005Dialect extends SQLServerDialect {
	public SQLServer2005Dialect() {
		super();

		registerColumnType(Types.VARCHAR, 1073741823, "NVARCHAR(MAX)");
		registerColumnType(Types.VARCHAR, 2147483647, "VARCHAR(MAX)");
		registerColumnType(Types.VARBINARY, 2147483647, "VARBINARY(MAX)");
	}
  /**
   * Add a LIMIT clause to the given SQL SELECT
   *
   * The LIMIT SQL will look like:
   *
   * WITH query AS
   * (SELECT TOP 100 percent ROW_NUMBER() OVER (ORDER BY orderby) as __hibernate_row_nr__, ... original_query)
   * SELECT *
   * FROM query
   * WHERE __hibernate_row_nr__ > offset AND __hibernate_row_nr__ &lt;= offset + limit
   * ORDER BY __hibernate_row_nr__
   *
   * @param querySqlString The SQL statement to base the limit query off of.
   * @param offset         Offset of the first row to be returned by the query (zero-based)
   * @param limit           Maximum number of rows to be returned by the query
   * @return A new SQL statement with the LIMIT clause applied.
   */
  public String getLimitString(String querySqlString, int offset, int limit) {
   
    StringBuffer pagingBuilder = new StringBuffer();
    String orderby = getOrderByPart(querySqlString);
    String distinctStr = "";

    String loweredString = querySqlString.toLowerCase();
    String sqlPartString = querySqlString;
    if (loweredString.trim().startsWith("select")) {
      int index = 6;
      if (loweredString.startsWith("select distinct")) {
        distinctStr = "DISTINCT ";
        index = 15;
      }
      sqlPartString = sqlPartString.substring(index);
    }
    pagingBuilder.append(sqlPartString);

    // if no ORDER BY is specified use fake ORDER BY field to avoid errors
    if (orderby == null || orderby.length() == 0) {
      orderby = "ORDER BY CURRENT_TIMESTAMP";
    }

    StringBuffer result = new StringBuffer();
    result.append("WITH query AS (SELECT ")
    .append(distinctStr)
    .append(" TOP 100 PERCENT ROW_NUMBER() OVER (") //使用TOP 100 PERCENT可以提高性能
    .append(orderby)
    .append(") AS __hibernate_row_nr__, ")
    .append(pagingBuilder)
    .append(") SELECT * FROM query WHERE __hibernate_row_nr__ >")
    .append(offset)
    .append(" AND __hibernate_row_nr__ &lt;=")
    .append(offset + limit)
    .append(" ORDER BY __hibernate_row_nr__");
    
    return result.toString();
  }

  public boolean supportsLimit() {
    return true;
  }

  static String getOrderByPart(String sql) {
    String loweredString = sql.toLowerCase();
    int orderByIndex = loweredString.indexOf("order by");
    if (orderByIndex != -1) {
      // if we find a new "order by" then we need to ignore
      // the previous one since it was probably used for a subquery
      return sql.substring(orderByIndex);
    } else {
      return "";
    }
  }
}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/218981#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Jul 2008 11:46:08 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/218981</link>
        <guid>http://seam.group.javaeye.com/group/blog/218981</guid>
      </item>
      <item>
        <title>jsf原始页面中文与动态嵌入的页面代码的中文编码问题</title>
        <author>xxqn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://xxqn.javaeye.com">xxqn</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/216439" style="color:red;">http://seam.group.javaeye.com/group/blog/216439</a>&nbsp;
          发表时间: 2008年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          关于中文 <br />以前不太注意不知道其他的jsf产生的页面代码中文是怎样表示的，现在发现同一页面会有两种表示形式，一种形如＆＃36866;，另一种就是中文显示的中文。 <br />页面嵌入的中文显示字符一般是jsf后台产生的，形如＆＃36866;则是页面原始的中文页面代码被jsf(或者seam或者容器)转换成形如＆＃36866; <br />页面原始的中文代码，在页面首次编译的时候中文被编译成形如＆＃36866;<br />页面嵌入的中文显示字符是每次客户端请求页面的时候由jsf生成的 <br />为何会有两种中文编码形式出现在同一页面呢？我认为原因如下：<br />1、<br />jsf认为未编译的原始jsf只能用一种字符编码，那就是ISO-8859-1，如果不是ISO-8859-1，编辑器IDE就必须提前转换成ISO-8859-1字符格式，例如把中文转换为形如＆＃36866;，否则都不予保存；在客户端请求页面的时候，这些源码将不在作任何转换直接送到客户端浏览器。<br />原因2、<br />客户端向jsf请求的时候，同时告诉JSF自己的当前的编码等等信息，JSF据此将需要嵌入的页面代码转换成客户端的当前的页面代码，这个时候由于已经知道了本次浏览器的接受编码了，就不用形如＆＃36866;这样的编码了，而是直接用指定的编码转换，这就是我们在页面看到的中文字符显示了。 <br />这里引出了另外一个问题就是。形如＆＃36866;表示的utf-8的页面代码好，还是用utf-8显示的中文页面代码好呢？<br />我认为形如＆＃36866;的页面代码更通用，没有障碍，所有的浏览器都能正确解释，不像以utf-8编码的中文页面代码，如果浏览器用错了编码集，就是乱码。
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/216439#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 19 Jul 2008 09:39:17 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/216439</link>
        <guid>http://seam.group.javaeye.com/group/blog/216439</guid>
      </item>
      <item>
        <title>Hibernate 的 getCurrentSession 简析</title>
        <author>SSailYang</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ssailyang.javaeye.com">SSailYang</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/215444" style="color:red;">http://seam.group.javaeye.com/group/blog/215444</a>&nbsp;
          发表时间: 2008年07月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>SessionFactory.getCurrentSession() 是 Hibernate 应用获取 Session
的常用方法。在调用该方法时，Hibernate 会从 interface CurrentSessionContext 获取当前的
Session，这是Hibernate 在不同组件中传递 Session 的方法。<br id="rx2v" />
<br id="rx2v0" />
CurrentSessionContext 有三个实现，分别是
ThreadLocalSessionContext、JTASessionContext 和
ManagedSessionContext。ThreadLocalSessionContext 将 Session
与当前线程绑定，是使用较多的一种方案；JTASessionContext 将 Session 与 JTA 事务绑定，在 JTA
环境中使用；ManagedSessionContext 使应用可以通过 bind() 和 unbind() 方法控制 Session
的绑定，主要在有 Conversation 的应用中使用（如果使用
ManagedSessionContext，开发人员要做的事情还是很多的）。CurrentSessionContext 实现的选择可以通过
hibernate.current_session_context_class 来配置。<br id="v:ca" />
<br id="v:ca0" />
另一种更常见的创建 Session 的方法是 openSession()。openSession() 与
getCurrentSession() 有何不同和关联呢？在 SessionFactory 启动的时候，Hibernate
会根据配置创建相应的 CurrentSessionContext，在 getCurrentSession() 被调用的时候，实际被执行的方法是
CurrentSessionContext.currentSession() 。在 currentSession() 执行时，如果当前
Session 为空，currentSession 会调用 SessionFactory 的 openSession。所以
getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。<br id="gr:f" />
<br id="gr:f0" />
再说 ManagedSessionContext，它提供了更灵活的绑定 Session 的方式，但是使用起来去不简单。在 Hibernate
的 CaveatEmptor 实例中有关于使用 ManagedSessionContext 的例子，但更好的选择是使用 Seam
Framework。<br id="y31y" />
</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/215444#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Jul 2008 15:45:27 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/215444</link>
        <guid>http://seam.group.javaeye.com/group/blog/215444</guid>
      </item>
      <item>
        <title>两个JBoss 实例再一台机器上启动的端口配置</title>
        <author>wwtyler</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wwtyler.javaeye.com">wwtyler</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/210234" style="color:red;">http://seam.group.javaeye.com/group/blog/210234</a>&nbsp;
          发表时间: 2008年07月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          经验证主要有以下几个地方需要改动，用来避免启动时的地址已经被绑定的异常。<br /><br />环境：JBoss 4.2.2GA，JDK 1.5<br /><br />1.   $JBoss_home/server/default/deploy/ejb3.deployer/META-INF/jboss-service.xml<br />     修改3873端口的值；<br />2.   $JBoss_home/server/default/deploy/jboss-web.deployer/server.xml<br />     修改8080，8009，8443端口值。<br />3.   $JBoss_home/server/default/conf/jboss-service.xml<br />     修改8083，1098，1099，4444，4445，4446端口值<br />4.   $JBoss_home/server/default/conf/jboss-minimal.xml<br />     修改1099端口值，与3中保持一致。<br />5.   $JBoss_home/server/default/deploy/jms/uil2-service.xml<br />     修改8093端口值。
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/210234#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Jul 2008 17:32:44 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/210234</link>
        <guid>http://seam.group.javaeye.com/group/blog/210234</guid>
      </item>
      <item>
        <title>电讯盈科 面试</title>
        <author>nbaertuo</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://nbaertuo.javaeye.com">nbaertuo</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/206313" style="color:red;">http://seam.group.javaeye.com/group/blog/206313</a>&nbsp;
          发表时间: 2008年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp; 一直呆在武汉这个地方，现在觉得武汉真的呆不下去了，软件行业中做技术的空间在这里太小了。2个星期前开始投简历了，有很多公司都联系到我了，北京，上海，深圳，杭州，广州，天津的，后来感觉投了，直接确定了自己的旅程方向：上海。</p>
<p>&nbsp;&nbsp;&nbsp; 这个星期一的时候，上海电讯盈科通知我前两轮的技术面试已经通过了，周三参加他们最后一轮的面试，地点是上海。我周二的晚上搭乘火车，周三的早上7.30到达上海，第一次来上海，本来想看看上海，但是偏偏坐的地铁，看到的大部分是地下隧道。一路赶到他们公司，已经9.40来。10点面试开始。。。。。。。。。。。。。。。。。。。。。</p>
<p>&nbsp;&nbsp;&nbsp; 11.40面试结束,通知两天内有结果。</p>
<p>&nbsp;&nbsp;&nbsp; 将近2个小时的面试，内容全部是管理，感觉像是我在面试他的管理经验，能聊两个小时，我的确有点佩服他的IBM的IDS方式管理。但是同时我从他的话中感觉到所谓的技术都很缥缈了，追随的最终结果是一场空。</p>
<p>&nbsp;&nbsp;&nbsp; 第一：你觉得你现在的技术是你的薪水<strong>价值</strong>，但是你面试的公司不这么认为。他认为的是你掌握基本技术，结合你的综合素质在公司创造出来的价值才是<strong>价值</strong>。</p>
<p>&nbsp;&nbsp;&nbsp; 第二：你现在所认为的技术，还只是停留在对国外的技术的一种应用，熟练而已。（我承认）</p>
<p>&nbsp;&nbsp;&nbsp; 第三：就算你超过了应用水平开始从底层开始编码你自己设计的一个框架的时候，会不会有一个人请你去做呢？例如：我今天面试你，我不懂构架，所以实际上我根本没有能力来考核你。在这种情况下我会花500W去国外的IBM或者国外的其他大公司挖一个在职的系统构架师而不愿意在国内花100请一个系统构架师。因为在我不懂的情况下我只能盲目的信从品牌。</p>
<p>&nbsp;&nbsp;&nbsp; 下午结果就出来了，我被录取了，我很高兴，但是想想以后该怎么发展呢？因为我是一个技术发烧友。我应该去大大退烧针？</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/206313#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 20 Jun 2008 15:14:24 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/206313</link>
        <guid>http://seam.group.javaeye.com/group/blog/206313</guid>
      </item>
      <item>
        <title>各种Button，Link组件的局限和搭配</title>
        <author>yourenyouyu2008</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yourenyouyu2008.javaeye.com">yourenyouyu2008</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/204109" style="color:red;">http://seam.group.javaeye.com/group/blog/204109</a>&nbsp;
          发表时间: 2008年06月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>各种jsf框架提供了相同功能的不同组件实现，他们都解决了某些问题，却又增添了新的问题，必须深刻理解才能在不同的场景下正确的使用不同的组件。</p>
<p>h:commandButton</p>
<p>可以提交表单，但不能传递参数</p>
<p>h:commandLink</p>
<p>可以提交表单，又能传递参数，但是以链接的形式展现</p>
<p>&nbsp;</p>
<p>a:commandButton</p>
<p>a:commandLink</p>
<p>都可以传递参数，但只能局部刷新页面</p>
<p>&lt;a:actionparam value="0" assignTo="#{contract_search.firstResult}"/&gt;</p>
<p>&nbsp;</p>
<p>s:button</p>
<p>s:link</p>
<p>都可以传递参数，但不能提交表单</p>
<p>&nbsp;</p>
<p>限于本人的表达能力有限，具体的使用场景欢迎qq讨论</p>
<p>62762013</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/204109#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 16 Jun 2008 13:57:17 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/204109</link>
        <guid>http://seam.group.javaeye.com/group/blog/204109</guid>
      </item>
      <item>
        <title>看了看《Seam in Action》的 unedited draft</title>
        <author>SSailYang</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://ssailyang.javaeye.com">SSailYang</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/201589" style="color:red;">http://seam.group.javaeye.com/group/blog/201589</a>&nbsp;
          发表时间: 2008年06月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>刚从网上下了本《Seam in Action》的 unedited draft 看。相信这最终是一本好书，但是现在的 draft 还是不推荐看，有很多语言需要调整。第一章读起来有点费劲。可能是 Seam 的只是不够丰富，所以很多地方看不懂，但是懂得多了也就用不着这本书了。总之，还是等正式版发行吧，再忍忍了。</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/201589#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 09 Jun 2008 22:45:22 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/201589</link>
        <guid>http://seam.group.javaeye.com/group/blog/201589</guid>
      </item>
      <item>
        <title> Hibaernate Search 全文搜索 庖丁 解词 </title>
        <author>nbaertuo</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://nbaertuo.javaeye.com">nbaertuo</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/201366" style="color:red;">http://seam.group.javaeye.com/group/blog/201366</a>&nbsp;
          发表时间: 2008年06月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在SEAM中使用已经配置好的HIBERNATE 全文搜索时使用中文的庖丁解词时，测试的时候都很成功，一旦发布到JBOSS中去就不能启动啦，老是报JAVA HEAP，内存不够。原因是庖丁解词在构造对象的时候，读取了很多中文常用词到内存，但是jboss默认的内存是128-512，所以需要修改内存配置。</p>
<p>开发环境下加上启动参数-Xms512m -Xmx1024m。</p>
<p>运行环境中修改RUN.BAT替换原来的修改为-Xms512m -Xmx1024m。</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/201366#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 08 Jun 2008 16:41:19 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/201366</link>
        <guid>http://seam.group.javaeye.com/group/blog/201366</guid>
      </item>
      <item>
        <title>JBoss Seam使用JBPM with out ejb</title>
        <author>nbaertuo</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://nbaertuo.javaeye.com">nbaertuo</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/201364" style="color:red;">http://seam.group.javaeye.com/group/blog/201364</a>&nbsp;
          发表时间: 2008年06月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;现在的项目基础构架是HIBERNATE+SEAM，在开发中想使用JBPM。开始仿照SEAM的例子配置了JBPM，结果发现项目跟不能启动，启动的时候报错。</p>
<p>org.hibernate.MappingException: An AnnotationConfiguration instance is required to use &lt;mapping class="com.ctazc.zs.model.system.Users"/&gt;</p>
<p>在JBOSS FORMS上搜索以后发现这是JBPM的缺陷，JBPM不支持HIBERNATE annotations,给出的办法是重新构造org.jbpm.db.hibernate.HibernateHelper类中的createConfiguration方法，原始的如下：</p>
<p>Configuration configuration = new Configuration();</p>
<p>替换上面那句为</p>
<p>&nbsp;AnnotationConfiguration configuration = new AnnotationConfiguration(); </p>
<p>OK了，这样就可以然JBPM支持HIBERNATE annotations啦。。。</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/201364#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 08 Jun 2008 16:34:46 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/201364</link>
        <guid>http://seam.group.javaeye.com/group/blog/201364</guid>
      </item>
      <item>
        <title>基于seam的datatable全选解决方案</title>
        <author>yourenyouyu2008</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yourenyouyu2008.javaeye.com">yourenyouyu2008</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/201138" style="color:red;">http://seam.group.javaeye.com/group/blog/201138</a>&nbsp;
          发表时间: 2008年06月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">基于</span><span lang="EN-US"><span style="font-family: Times New Roman;">seam</span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">的</span><span lang="EN-US"><span style="font-family: Times New Roman;">datatable</span></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">全选解决方案</span></span></p>
<p><span style="font-size: small;"><span style="font-family: 宋体;">目前的<span lang="EN-US">table只支持单行操作和全部行操作，而不支持多选操作，比如每行号前有个复选框，用于批量删除。</span></span></span></p>
<h1 style="margin: auto 0cm;"><span style="font-size: x-large;"><span style="font-family: 宋体;">通常做法</span></span></h1>
<p><span lang="EN-US"><br /><span style="font-size: small;"><span style="font-family: 宋体;">通常的做法是改写值对象，或者改写值对象的基类，在其中增加checked属性 <br />------------------------------------------------ <br />public abstract class BaseObject implements Serializable { <br />private boolean checked; <br /><br />public void setChecked(boolean value) { <br />this.checked = value; <br />} <br />public boolean isChecked(){ <br />return this.checked; <br />} <br />... <br />} <br />在页面上使用&lt;h:selectBooleanCheckbox value="#{e.checked}" /&gt; <br />&lt;h:dataTable var="e" value="#{typeallList.typeallModel }"&gt; <br />&lt;f:facet name="header"&gt;&lt;h:outputText value="#{text['typeall.typelist'] }"/&gt; <br />&lt;/f:facet&gt; <br />&lt;h:column&gt; <br />&lt;f:facet name="header"&gt;&lt;h:outputText value="#{text['list.checkall'] }"/&gt;&lt;/f:facet&gt; <br />&lt;h:selectBooleanCheckbox value="#{e.checked}" /&gt; <br />&lt;/h:column&gt; <br />提交后循环全部行，取出选择的行 <br />public String removeChecked(){ <br />List tempList = typeallModel.getWrappedObject(); <br />for (int i=0;i&lt;tempList.size();i++){ <br />OaTypeall obj=(OaTypeall)tempList.get(i); <br />if (obj.isChecked()) { <br />//删除obj <br />} <br />return null; <br />} <br />该方法的缺点是需要修改值对象，而添加的属性对值对象而言是没有意义的。这种方式破坏了对象的内聚性，把与该对象不相关的属性强添加到对象中。 </span></span></span></p>
<h1 style="margin: auto 0cm;"><span style="font-size: x-large;"><span style="font-family: 宋体;">新思路</span></span></h1>
<p><span lang="EN-US"><br /><span style="font-size: small; font-family: 宋体;">尽量做到最大程度的通用性，不用修改值对象的类，用</span></span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">CheckeableList</span><span style="font-size: small;"><span style="font-family: 宋体;">转换<span lang="EN-US">list，其中的对象用</span></span></span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">CheckedWrapped</span><span style="font-family: 宋体;"><span style="font-size: 10pt; color: #000000; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New';">来包装</span><span style="font-size: small;">，这样相当于给每行对象增加了<span lang="EN-US">checked属性，那样就可以在table的每行增加复选框了，提交后需要通过</span></span></span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">CheckeableList.<em>getCheckedList</em>(</span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;;">list</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">)</span><span style="font-family: 宋体;"><span style="font-size: 10pt; color: #000000; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New';">获取选种的记录。</span></span></p>
<h2 style="margin: auto 0cm;"><span style="font-size: large; font-family: 宋体;">页面效果</span></h2>
<p>&nbsp;</p>
<p><span style="font-family: 宋体;"><span style="font-size: 10pt; color: #000000; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New';">具体代码参照如下</span></span></p>
<h2 style="margin: auto 0cm;"><span style="font-size: large;"><span style="font-family: 宋体;"><span lang="EN-US" style="background: silver; mso-highlight: silver;">CheckedWrapped</span>包装类</span></span></h2>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">package</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> com.bhl.commons.web;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&nbsp;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">class</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> <span style="background: silver; mso-highlight: silver;">CheckedWrapped</span> {</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">private</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> Object </span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">data</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">private</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">boolean</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">checked</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> CheckedWrapped(Object data,</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">boolean</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> checek){</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">this</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">.</span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">data</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=data;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">this</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">.</span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">checked</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=checek;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> Object getData() {</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">return</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">data</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">void</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> setData(Object data) {</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">this</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">.</span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">data</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> = data;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">boolean</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> isChecked() {</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">return</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">checked</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">public</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">void</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> setChecked(</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">boolean</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> checked) {</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">this</span></strong><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">.</span><span style="font-size: 10pt; color: #0000c0; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">checked</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"> = checked;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">}</span></p>
<h2 style="margin: auto 0cm;"><span lang="EN-US"><span style="font-size: large; font-family: 宋体;">CheckeableList全选操作类</span></span></h2>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">package com.bhl.commons.web;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">import &hellip;&hellip;&hellip;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">@Name("checkeableList")</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">public class CheckeableList {</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>private boolean selected=false;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>private String dataModel;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public static String eventType="select_all";</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public String getDataModel() {</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return dataModel;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public void setDataModel(String dataModel) {</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.dataModel = dataModel;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public boolean isSelected() {</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return selected;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public void setSelected(boolean selected) {</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.selected = selected;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public static List transformList(List list){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(list!=null&amp;&amp;list.size()&gt;0){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int length=list.size();</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for(int i=0;i&lt;length;i++){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Object o=list.get(i);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CheckedWrapped wrap=new CheckedWrapped(o,false);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>list.set(i, wrap);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return list;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public static List&lt;Object&gt; getCheckedList(List&lt;CheckedWrapped&gt; list){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>List obList=new ArrayList();</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(list!=null&amp;&amp;list.size()&gt;0){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for(CheckedWrapped wrap:list){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(wrap.isChecked()){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>obList.add(wrap.getData());</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return obList;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">&nbsp;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public void selectAll(String dataName){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Object o=Contexts.lookupInStatefulContexts(dataName);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(o!=null&amp;&amp;o instanceof DataModel){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DataModel dm=(DataModel)o;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>List&lt;CheckedWrapped&gt; temList=(List&lt;CheckedWrapped&gt;)dm.getWrappedData();</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(temList!=null&amp;&amp;temList.size()&gt;0){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for(CheckedWrapped wrap:temList){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(selected){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wrap.setChecked(true);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}else{</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>wrap.setChecked(false);</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>//</span><span style="font-family: 宋体;"><span style="font-size: 10pt; color: #000000; mso-ascii-font-family: 'Courier New'; mso-hansi-font-family: 'Courier New'; mso-bidi-font-family: 'Courier New';">用于页面提交动作后的选择状态清除</span></span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>@Observer("select_all")</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>public void clearSelected(){</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>selected=false;</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;;">}</span></p>
<h2 style="margin: auto 0cm;"><span style="font-size: large; font-family: 宋体;">页面及程序使用示例</span></h2>
<h3 style="margin: 13pt 0cm;"><span style="font-size: large;"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt;">页面</span></span></h3>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">黑体加粗部分与全选有关</span></span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">a:outputPanel </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">id</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"searchResults"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-spacerun: yes;">&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">div </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">class</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"section"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-spacerun: yes;">&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:form</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-spacerun: yes;">&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:inputText </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">value</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"#{hotelSearch.name}" </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">style</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"width: 165px;"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-spacerun: yes;">&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:inputText </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">value</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"#{hotelSearch.city}" </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">style</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"width: 165px;"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:outputText </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">value</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"No Hotels Found" </span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">a:region</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">rich:spacer </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">height</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"30" </span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">rich:spacer </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">height</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"30" </span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 1;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:dataTable </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">id</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"hotels"<span style="mso-spacerun: yes;">&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">value</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"#{</span><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">hotels</span></strong><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">}" </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">columnClasses</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"col" </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">var</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"wrap" </span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:column</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">name</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"header"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:panelGroup</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong style="mso-bidi-font-weight: normal;">&lt;h:selectBooleanCheckbox name="checkname" value="#{checkeableList.selected}"&gt;</strong></span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;a:support event="onclick" actionListener="#{checkeableList.selectAll('hotels')}" reRender="searchResults" /&gt;</span></strong></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/h:selectBooleanCheckbox&gt;</span></strong></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 4;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:outputText </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">value</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"selectAll"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">/&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:panelGroup</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong style="mso-bidi-font-weight: normal;">&lt;h:selectBooleanCheckbox id="checkid" name="checkname" value="#{wrap.checked}"&gt;&lt;/h:selectBooleanCheckbox&gt;<span style="mso-tab-count: 1;">&nbsp;&nbsp; </span></strong></span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:column</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:column</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">name</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"header"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">Name</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dd</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:column</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 2;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">h:column</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;"><span style="mso-tab-count: 3;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet </span><span style="font-size: 10pt; color: #7f007f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">name</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">"header"</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&gt;</span><span style="font-size: 10pt; color: #000000; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">Address</span><span style="font-size: 10pt; color: #008080; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &quot;Courier New&quot;; mso-font-kerning: 0pt;">f:facet</span></p>
<p class="MsoNormal" align="left" style="margin: 0cm 0cm 0pt; text-align: left; mso-layout-grid-align: none;"><span style="font-size: x-small; color: #3f7f7f; font-family: Courier New;">页面下面的代码显示不出来了，请参加附件。。。。</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com/group/blog/201138#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 07 Jun 2008 10:56:17 +0800</pubDate>
        <link>http://seam.group.javaeye.com/group/blog/201138</link>
        <guid>http://seam.group.javaeye.com/group/blog/201138</guid>
      </item>
      <item>
        <title>深入浅出JBoss Seam</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://seam.group.javaeye.com/group/blog/200884" style="color:red;">http://seam.group.javaeye.com/group/blog/200884</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h1>深入浅出JBoss Seam</h1>
<p>转载自InfoQ http://www.infoq.com/cn/articles/jboss-seam</p>
<p class="info">作者 <strong>Michael Yuan</strong>
译者 <strong>包亮</strong>
 发布于 
2007年11月2日 上午1时3分 </p>
<p>&nbsp;</p>
<h2>什么是Seam？</h2>
<p>JBoss Seam是&ldquo;Java EE 5.0的一个轻量级的框架&rdquo;。这是什么意思？难道Java EE(Enterprise Edition) 
5.0本身不是一套&ldquo;框架吗&rdquo;？为什么在官方规范之外，还需要另外一个框架？好吧，我们就将seam看作是本应该被包括在Java EE 
5.0中的一个&ldquo;遗漏的框架&rdquo;吧。它在Java EE 
5.0框架的上层，为所有的在企业Web应用中的组件提供了一个统一的、易于理解的编程模型。它同样使基于状态的应用和业务流程驱动的应用的开发易如反掌。换句话说，Seam致力于开发者生产力和应用扩展性。</p>
<h3>1. 整合和强化Java EE框架 </h3>
<p>Java EE5.0的核心框架是EJB(Enterprise JavaBeans)3.0和JSF(JavaServer Faces)1.2。EJB 
3.0(以下简称EJB3)是基于一个POJO(Plain Old Java 
Objects)的业务服务和数据库持久化的轻型框架。JSF是一个基于MVC(Model-View-Controller)的Web应用框架。大多数的Web应用都将包含有业务逻辑的EJB3组件和Web应用前端显示的JSF组件。EJB3和JSF虽然互补，但是他们是根据各自的理念设计的独立的框架。例如，EJB3使用注解（annotation）来配置服务，而JSF使用的是XML文件。更进一步讲，EJB3和JSF组件在框架层面上是互不敏感的。要整合EJB3和JSF，开发者必须手动地构造facade对象（如：JSF支持bean），将业务组件与Web页面和样板代码（又称plumbing代码）联结起来，以便能跨框架调用方法。将这些技术粘合起来是Seam的职责之一。</p>
<p>Seam打破了EJB3和JSF之间的人工层，它为整合EJB3和JSF提供了一个一致的，基于注解的途径。只需要个别简单的注解，Seam中的EJB3业务组件就能直接被用来支持JSF 
Web表单或者处理Web 
UI事件。Seam允许开发者将&ldquo;同一种东西&rdquo;&mdash;&mdash;有注解的POJOs&mdash;&mdash;应用与所有的应用组件。与其他Web框架开发的应用相比，Seam应用概念简洁，同样的功能却需要较少的代码（在JAVA和XML中）。如果没有耐心，或者想要快速预览，一个Seam到底有多简单，你可以现看看本文描述的hello 
world一例。</p>
<p>在JSP来说困难的任务，Seam可以轻易的完成。例如，JSF头疼的一个问题就是过分依赖HTTP 
POST。这使得将一个添加到书签中的JSF网页，通过HTTP 
GET访问相当困难。但是有了Seam，生成一个REST网页是非常容易的。Seam提供了一系列JSF组件标签和注解，增加了&ldquo;web友好&rdquo;和JSF应用的网页效率。</p>
<p>同时，Seam拓展了EJB3到POJO的组件模式, 
从web层到业务层都有了状态上下文。进一步说，Seam整合了一系列主要的其他开放源代码框架，例如jBPM、JBoss Rules(又名Drools)、JBoss 
Portal、JBoss Microcontainer等等。Seam不仅能将它们&ldquo;有机结合&rdquo;起来，而且可以像整合JSF和EJB3一样强化原有的框架。</p>
<p>Seam位于Java EE 5.0底层，但它的应用并不局限与Java EE 5.0服务器。一个Seam应用可以部署在J2EE 
1.4应用服务器和Tomcat服务器上。这意味着现在能在Seam应用中得到产品化支持。</p>
<blockquote><strong>1 + 1 &gt; 2</strong>
<br />
<p>或许有这样一种误解，认为Seam仅仅是将各种不同框架串起来的另外一个集成框架。Seam提供了它自身管理的状态上下文，允许框架通过注解和EL（表达式语言）表达式与其他框架进行深度整合。整合的程序来自于Seam开发者对第三方框架的认知。</p>
</blockquote>
<h3>2. 一个为ORM设计的Web框架 </h3>
<p>对象关系映射(ORM)解决方案在当今企业应用中广为使用。但是，大多数当前的业务和web框架并不是为ORM设计的，它们并不在整个Web交互生命周期&mdash;&mdash;从请求来临到响应完成&mdash;&mdash;管理持久上下文。这就导致了包括可怕的<strong>LazyInitializationException</strong>
在内的各种ORM异常，带来了如&ldquo;数据传输对象（DTO）&rdquo;等丑陋的伎俩（ugly 
hacks）。</p>
<p>Gavin 
King发明了Seam，同时他也发明了在世界上广为使用的ORM解决方案Hibernate。为了继承和发扬ORM的最佳实践，Seam进行了重新设计。有了Seam，就不必再写DTO，你所做的就是延迟加载。因为扩展后的持久上下文就如同一个自然的高速缓存，可以减少和数据库的交互，ORM的性能就会被极大地改进。</p>
<p>进一步讲，因为Seam整合了ORM层、业务层和表示层，开发者就能够在表示层直接展示ORM对象，也能把数据库验证注解用于输入表单，以及重新定向ORM例外到定制的错误页面。</p>
<h3>3.专为有状态Web应用而设计</h3>
<p>Seam是专为有状态Web应用而设计的。Web应用是天生的多用户应用，电子商务应用天生也是有状态的和有事务的。但是，大多数已有Web应用框架是面向无状态应用的。开发者必须操作HTTP会话（session）对象来管理用户状态，与核心业务逻辑无关的代码不仅会混乱你的应用，而且带来了一系列的性能问题。</p>
<p>在Seam中，所有的基础应用组件天生地有状态。它们使用起来要比HTTP 
session容易，因为它们的状态由Seam公开管理。没有必要在Seam应用中编写引起麻烦的状态管理代码&mdash;&mdash;只需在其组件上注解其做用域、生命周期方法以及其他状态属性，Seam就会掌管其他[译者注：指这些组件的生命周期]。Seam状态组件要比HTTP会话（session）能更好的管理用户状态。例如，你能有多个&ldquo;会话&rdquo;进行，每个&ldquo;会话&rdquo;由在一个HTTP会话（session）中一系列的Web请求和业务方法调用组成。</p>
<p>进一步说，在Seam中，数据库缓存和事务能自动与应用的状态相连。Seam在内存中自动保存数据库更新，等到对话结束后提交到数据库。内存中的缓存能大大减轻复杂状态应用中数据库的负载。</p>
<p>除了以上这些，Seam支持整合开源JBoss 
jBPM业务程序引擎，大大提升了Web应用中的状态管理。你现在能为一个机构中不同工作人员（诸如客户、经理、技术支持人员等等）的指定工作流程，利用工作流程来驱动应用，而不是依赖用户界面事件处理和数据库。</p>
<h3>4. 支持Web 2.0 </h3>
<p>Seam为Web2.0应用进行了充分的优化。它给AJAX（异步JavaScript和XML，增加网页交互的一种技术）提供了多种支持&mdash;&mdash;从内置&ldquo;零Javascript&rdquo;的AJAX组件到有AJAX支持的JSF组件，再到定制的JavaScript库，Seam为浏览器端的Javascript对象提供了直接访问Seam服务器组件的途径。Seam提供了一个先进的并发模型，有效的管理来自同一用户的多个AJAX请求。</p>
<p>对于AJAX应用，不断增长的数据库负载是一个巨大的挑战。与一个非AJAX应用相比，一个AJAX应用要向服务器发送的更频繁的请求。一但数据库必须响应这些AJAX请求，那么数据库就不堪重荷。Seam中的状态持久上下文正如一个内存中的缓存，它能在会话始末保存信息，最终帮助减少数据库交互。</p>
<p>Web2.0应用往往为其数据使用复杂关系模型（例如，一个网络交际站点所做的就是处理和显示&ldquo;用户&rdquo;之间的关系），对于这些站点，延迟加载对于ORM层至关重要。否则，一个简单的查询就能级联地加载整个数据库。正如我们前面所讨论过的，Seam是现今唯一一个正确支持Web应用延时加载的Web框架。</p>
<h3>5.依赖双向映射的Pojo服务 </h3>
<p>Seam是一个&ldquo;轻量级&rdquo;框架，因为它使用POJO（plain old Java 
objects）作为服务组件。在应用中，POJO没有使用接口或抽象类来&quot;钩住&quot;组件。当然，问题是如何使POJO交互来组成这个应用？它们如何与容器服务（例如，数据库持久化服务）交互？</p>
<p>Seam通过使用一个流行的、被称作依赖注入(DI)的设计模式联结所有POJO组件。在这个模式下，Seam框架管理着所有组件的生命周期。当一个组件需要使用另外一个时，它通过注解（annotation）向Seam声明此依赖。Seam依据应用当前状态得到这个依赖组件，并将它注入到所需求的组件中。</p>
<p>通过拓展依赖注入概念，一个Seam组件A不但可以构造另外一个组件B，而且把此组件B&ldquo;抛还&rdquo;给Seam以备其他组件（例如组件C）以后使用。</p>
<p>这类双向依赖管理甚至都广泛的应用于简单的Seam web应用中（例如第二章的hello 
world一例）。在Seam术语中，我们称这个为&ldquo;依赖双向映射&rdquo;。</p>
<h3>6.非常规的配置</h3>
<p>[译者注：指以隐式映射为主题，以显式映射为例外的配置方式] 
</p>
<p>使Seam易用的主要设计原则是&ldquo;非常规的配置&rdquo;。其思想是为这些组件提供一系列默认行为，开发者只需要在预期行为非默认的时候，显示地配置组件。例如, 
当Seam将组件A作为属性注入到组件B时，默认地，组件A刚会以组件B被注入的属性的名称命名。Seam里还有很类似的细节。总的结果是Seam中配置元数据要比其他Java框架简单的多。因此，大多数的Seam应用能通过一系列简单的Java注解进行充分配置。开发者从减化的复杂度中受益匪浅，最后，与其他Java框架相比，用更少的代码实现同样的功能。</p>
<h3>7.避免滥用XML</h3>
<p>或许你已经注意到，Java注解在表述和处理Seam配置元数据时扮演着重要的角色。通过这样的设计使框架更易于操作。</p>
<p>在J2EE发展早期，XML曾经被看作配置管理的&ldquo;圣杯&rdquo;。框架设计者将所有的配置信息，包括Java类和方法名称都统统丢进XML文档，而不考虑对开发者所带来的后果。反省后，发现这是个严重的错误。XML配置文档太过重复。开发者必须重复代码中已有的信息，从而将配置和代码联结起来。这些重复使应用易于出错（例如，一个拼写错误的类名可能在运行时显示为一个难于调试错误）。缺少合理的默认配置进一步使这一问题复杂化。事实上，在一些框架中，相当数量的样板代码伪装为XML，可能相当于或者超过实际应用中JAVA代码的数量。对于J2EE开发者，XML的滥用通常被称为&ldquo;XML地狱&rdquo;。</p>
<p>Java社区认识到了XML的滥用问题，并且已经非常成功地用Java代码中的注解取代了XML。EJB3是Java官方标准化机构促进Java企业组件中注解使用的一项成果。EJB3完全可选择的使用XML文档，它向正确方向迈出了积极的一步。Seam加入了EJB3的注解，为整个web应用拓展了基于注解的编程模型。</p>
<p>当然，XML对于配置数据并非完全不利。Seam设计者认识到XML适用于指定页面流程或者定义业务流程的web应用。XML文档使开发者集中地管理整个web应用的工作流程成为可能，同时也反对将配置信息分散于java源文件中。工作流程很少能与源代码耦合，因此XML文档中并不需要重复键入已存在于代码中的信息。</p>
<h3>8.为测试而设计</h3>
<p>Seam为了易于测试而重新设计。因为所有的Seam组件都是注解过的POJO，它们易于进行单元测试。开发者仅仅通过利用常规的Java 
new关键词来构造实例，然后在测试框架（例如JUnit 
或者TestNG）中运行任何方法。如果需要测试多个Seam组件的交互，开发者则逐个实例化这些组件，然后手动建立它们的相互关系（也就是显示地使用setter 
方法，而不是依靠Seam依赖注入功能）。</p>
<p>集成测试整个Seam应用比较复杂，因为开发者必须在Seam容器中运行应用。Seam用嵌入的轻量级容器来帮助该类测试。在测试框架中，开发者能按步骤地加载Seam容器，然后运行测试。</p>
<h3>9. 卓越的工具支持</h3>
<p>对于一个聚焦于开发者生产力的应用框架，开发工具的支持至关重要。Seam发布了一个基于命令行的生成器，称作 
SeamGen。SeamGen类似于Ruby-On-Rails中的生成器，它支持诸如从一个数据库生成完整CRUD应用的功能，聪明的开发者会通过诸如&ldquo;编辑/保存/在浏览器重新载入&rdquo;的步骤、有测试支持的特性，来改进web应用。</p>
<p>但更重要的是，SeamGen生成项目不依赖于主流的Java集成开发环境，如Eclipse和NetBeans。有了SeamGen，开发者可以随时入门。</p>
<h3>10. 让我们开始编码吧</h3>
<p>总而言之，Seam为JavaEE应用削减了开发费用，同时，增加了Java EE 
5.0不具有的强大的新功能。在下节（节选自本书第二章），我们将给您展示一些实际代码例子来阐述Seam如何工作的。你能通过网站<a>http://www.michaelyuan.com/seam/</a>
下载到本书中所有的例子的源代码。</p>
<h2>Seam Hello World </h2>
<p>JBoss Seam是EJB3和JSF中间的粘合剂，这是Jboss 
Seam最基本的和最广泛的应用。通过被Seam管理的组件，Seam允许这两个框架之间无缝(不是有意双关的)的集成。它为整个web应用拓展了基于注解的EJB3 
POJO编程模型。在层与层之间，没有了必需的手动JNDI查找，没有了冗长的JSF支持bean的声明，没有了过多facade方法，没有了艰辛的对象传递，快哉！</p>
<blockquote><strong>继续在Seam中使用JavaEE模式</strong>
<br />
<p>在传统的java 
EE应用中，一些设计模式，例如JNDI查找、XML声明组件、值对象、facade是被强制使用的。Seam用基于注解的POJO消除了这些人为的需求。但是，当Seam应用中真正需要它们的时候，仍然可以自由地使用这些模式。</p>
</blockquote>
<p>编写一个Seam web应用概念上很简单。你只需要编码出下列组件：</p>
<ul>
<li>实体对象代表数据模型。实体对象可能是JPA或者Hibernate中的POJO对象。它们自动地映射到关系数据库表。 
</li>
<li>SF 
web页面展示了用户界面。页面通过表单捕获用户的输入，并且显示结果。表单域与其数据显示数据库表，这些表被映射到实体bean或者实体bean的集合上。 
</li>
<li>EJB3 会话bean或者注解过的Seam POJO可以作为JSF 
Web页面的UI事件处理器。它们处理封装在实体bean中的用户输入，为下一步（或者页面）生成显示的数据对象。 </li>
</ul>
<p>所有以上组件均由Seam自行管理，它们在运行时被自动注入到正确的页面或者对象。例如，当用户单击按钮提交一个JSF表单，Seam就会自动解析表单域并构造一个实体bean。然后，Seam将实体bean传入同样被Seam构造的事件处理器会话bean中来处理。开发者不需要在代码中管理组件的生命周期和组件之间的相互关系。依赖处理过程中，没有样板代码和XML文件。</p>
<p>本章中，我们使用hello 
world一例来明确展示Seam如何粘合一个web应用。该例子工作如下：用户能在web表单中输入其名字来&ldquo;问候&rdquo;Seam。一旦她提交了表单，应用则保存她的名字到一个关系数据库中，并且显示所有已经&ldquo;问候&rdquo;过Seam的用户。该项目示例在该书下载的源代码中的HelloWorld文件夹中。为了建立它，你必须安装Apache 
ANT 1.6版本以上 
(http://ant.apache.org/)。进入HelloWorld目录，运行命令ant，则会生成build/jars/helloworld.ear文件，可以直接拷贝该文件到Jboss 
AS实例的server/default/deploy目录下。现在，启动JBoss 
AS并且打开网址http://localhost:8080/helloworld/。</p>
<p>为了运行本书中的例子，我们建议您使用JEMS GUI安装程序安装一个与Seam兼容的JBoss AS。您可以从<a href="http://labs.jboss.com/portal/jemsinstaller/downloads">http://labs.jboss.com/portal/jemsinstaller/downloads</a>
下载JEMS安装程序。如果您需要更多安装JBoss 
AS和应用部署帮助，请参见附录A，&ldquo;安装和部署JBoss AS&rdquo;</p>
<p>欢迎使用示例作为模板，快速开始你自己Seam项目（参见附录B &ldquo;使用应用示例作为模板&rdquo;）。或者，你能使用命令行工具Seam Gen 
(参见第四章&ldquo;快速应用开发工具&rdquo;)自动生成项目模板，包括所有的配置文件。本章中，我将花少量的时间来阐释源代码项目中的目录结构。相反，我们将集中讨论代码和配置，这也是开发者建立一个Seam 
应用必需的。如此，我们就能将知识应用到任何一个项目结构，而不需要受模板的限制。</p>
<blockquote><strong>源代码目录</strong>
<br />
<p>一个Seam应用由java类和XML或文本配置文件组成。本书的项目例子中，java源代码文件在src目录中，网页在view 
目录中，所有的配置文件都在resources目录中。更多信息请看附件B,使用应用示例作为模板。</p>
</blockquote>
<h3>1. 创建一个数据模型</h3>
<p>Helloworld应用中的数据模型仅仅是一个有name和id属性的person 
类。注解<strong>@Entity</strong>
告诉容器映射该类到一个关系数据库表，每个属性对应表中一个字段，每个person实例相当于表中的一条记录。因为Seam采用非常规的配置方式，容器为表名和字段中仅仅使用类名和属性名。属性id上的<strong>@Id</strong>
和<strong>@GeneratedValue</strong>
注解暗示id字段是主键，它的值是应用服务器为每个保存到数据库的peron对象自动生成。</p>
<pre>@Entity
@Name(&quot;person&quot;)
public class Person implements Serializable {

  private long id;
  private String name;

  @Id @GeneratedValue
  public long getId() { return id;}
  public void setId(long id) { this.id = id; }

  public String getName() { return name; }
  public void setName(String name) {this.name = name;}
}</pre>
<p>Person类中最重要的注解是@Name，它为这个将要注册于Seam中的Person 
bean指定了名称。在其他Seam组件中（例如，页面和会话bean）中，开发者能指直接使用&ldquo;<strong>person</strong>
&rdquo;来引用被管理的<strong>Person 
bean</strong>
。</p>
<h3>2. 将数据模型映射到web表单</h3>
<p>在JSF页面中，我们使用Person 
bean来支持表单输入文本域。<strong>#{person.name}</strong>
符号指代名为&ldquo;<strong>person</strong>
&rdquo;的Seam组件的name属性，名为&ldquo;<strong>person</strong>
&rdquo;的Seam组件是<strong>Person</strong>
实体bean的一个实例。</p>
<pre>&lt;h:form&gt;
Please enter your name:&lt;br/&gt;
&lt;h:inputText value=&quot;#{person.name}&quot; size=&quot;15&quot;/&gt;&lt;br/&gt;
&lt;h:commandButton type=&quot;submit&quot; value=&quot;Say Hello&quot;
                 action=&quot;#{manager.sayHello}&quot;/&gt;
&lt;/h:form&gt;</pre>
<p>通过以下的实体表单，JSF页面显示了数据库中所有已经向Seam说&ldquo;hello&rdquo;的用户。用户名单列表存储在一个名为&ldquo;<strong>fans</strong>
&rdquo;的Seam组件中，它是一个<strong>List 
</strong>
对象。JSF<strong>dataTable</strong>
通过遍历列表，每一行显示一个<strong>Person</strong>
对象。<strong>Fan</strong>
标记是<strong>fans</strong>
列表的迭代子。</p>
<pre>&lt;h:dataTable value=&quot;#{fans}&quot; var=&quot;fan&quot;&gt;
  &lt;h:column&gt;
    &lt;h:outputText value=&quot;#{fan.name}&quot;/&gt;
  &lt;/h:column&gt;
&lt;/h:dataTable&gt;
    </pre>
<p><img src="../../../resource/articles/jboss-seam/zh/resources/image1.png;jsessionid=1A0D677EF0D8B8B6A9F90C93E7E45F4C" alt="" />
</p>
<p>图2.1显示了Hello World网页</p>
<p>当用户点击&ldquo;Say 
Hello&rdquo;按钮提交表单，Seam用输入数据构造了该person组件。然后它调用了名为&ldquo;<strong>manager</strong>
&rdquo;的Seam 
组件的sayhello()的方法(像这样，<strong>#{manager.sayHello}</strong>
是表单提交按钮的UI事件处理器)，这就在数据库中保存了<strong>person</strong>
对象并且刷新了<strong>fans</strong>
列表。名为<strong>manager</strong>
的组件是一个EJB3的会话bean, 
我们将在下节讨论该话题。</p>
<h3>2. 处理web事件 </h3>
<p>Seam 中的名为manager的组件是会话bean 
<strong>ManagerAction</strong>
，正如该类中<strong>@Name</strong>
注解指定的。<strong>ManagerAction类</strong>
有<strong>person</strong>
和<strong>fans</strong>
两个属性，这两个属性被<strong>@In</strong>
和<strong>@Out</strong>
所注解。</p>
<pre>@Stateless
@Name(&quot;manager&quot;)
public class ManagerAction implements Manager {

  @In @Out
  private Person person;

  @Out
  private List &lt;Person&gt; fans; </pre>
<p>注解@In和@Out在Seam编程模型中处于核心。因此，让我们看看到底它们在这里是做什么的。</p>
<p>注解@In告诉Seam，在此会话bean中，执行任何一个方法之前，Seam就会把由JSF表单构造的名为person组件赋给该person字段（通过依赖注入）。开发者能为@In中的注入的组件指定一个任意的名称，但是如果没有指定，如这里所示，Seam会将同类型以及同名称的组件注入到该字段中。注解@Out告诉Seam，在执行任何方法后，Seam会将属性fans值和属性person的值都赋给被Seam管理的同名的组件。在Seam中，我们将这个操作称作 
&ldquo;依赖抛出&rdquo;。以此，在ManagerAction.sayHello()方法中，我们仅仅需要更新属性fans和属性person的值，它们会自动显示在页面上。</p>
<blockquote><strong>什么是双向映射</strong>
<br />
<p>在Seam 文件中，有时你就会看到术语&ldquo;双向映射&rdquo;。它指的是被Seam管理的组件和Seam管理上下之间的注入和抛出。</p>
</blockquote>
<p>因为<strong>person</strong>
属性已经通过注入持有了表单数据，<strong>sayHello()</strong>
方法仅仅是通过JPA 
<strong>EntityManager</strong>
将它保存到数据库中，JPA 
<strong>EntityManager</strong>
也是通过<strong>@PersistenceContext</strong>
注入的。当方法返回之后，它便更新了<strong>fans</strong>
和<strong>person</strong>
对象并且把这两个对象抛出。方法<strong>sayHello()</strong>
一般会返回null，预示着在调用之后，更新的数据模型将在当前的JSF页面显示。</p>
<pre>  @PersistenceContext
  private EntityManager em;

  public String sayHello () {
    em.persist (person);
    person = new Person ();
    fans = em.createQuery(&quot;select p from Person p&quot;)
          .getResultList();

    return null;
  }</pre>
<p>除了一些细节，我们基本完成了。可能你已经注意到，ManagerAction bean类实现了Manager接口。为了符合EJB3会话bean 
规范，我需要一个能列出bean中所有业务方法的方法。下面是接口Manager代码，幸运的是，用任何高级IDE工具都能轻松地自动生成这个接口。</p>
<pre>@Local
public interface Manager {
  public String sayHello ();
}</pre>
<p>这就是在Hello 
World例子中需要的所有代码。后面两章小节将涵盖Seam应用的其他方法和配置。如果开发者为了自己的小型数据库应用想立即编码和定制helloworld项目，那么现在就可以跳过本章的剩余部分。</p>
<h3>4. 更易于理解的seam编程模型</h3>
<p>现在我们已经大致了解了Hello 
World的应用。但是我们还有一些重要的话题继续，例如其他折中途径以及前面代码没有涉及到重要特性，我们将在本节讨论这些话题。它们能帮助开发者对seam更深刻的理解，但是如果你没有耐心，可以直接跳过本节，需要的时再来阅读。</p>
<h4>4.1 Seam POJO组件 </h4>
<p>上例中，我们用一个EJB3会话bean实现了应用逻辑，但是我们并不局限于EJB3组件。事实上，Seam中任何一个有<strong>@Name</strong>
注解的POJO都能被转化为一个可管理的组件。</p>
<p>例如，我们能将<strong>ManagerAction</strong>
转化为一个 POJO，而不是一个EJB3 session bean。</p>
<pre>@Name(&quot;manager&quot;)
public class ManagerAction {

  @In (create=true)
  private EntityManager em;

  ... ...
} </pre>
<p>使用POJO取代EJB3 
bean有正反两方面意见，使用POJO编程时很简单，因为它们不需要EJB3特有的注解和接口（参见上文）。如果你的所有业务组件都是Seam POJO, 
那么你就能不依赖EJB3应用服务器，运行你的Seam 应用（参见23章，没有EJB3的Seam)。</p>
<p>但是，POJO比EJB3的功能少，因为POJO不能获得EJB3容器服务。在不依赖EJB3的Seam 中丧失的EJB3服务就包括以下几点：</p>
<ul>
<li><strong>@PersistenceContext</strong>
注入在POJO中不在管用。为了在一个Seam 
POJO中得到EntityManager，开发者不得不在Seam配种文件中初始化EntityManager，然后使用Seam注解@In将它注入到POJO中。 
</li>
<li>POJOs中将不在支持方法级别事务声明（declarative method-level 
transaction）。相反，你可以配置Seam来划分事务，可以从收到web请求开始直到响应页面产生结束。 
</li>
<li>Seam POJO不是消息驱动组件。 
</li>
<li>不支持注解为<strong>@Asynchronous</strong>
的方法。 
</li>
<li>不支持容器安全管理。 
</li>
<li>没有事务或者组件级别的持久上下文。Seam POJO中的所有的持久上下文都是经过拓展的（更多细节请参见7.1 &ldquo;默认的对话作用域&rdquo;）。 
</li>
<li>没有集成容器管理的体系结构（例如，JMX控制台服务）。 
</li>
<li>Seam POJO方法中没有Java RMI。 
</li>
<li>Seam POJO不能是注解为<strong>@WebService</strong>
组件。 
</li>
<li>没有JCA集成。 </li>
</ul>
<p>所以当在EJB3容器中进行部署时，为什么每个人都想使用POJO组件？答案就是，POJO组件对于纯&ldquo;业务逻辑&rdquo;组件非常有益。POJO为其他组件代理了数据访问、消息传递和其他基本功能。例如，我们能使用POJO组件操纵Seam数据访问对象，这对&ldquo;业务逻辑&rdquo;POJO是非常有用的，因为它们可以在需要的时候，在其他框架中被重用。但是总的来说，它们的应用要比EJB3组件少，特别是在中小型应用中。所以，本书的大多数例子我们都使用EJB3组件。</p>
<h4>4.2 易于测试</h4>
<p>我们已经在第一章中提到，Seam为了不依赖容器的方便的测试，进行了重新设计。在<strong>helloworld</strong>
项目中，我们在测试文件夹中包括了单元测试和集成测试这两个测试用例。在纯Java 
SE环境下，Seam 测试体系模拟了数据库、JSF、Seam上下文以及其他应用服务器服务，只要运行ant test命令就能运行所有的测试。</p>
<h4>4.3 基于Getter和Setter的双向映射 </h4>
<p>在Hello 
World一例中，我们已经展示了通过成员变量对Seam组件进行的双向映射，你也能通过Getter和Setter方法对组件进行双向映射。例如，以下代码就工作的很好。</p>
<pre>private Person person;
private List &lt;Person&gt; fans;

@In
public void setPerson (Person person) {
  this.person = person;
}
@Out
public Person getPerson () {
  return person;
}
@Out
public List &lt;Person&gt; getFans () {
  return fans;
}</pre>
<p>虽然以上的getter和setter方法看似轻微，利用getter和setter方法的双向映射真正的价值在于能其加入定制逻辑来操纵双向映射的过程。例如，你可以验证被注入的对象或者快速地从数据库重新得到被抛出的对象。</p>
<h4>4.4避免过度的双向映射</h4>
<p>在Hello World一例中 
,通过将数据组件作为业务组件的属性，可以轻易的减少或者消除双向映射。在JSF页面中，通过这种方式，开发者只需要引用业务组件，而不需要在业务组件和数据组件之间的双向映射。例如，开发者可以修改 
ManagerAction类为以下所述。</p>
<p>依赖双向映射是一个非常实用的设计模式。但是，正如其他设计模式，过度使用就会有害。过度的依赖双向映射让代码变得难以阅读，因为开发者必须理解每个注入的组件出自何处。过度的依赖双向映射也能增加性能消耗，因为双向映射是在运行时进行。</p>
<pre>@Stateless
@Name(&quot;manager&quot;)
public class ManagerAction implements Manager {

  private Person person;
  public Person getPerson () {return person;}
  public void setPerson (Person person) {
    this.person = person;
  }

  private List &lt;Person&gt; fans;
  public List&lt;Person&gt; getFans () {return fans;}

...  ...
}</pre>
<p>接下来，我们在页面上引用的属性如下：</p>
<pre>&lt;h:form&gt;

Please enter your name:&lt;br/&gt;

&lt;h:inputText value=&quot;#{manager.person.name}&quot;/&gt;
&lt;br/&gt;
&lt;h:commandButton type=&quot;submit&quot; value=&quot;Say Hello&quot;
                 action=&quot;#{manager.sayHello}&quot;/&gt;
&lt;/h:form&gt;</pre>
<pre>... ...</pre>
<pre>&lt;h:dataTable value=&quot;#{manager.fans}&quot; var=&quot;fan&quot;&gt;
  &lt;h:column&gt;
    &lt;h:outputText value=&quot;#{fan.name}&quot;/&gt;
  &lt;/h:column&gt;
&lt;/h:dataTable&gt;</pre>
<p>最后，具有了依赖管理的Seam是多用的。通常用数据访问业务组件封装数据是一项好的实践，特别是针对有状态业务组件。</p>
<h4>4.5 JSF中的页面导航</h4>
<p>本例中，只有一个页面。每次点击按钮后，JSF页面会重新显示更新过的数据模型。显然，大多数web应用多于一个页面。在JSF中，一个用户界面事件处理器能通过返回导航规则名称，决定下一步该显示哪个页面。例如，开发者可以在<strong>navigation.xml</strong>
中定义以下导航规则。</p>
<pre>&lt;navigation-case&gt;
  &lt;from-outcome&gt;anotherPage&lt;/from-outcome&gt;
  &lt;to-view-id&gt;/anotherPage.jsp&lt;/to-view-id&gt;
&lt;/navigation-case&gt;
</pre>
<p>之后，如果sayHello()方法返回一个名为&ldquo;another 
page&rdquo;的字符串，JSF下一步就该展示anotherPage.jsp。UI事件处理器决定了接下来要显示哪个页面，从而为我们带来了有步骤的控制。</p>
<h4>4.6 通过EntityManager访问数据库</h4>
<p>JPA（Java Persistence API）<strong>EntityManager</strong>
管理着关系数据库表与实体bean 
之间的映射。<strong>EntityManager</strong>
 
在运行时由应用服务器创建。你能使用注解@PersistenceContext，注入一个EntityManager的实例。</p>
<p><strong>EntityManager.persist()</strong>
方法将实体bean存为与之对应数据表的一条记录。EntityManager.query()方法运行SQL化的查询，并以实体bean集合形式从数据库返回数据。更多细节请参考JPA文件中关于如何使用EntityManager和查询语言。在本书中，我们只用最简单的查询语句。</p>
<p>默认地，EntityManager将数据存于嵌入的HSQL数据库中。如果在本机上运行Jboss 
AS，可以通过以下步骤，为HSQL数据库开启一个GUI控制台：访问<strong>http://localhost:8080/jmx-console/</strong>
，点击<strong>database=localDB,service=Hypersonic 
</strong>
MBean服务，之后，点击在startDatabaseManager方法下方的&ldquo;invoke&rdquo;按钮。你就可以从控制台执行任意SQL指令。</p>
<h3>5. 配置和打包</h3>
<p>下面，我们将转移话题，讨论配置文件和应用程序打包。实际上，你可以通过Seam 
Gen命令行工具，生成几乎所有的配置文档和构造脚本文件。或者你也可以简单的重用在示例中的源文件。所以，如果你想首先学习Seam编程技术，但又担心接下来的配置和部署，这个是很正常的。你可以完全放心地跳过本节，需要的时候可以再次阅读。</p>
<p>本节中，我们集中探讨Seam EJB3组件配置，JBoss AS外的Seam POJO配置和部署当然是可行的。</p>
<p>大多数Seam配置文件都是XML文档。但是等等！我们刚才不是承诺Seam能让我们摆脱J2EE和Spring中的XML地狱吗？为什么它又有了XML文档呢? 
是的，XML文档确实有很多用处。XML文档非常适合部署阶段的配置（例如web应用的根URL和后台数据库的定位）。因为它允许我们在部署阶段改变配置而不需要改变和重新编译源代码。它也适合粘合应用服务器中的不同子系统（例如，配置如何让JSF组件与Seam 
EJB3组件交互）。XML文档也非常适合表示层相关内容（例如网页和页面导航流程）。</p>
<p>我们反对在XML文档中重复已经存在于Java源代码中的信息。开发者很快就会发现，这个简单的SeamEJB3 
应用有多个XML配置文档，每个文档那个都非常简短，并且没有一个包含存在于Java代码中的信息。换句话说，Seam中没有&ldquo;XML代码&rdquo;。</p>
<p>进一步讲，XML文档中的大多数内容都是静态的。所以开发者能在自己的Seam应用中轻松地重用这些文档。如何使用示例作为自己的应用模板的介绍，请参见附录B&mdash;&mdash;使用应用示例作为模板。</p>
<p>我们将用下面几页来详细讲解示例应用的配置文档和打包后的目录结构。如果你没有耐心看下去，而且很满意这个应用模板，你可以跳过以下内容。不管怎样，不再罗嗦, 
我们一起来了解hello world示例是如何进行配置和打包的。为了构建一个JBoss AS的部署Seam 应用，我们必须将以上所有java 
类和配置文档打包为企业应用程序归档(EAR)。该例中，EAR文件是<strong>helloworld.ear</strong>
。它包含了三个JAR文件那个和两个XML配置文档。</p>
<pre>helloworld.ear
|+ app.war        //包含Web页面等
|+ app.jar        //包含Seam组件
|+ jboss-seam.jar // Seam库
|+ META-INF
   |+ application.xml
   |+ jboss-app.xml  </pre>
<blockquote><strong>源代码目录</strong>
<br />
<p>在此项目的源代码中，resources/WEB-INF目录包含属于app.war/WEB-INF目录的配置文档。resources/META-INF目录包含属于app.jar/META-INF和helloworld.ear/META-INF的文档。Resources根目录包含属于根目录app.jar的文档。</p>
</blockquote>
<p>application.xml文档列出了在EAR中的JAR文件，并为该应用指定了根URL。</p>
<pre>&lt;application&gt;
  &lt;display-name&gt;Seam Hello World&lt;/display-name&gt;

  &lt;module&gt;
    &lt;web&gt;
      &lt;web-uri&gt;app.war&lt;/web-uri&gt;
      &lt;context-root&gt;/helloworld&lt;/context-root&gt;
    &lt;/web&gt;
  &lt;/module&gt;

  &lt;module&gt;
    &lt;ejb&gt;app.jar&lt;/ejb&gt;
  &lt;/module&gt;

  &lt;module&gt;
    &lt;java&gt;jboss-seam.jar&lt;/java&gt;
  &lt;/module&gt;

&lt;/application&gt;</pre>
<p><strong>jboss-app.xml</strong>
文档为该应用指定了类加载器，每个EAR应用的类加载器应该有一个唯一的名称。这里我们使用应用程序名作为类加载器的名称，以避免重复。</p>
<pre>&lt;jboss-app&gt;
  &lt;loader-repository&gt;
    helloworld:archive=helloworld.ear
  &lt;/loader-repository&gt;
&lt;/jboss-app&gt;
</pre>
<p>jboss-seam.jar是Seam发布Seam类库。app.war和app.jar文档由我们来建构。所以，下面我们要研究app.war和app.jar。</p>
<h4>5.1. WAR文件 </h4>
<p><strong>app.war</strong>
是按照Web应用程序归档规范打包的JAR文件，它包含页面和标准的JSF/Seam配置文档。你还可以将JSF特有的类库文件放入<strong>WEB-INF/lib</strong>
目录 
(例如<strong>jboss-seam-ui.jar</strong>
)。 </p>
<pre>app.war
|+ hello.jsp
|+ index.html
|+ WEB-INF
   |+ web.xml
   |+ faces-config.xml
   |+ components.xml
   |+ navigation.xml</pre>
<p><strong>web.xml</strong>
文档是所有java EE web应用必需的。JSF用它来配置JSF 
servlet控制器，Seam用它来拦截所有的web请求。该配置文档的相当标准。</p>
<pre>&lt;web-app version=&quot;2.4&quot;
    xmlns=&quot;http://java.sun.com/xml/ns/j2ee&quot;
    xmlns:xsi=&quot;...&quot;
    xsi:schemaLocation=&quot;...&quot;&gt;

  &lt;!-- Seam --&gt;
  &lt;listener&gt;
    &lt;listener-class&gt;
      org.jboss.seam.servlet.SeamListener
    &lt;/listener-class&gt;
  &lt;/listener&gt;

  &lt;!-- MyFaces --&gt;
  &lt;listener&gt;
    &lt;listener-class&gt;
org.apache.myfaces.webapp.StartupServletContextListener
    &lt;/listener-class&gt;
  &lt;/listener&gt;

  &lt;context-param&gt;
    &lt;param-name&gt;
      javax.faces.STATE_SAVING_METHOD
    &lt;/param-name&gt;
    &lt;param-value&gt;client&lt;/param-value&gt;
  &lt;/context-param&gt;

  &lt;servlet&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;
      javax.faces.webapp.FacesServlet
    &lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;

  &lt;!-- Faces Servlet Mapping --&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.seam&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;context-param&gt;
    &lt;param-name&gt;javax.faces.CONFIG_FILES&lt;/param-name&gt;
    &lt;param-value&gt;/WEB-INF/navigation.xml&lt;/param-value&gt;
  &lt;/context-param&gt;
&lt;/web-app&gt;</pre>
<p><strong>faces-config.xml</strong>
文档是JSF标准的配置文档，Seam用它来将其拦截器添加到JSF生命周期中。</p>
<pre>&lt;faces-config&gt;

  &lt;lifecycle&gt;
    &lt;phase-listener&gt;
      org.jboss.seam.jsf.SeamPhaseListener
    &lt;/phase-listener&gt;
  &lt;/lifecycle&gt;

&lt;/faces-config&gt;</pre>
<p>navigation.xml文档为多页面应用包含JSF页面导航规则。因为hello world示例只有一个简单的页面，因此该文档是空的。</p>
<p><strong>components.xml</strong>
文档包含Seam特有的配置选项，除<strong>jndi-pattern</strong>
属性以外，其他都不依赖于应用。该属性必须包括EAR文档的名称，以便Seam通过其的JNDI全名访问EJB3 
bean。</p>
<pre>&lt;components ...&gt;

  &lt;core:init
    jndi-pattern=&quot;helloworld/#{ejbName}/local&quot;
    debug=&quot;false&quot;/&gt;

  &lt;core:manager conversation-timeout=&quot;120000&quot;/&gt;

&lt;/components&gt;</pre>
<h4>5.2. Seam组件JAR包</h4>
<p><strong>app.jar</strong>
文档包含所有的EJB3bean 类（实体bean和会话bean）以及EJB3相关的配置文档。</p>
<pre>app.jar
|+ Person.class        // entity bean
|+ Manager.class       // session bean interface
|+ ManagerAction.class // session bean
|+ seam.properties     // empty file but needed
|+ META-INF
   |+ ejb-jar.xml
   |+ persistence.xml</pre>
<p><strong>seam.properties</strong>
文档这儿是空但必需的，因为Jboss要通过它知道此JAR文件包含Seam EJB3 
bean类，并且相应地处理注解。</p>
<p><strong>ejb-jar.xml</strong>
文档包含额外的配置信息，这些信息能重载或者增补EJB3 
bean上的注解。在一个Seam应用中，它能将所有的EJB3 类加入Seam拦截器。我们能在所有的Seam应用中重用该文档。</p>
<pre>&lt;ejb-jar&gt;
  &lt;assembly-descriptor&gt;
    &lt;interceptor-binding&gt;
      &lt;ejb-name&gt;*&lt;/ejb-name&gt;
      &lt;interceptor-class&gt;
        org.jboss.seam.ejb.SeamInterceptor
      &lt;/interceptor-class&gt;
    &lt;/interceptor-binding&gt;
  &lt;/assembly-descriptor&gt;
&lt;/ejb-jar&gt;</pre>
<p><strong>persistence.xml</strong>
文档为EJB3 实体bean配置了后台数据源。本例中，我们只是使用了被嵌入到JBoss 
AS中默认的HSQL数据库(也就是<strong>java:/DefaultDS</strong>
数据源)。</p>
<pre>&lt;persistence&gt;
  &lt;persistence-unit name=&quot;helloworld&quot;&gt;
    &lt;provider&gt;
      org.hibernate.ejb.HibernatePersistence
    &lt;/provider&gt;
    &lt;jta-data-source&gt;java:/DefaultDS&lt;/jta-data-source&gt;
    &lt;properties&gt;
      &lt;property name=&quot;hibernate.dialect&quot;
          value=&quot;org.hibernate.dialect.HSQLDialect&quot;/&gt;
      &lt;property name=&quot;hibernate.hbm2ddl.auto&quot;
          value=&quot;create-drop&quot;/&gt;
      &lt;property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/&gt;
    &lt;/properties&gt;
  &lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre>
<p>这样，以上就是一个简单Seam应用所需的所有配置和打包。我们将在以后讨论到本书的更高级的主题时，涵盖更多的配置选项和类库。再次强调一下，Seam应用入门最简单的方法就是，不要担心这些配置文件，只需要从已有的应用模板做起。</p>
<h3>6. 为何这么简单？</h3>
<p>这就是hello world 
应用，三个简单的Java类，一个JSF页面，一组静态配置文件。我们已经有了一个完整的数据库驱动的web应用。整个应用只需要的是少于30行的Java代码，没有一处&ldquo;XML代码&rdquo;。但是如果开发者有PHP背景，你可能仍然会问&ldquo;何以这么简单？我能在php中使用更少的代码吗？&rdquo;</p>
<p>好吧，答案就是Seam应用在理论上要比PHP（或者其他任何一种脚本语言）应用简单的多。Seam 
组件模式允许我们，有所控制地，可维护地给应用增加更多的功能。我们很快就会发现，Seam组件使开发有状态的和有事务的web应用变得易如反掌。对象关系映射框架（例如：实体bean）允许我们将注意力放在抽象数据模型上，而不需要处理数据库特有的SQL语句。</p>
<p>本文是基于该书的第一章和第二章。后面的章节中，我们继续讨论如何使用Seam组件继续开发复杂的Seam 应用。参见<a href="../../../resource/articles/jboss-seam/zh/resources/seam-book-toc.pdf;jsessionid=1A0D677EF0D8B8B6A9F90C93E7E45F4C">本书目录</a>
来查看本书的所有主题。</p>
<p>请看Gavin King的两个访谈录来查看以往关于Seam的话题。</p>
<ul>
<li>JBoss Seam 1.1 Indepth: An Interview with Gavin King 
</li>
<li>JBoss Seam 1.0: rethinking web application architecture </li>
</ul>
<h2>关于作者</h2>
<p>Dr. Michael Yuan是<a href="http://www.michaelyuan.com/seam/;jsessionid=1A0D677EF0D8B8B6A9F90C93E7E45F4C">JBoss 
Seam: Simplicity and Power Beyond Java EE 5.0</a>
一书的作者。该书探讨了下一代web应用框架。他同时也是<a href="http://www.michaelyuan.com/blog/nokia-smartphone-hacks/;jsessionid=1A0D677EF0D8B8B6A9F90C93E7E45F4C">Nokia 
Smartphone 
Hacks</a>
一书和其他三本技术读物的作者。Michael潜心研究轻量级企业web应用，终端对终端的移动应用开发。你可以通过他的博客联系他。</p>
<p><strong>查看英文原文：</strong>
<a href="http://www.infoq.com/articles/jboss-seam;jsessionid=1A0D677EF0D8B8B6A9F90C93E7E45F4C">Introduction 
to JBoss Seam</a>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://seam.group.javaeye.com