<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>julycn</title>
    <description>QQ群：Java开源论坛[36885039]

MSN:julycn@live.com

想更多的人帮助你，请先帮助更多的人……</description>
    <link>http://julycn.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>深入浅出JBoss Seam</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/200884" style="color:red;">http://julycn.javaeye.com/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://julycn.javaeye.com/blog/200884#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, 06 Jun 2008 13:12:52 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/200884</link>
        <guid>http://julycn.javaeye.com/blog/200884</guid>
      </item>
      <item>
        <title>Gwt-Ext学习笔记之中级篇</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/192772" style="color:red;">http://julycn.javaeye.com/blog/192772</a>&nbsp;
          发表时间: 2008年05月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;">Gwt-Ext<span style="font-family: 宋体;">学习笔记之中级篇</span>
</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>一、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">配置</span>
Gwt-Ext<span style="font-family: 宋体;">开发环境</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">请参照</span>
<a href="../../blog/191634">Gwt-Ext<span style="font-family: 宋体;">学习笔记之基础篇</span>
</a>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">此教程是在</span>
<a href="../../blog/191634"><span style="font-family: 宋体;">基础篇</span>
</a>
<span style="font-family: 宋体;">和</span>
<a href="../../blog/191819"><span style="font-family: 宋体;">进级篇</span>
</a>
<span style="font-family: 宋体;">的基础上做的扩展，具体细节请参照前面教程。</span>
</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>二、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">在</span>
gwtext<span style="font-family: 宋体;">项目上创建客户端模型文件</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">创建模型文件</span>
InfoList.java,<span style="font-family: 宋体;">内容如下</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">public class InfoList implements EntryPoint {

	public void onModuleLoad() {

		ExtElement main = Ext.get(&quot;main&quot;);

		Panel mainPanel = new Panel() {
			{
				setTitle(&quot;测试&quot;);
				setHeight(300);
				setWidth(500);
				setFrame(true);
				setHtml(&quot;&lt;p&gt;如果看到这些信息，说明你的环境已经配置成功了！&lt;/p&gt;&quot;);
				setStyle(&quot;margin: 10px 0px 0px 10px;&quot;);
			}
		};

		if (main != null) {
			mainPanel.setApplyTo(main.getDOM());
			mainPanel.render(&quot;&quot;);
		} else {
			RootPanel.get().add(mainPanel);
		}
	}

}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">修改</span>
HTML<span style="font-family: 宋体;">宿主页面</span>
InfoList.html<span style="font-family: 宋体;">文件</span>
</p>
<p class="MsoNormal" style="margin-left: 1.5in; text-indent: -1.5in;"><!-- [if !supportLists]--><span><span><span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
i.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">在</span>
InfoList.html<span style="font-family: 宋体;">文件中加入以下代码</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">&lt;link href=&quot;js/resources/css/ext-all.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;/&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/ext-all.js&quot;&gt;&lt;/script&gt;
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">在</span>
InfoList.gwt.xml<span style="font-family: 宋体;">文件中加入以下代码</span>
</p>
<pre name="code" class="java">&lt;inherits name=&quot;com.gwtext.GwtExt&quot;/&gt;</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>d.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">测试环境是否配置成功</span>
,<span style="font-family: 宋体;">运行方式参考</span>
<a href="../../blog/191634">Gwt-Ext<span style="font-family: 宋体;">学习笔记之基础篇</span>
</a>
,<span style="font-family: 宋体;">效果如下图</span>
</p>
<p class="MsoNormal" style="margin-left: 1in;"><!-- [if gte vml 1]><v:shapetype
 id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
 path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
 <v:stroke joinstyle="miter"/>
 <v:formulas>
  <v:f eqn="if lineDrawn pixelLineWidth 0"/>
  <v:f eqn="sum @0 1 0"/>
  <v:f eqn="sum 0 0 @1"/>
  <v:f eqn="prod @2 1 2"/>
  <v:f eqn="prod @3 21600 pixelWidth"/>
  <v:f eqn="prod @3 21600 pixelHeight"/>
  <v:f eqn="sum @0 0 1"/>
  <v:f eqn="prod @6 1 2"/>
  <v:f eqn="prod @7 21600 pixelWidth"/>
  <v:f eqn="sum @8 21600 0"/>
  <v:f eqn="prod @7 21600 pixelHeight"/>
  <v:f eqn="sum @10 21600 0"/>
 </v:formulas>
 <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
 <o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style="width:404.25pt;
 height:341.25pt" mce_style="width:404.25pt;
 height:341.25pt">
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg" mce_src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg"
  o:title="546VN[%4S{L4FLX(DOH~[OO"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../upload/picture/pic/14299/ffb2eccc-552a-3e8e-8d45-bc350ce008d0.jpg" border="0" height="455" alt="" style="border: 0;" width="539" />
<!-- [endif]--></p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>三、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">定义服务</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">在</span>
gwtext<span style="font-family: 宋体;">项目上，创建名为</span>
InfoListAction.java<span style="font-family: 宋体;">远程服务接口。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">把</span>
PostgreSQL<span style="font-family: 宋体;">数据库的</span>
 JDBC<span style="font-family: 宋体;">包</span>
postgresql-8.2-505.jdbc3.jar<span style="font-family: 宋体;">加入到项目中（其他数据库，加入相应的</span>
 JDBC<span style="font-family: 宋体;">包）。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">远程服务的实现类，在</span>
InfoListActionImpl.java<span style="font-family: 宋体;">中加入如下代码：</span>
</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public class InfoListActionImpl extends RemoteServiceServlet implements
		InfoListAction {

	public String[][] queryData() {
		Connection conn = null;
		String[][] allInfo = null;
		try {
			Class.forName(&quot;org.postgresql.Driver&quot;);
			String connString = &quot;jdbc:postgresql://127.0.0.1:5432/gwtext&quot;;
conn = DriverManager.getConnection(connString, &quot;julycn&quot;, &quot;julycn&quot;);
String sqlQuery = &quot;select username,password,email,phone from person&quot;;
			Statement stmt = conn.createStatement(
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
			ResultSet rst = stmt.executeQuery(sqlQuery);

			// 行数
			int rows = 0;
			if (rst.last()) {
				rows = rst.getRow();
				rst.beforeFirst();
			}

			// 表的列数
			ResultSetMetaData rsm = rst.getMetaData();
			int columns = rsm.getColumnCount();

			// 初始化输组
			allInfo = new String[rows][columns];

			int i = 0;
			while (rst.next()) {
				for (int j = 0; j &lt; columns; j++) {
					allInfo[i][j] = rst.getString(j + 1);
				}
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return allInfo;
	}

}
</pre>
&nbsp;
<p class="MsoNormal" style="margin: 0in 0in 0.0001pt 1in; line-height: normal;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;;"></span>
</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>四、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">绑定代码</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">定义一个远程接口类</span>
InfoListAction.java,<span style="font-family: 宋体;">代码如下：</span>
</p>
<p class="MsoNormal" style="margin: 0in 0in 0.0001pt 1in; line-height: normal;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in;">&nbsp;</p>
<pre name="code" class="java">/**
 * @author 七月天
 * 
 */
public interface InfoListAction extends RemoteService {

	public static final String SERVICE_URI = &quot;/InfoListAction&quot;;

	public static class Util {

		public static InfoListActionAsync getInstance() {

			InfoListActionAsync instance = (InfoListActionAsync) GWT
					.create(InfoListAction.class);
			ServiceDefTarget target = (ServiceDefTarget) instance;
			target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);
			return instance;
		}
	}

	public String[][] queryData();
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">定义远程异步接口类</span>
InfoListActionAsync.java<span style="font-family: 宋体;">，代码如下：</span>
</p>
<pre name="code" class="java">/**
 * @author 七月天
 * 
 */
public interface InfoListActionAsync {

	public void queryData(AsyncCallback callback);
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin: 0in 0in 0.0001pt 1in; line-height: normal;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in;">&nbsp;</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">注册服务器代码，将下面的一行加入到</span>
InfoList.gwt.xml<span style="font-family: 宋体;">中</span>
</p>
<p class="MsoNormal" style="margin: 0in 0in 0.0001pt 1in; line-height: normal;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: teal;"></span>
</p>
<pre name="code" class="java">&lt;servlet class=&quot;com.gwtext.julycn.server.InfoListActionImpl&quot; path=&quot;/InfoListAction&quot; /&gt;</pre>
&nbsp;
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>五、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">执行客户端调用</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">修改模型文件</span>
InfoList.java,<span style="font-family: 宋体;">代码如下：</span>
</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public class InfoList implements EntryPoint {

	public void onModuleLoad() {
		InfoListActionAsync action = InfoListAction.Util.getInstance();
		action.queryData(new AsyncCallback() {

			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				Panel panel = new Panel();
				panel.setBorder(false);
				panel.setPaddings(15);

				RecordDef recordDef = new RecordDef(new FieldDef[] {
						new StringFieldDef(&quot;username&quot;),
						new StringFieldDef(&quot;password&quot;),
						new StringFieldDef(&quot;email&quot;),
						new StringFieldDef(&quot;phone&quot;) });

				final GridPanel grid = new GridPanel();

				String[][] data = (String[][]) result;

				MemoryProxy proxy = new MemoryProxy(data);

				ArrayReader reader = new ArrayReader(recordDef);
				Store store = new Store(proxy, reader);
				store.load();
				grid.setStore(store);

				ColumnConfig[] columns = new ColumnConfig[] {
new ColumnConfig(&quot;用户名&quot;, &quot;username&quot;, 160, true, null,&quot;username&quot;),
						new ColumnConfig(&quot;密码&quot;, &quot;password&quot;, 45),
						new ColumnConfig(&quot;邮箱&quot;, &quot;email&quot;, 65),
						new ColumnConfig(&quot;电话&quot;, &quot;phone&quot;, 65) };

				ColumnModel columnModel = new ColumnModel(columns);
				grid.setColumnModel(columnModel);

				grid.setFrame(true);
				grid.setStripeRows(true);
				grid.setAutoExpandColumn(&quot;username&quot;);

				grid.setHeight(350);
				grid.setWidth(600);
				grid.setTitle(&quot;用户信息&quot;);

				Toolbar bottomToolbar = new Toolbar();
				bottomToolbar.addFill();
				bottomToolbar.addButton(new ToolbarButton(&quot;清除排序&quot;,
						new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
								grid.clearSortState(true);
							}
						}));
				grid.setBottomToolbar(bottomToolbar);

				panel.add(grid);

				RootPanel.get().add(panel);

			}

		});
	}
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin: 0in 0in 0.0001pt 1in; line-height: normal;"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in;">&nbsp;</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]-->AsyncCallback <span style="font-family: 宋体;">接口定义了两个方法：</span>
onSuccess(Object result) <span style="font-family: 宋体;">和</span>
<span>&nbsp;
</span>
onFailure(Throwable caught)<span style="font-family: 宋体;">。必须定义一个可以实现这两个方法的类。当执行远程调用时，模型类的实例并将其传递给异步服务方法。最后，服务器端资源完成，然后调用代码中两个方法之一。成功方法的参数是接口和实现中的调用的返回值。</span>
</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>六、</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">展示效果</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span style="font-family: 宋体;">凌晨1点了，收工睡觉；先看看效果吧</span>
</p>
<p class="MsoNormal" style="margin-left: 0.75in;"><!-- [if gte vml 1]><v:shape id="_x0000_i1026"
 type="#_x0000_t75" style="width:498.75pt;height:385.5pt" mce_style="width:498.75pt;height:385.5pt">
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image002.jpg" mce_src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image002.jpg"
  o:title="_8EW`35B7Y@RZM6RRBG5CX5"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../upload/picture/pic/14301/948fc2d0-4cb7-3da9-902f-797b3d50b61d.jpg" border="0" height="514" alt="" style="border: 0;" width="665" />
<!-- [endif]--></p>
<p class="MsoNormal" style="margin-left: 40.5pt;">&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://julycn.javaeye.com/blog/192772#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 May 2008 00:41:17 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/192772</link>
        <guid>http://julycn.javaeye.com/blog/192772</guid>
      </item>
      <item>
        <title>Gwt-Ext学习笔记之进级篇</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/191819" style="color:red;">http://julycn.javaeye.com/blog/191819</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;">Gwt-Ext<span lang="ZH-CN" style="font-family: 宋体;">学习笔记之进级篇</span>
<span style="font-family: 宋体;"></span>
</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>一、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">定义服务</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: 0.5in;">GWT<span lang="ZH-CN" style="font-family: 宋体;">过程调用大部分在两个类进行。在服务器端，定义一个</span>
RemoteServiceServlet<span lang="ZH-CN" style="font-family: 宋体;">子类</span>
RegisterActionImpl.java<span lang="ZH-CN" style="font-family: 宋体;">（远程服务实现类）。在这个类中，将操作数据库并将值返回给客户机。在客户端，定义一个实现</span>
AsyncCallback<span lang="ZH-CN" style="font-family: 宋体;">接口的类</span>
Register.java<span lang="ZH-CN" style="font-family: 宋体;">（客户端实现类），在这个类中，定义服务器操作完成时客户机页面如何处理数据（或异常）。除了这两个类之外，必须编写一些绑定代码使</span>
GWT-Ext <span lang="ZH-CN" style="font-family: 宋体;">可以将客户端类和服务器端类绑定在一起</span>
, <span lang="ZH-CN" style="font-family: 宋体;">绑定代码包含</span>
RegisterAction.java<span lang="ZH-CN" style="font-family: 宋体;">（远程接口）和</span>
RegisterActionAsync.java<span lang="ZH-CN" style="font-family: 宋体;">（远程异步接口）两个不同的接口外加一些客户端代码以及一两个设置。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在</span>
gwtext<span lang="ZH-CN" style="font-family: 宋体;">项目上点击右键，选择</span>
New&mdash;Other&mdash;Remote Service,<span lang="ZH-CN" style="font-family: 宋体;">创建名为</span>
RegisterAction<span lang="ZH-CN" style="font-family: 宋体;">的远程服务接口。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in;"><!-- [if gte vml 1]><v:shapetype
 id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
 path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
 <v:stroke joinstyle="miter"/>
 <v:formulas>
  <v:f eqn="if lineDrawn pixelLineWidth 0"/>
  <v:f eqn="sum @0 1 0"/>
  <v:f eqn="sum 0 0 @1"/>
  <v:f eqn="prod @2 1 2"/>
  <v:f eqn="prod @3 21600 pixelWidth"/>
  <v:f eqn="prod @3 21600 pixelHeight"/>
  <v:f eqn="sum @0 0 1"/>
  <v:f eqn="prod @6 1 2"/>
  <v:f eqn="prod @7 21600 pixelWidth"/>
  <v:f eqn="sum @8 21600 0"/>
  <v:f eqn="prod @7 21600 pixelHeight"/>
  <v:f eqn="sum @10 21600 0"/>
 </v:formulas>
 <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
 <o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:381pt;
 height:381.75pt'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg"
  o:title="0K3Y2Y{8JRRW2OY65{OSALV"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../upload/picture/pic/14109/4f58d19f-5d73-3137-9e86-695df7ce8945.jpg" height="509" alt="" width="508" />
<!-- [endif]--></p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">把</span>
PostgreSQL<span lang="ZH-CN" style="font-family: 宋体;">数据库的</span>
JDBC<span lang="ZH-CN" style="font-family: 宋体;">包</span>
postgresql-8.2-505.jdbc3.jar<span lang="ZH-CN" style="font-family: 宋体;">加入到项目中（其他数据库，加入相应的</span>
JDBC<span lang="ZH-CN" style="font-family: 宋体;">包）。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">远程服务的实现类，在</span>
RegisterActionImpl.java<span lang="ZH-CN" style="font-family: 宋体;">中加入如下代码：</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public class RegisterActionImpl extends RemoteServiceServlet implements RegisterAction {

	private static final long serialVersionUID = 1L;

	public void saveData(Map formData) {
		Connection conn=null;
		try {
			Class.forName(&quot;org.postgresql.Driver&quot;);
			String connString=&quot;jdbc:postgresql://127.0.0.1:5432/gwtext&quot;;
			conn=DriverManager.getConnection(connString,&quot;julycn&quot;,&quot;julycn&quot;);
			StringBuffer sqlQuery=new StringBuffer(&quot;insert into person (username,password,email,phone) &quot;);
			sqlQuery.append(&quot;values(?,?,?,?)&quot;);
			PreparedStatement stmt=conn.prepareStatement(sqlQuery.toString());
			stmt.setString(1, URLDecoder.decode(formData.get(&quot;username&quot;).toString(),&quot;UTF-8&quot;));
			stmt.setString(2, URLDecoder.decode(formData.get(&quot;password&quot;).toString(),&quot;UTF-8&quot;));
			stmt.setString(3, URLDecoder.decode(formData.get(&quot;email&quot;).toString(),&quot;UTF-8&quot;));
			stmt.setString(4, URLDecoder.decode(formData.get(&quot;phone&quot;).toString(),&quot;UTF-8&quot;));
			stmt.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(conn!=null){
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; line-height: normal;"><span style="color: red;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>d.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]-->GWT-Ext<span lang="ZH-CN" style="font-family: 宋体;">远程服务的要求很简单，它必须扩展</span>
RemoteServiceServlet<span lang="ZH-CN" style="font-family: 宋体;">并实现一个接口。</span>
</p>
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>二、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">绑定代码</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">要使新程序可用于客户端应用程序，必须定义两个接口。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">定义一个远程接口类</span>
RegisterAction.java<span lang="ZH-CN" style="font-family: 宋体;">，代码如下</span>
</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public interface RegisterAction extends RemoteService {

	public static final String SERVICE_URI = &quot;/RegisterAction&quot;;

	public static class Util {

		public static RegisterActionAsync getInstance() {

			RegisterActionAsync instance = (RegisterActionAsync) GWT
					.create(RegisterAction.class);
			ServiceDefTarget target = (ServiceDefTarget) instance;
			target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);
			return instance;
		}
	}

	public void saveData(Map formData);
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in;"><span style="color: red;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在这里完成的所有操作是获得用于实际的具体类中方法的同一个签名。这里的主要限制是接口必须扩展</span>
com.google.gwt.user.client.rpc.RemoteService;<span lang="ZH-CN" style="font-family: 宋体;">。此外，参数和返回值必须属于</span>
GWT <span lang="ZH-CN" style="font-family: 宋体;">可以序列化的类型</span>
(<span lang="ZH-CN" style="font-family: 宋体;">见备注</span>
)<span lang="ZH-CN" style="font-family: 宋体;">。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>d.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">定义远程异步接口</span>
RegisterActionAsync.java
<span lang="ZH-CN" style="font-family: 宋体;">，代码如下：</span>
</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public interface RegisterActionAsync {

	public void saveData(Map formData, AsyncCallback callback);
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>e.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">远程异步类的服务接口是从上面描述的远程服务类中派生出来的。两个类必须位于同一个包中，并且该包必须对</span>
GWT-EXT <span lang="ZH-CN" style="font-family: 宋体;">客户机代码可见。远程异步类中的类名必须是远程服务接口的名称且末尾附加字符串</span>
Async<span lang="ZH-CN" style="font-family: 宋体;">。对于远程服务接口中的每个方法，远程异步类必须有一个返回类型更改为</span>
 void <span lang="ZH-CN" style="font-family: 宋体;">的匹配方法和一个</span>
 AsyncCallback <span lang="ZH-CN" style="font-family: 宋体;">类型的附加参数。客户端代码将使用</span>
AsyncCallback <span lang="ZH-CN" style="font-family: 宋体;">作用于服务器响应上。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>f.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">注册服务器代码，将下面的一行加入到</span>
Register.gwt.xml<span lang="ZH-CN" style="font-family: 宋体;">中</span>
</p>
<pre name="code" class="java">&lt;servlet class=&quot;com.gwtext.julycn.server.RegisterActionImpl&quot; path=&quot;/RegisterAction&quot; /&gt;</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>三、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">执行客户端调用</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">完成服务器端操作以后，现在应该让客户机执行过程调用了。在这里基本的想法是慎重地告诉</span>
GWT <span lang="ZH-CN" style="font-family: 宋体;">系统正在调用的是哪个远程服务。然后将</span>
 AsyncCallback <span lang="ZH-CN" style="font-family: 宋体;">对象发送出去；最后，</span>
GWT <span lang="ZH-CN" style="font-family: 宋体;">将其送回，您可对结果进行操作。修改模型文件</span>
Register.java<span lang="ZH-CN" style="font-family: 宋体;">，代码如下：</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public class Register implements EntryPoint,AsyncCallback {
	public void onModuleLoad() {
		createComponents();
	}

	private void createComponents() {
		final FormPanel frm = new FormPanel();
		frm.setDraggable(true);
		frm.setWidth(300);
		frm.setTitle(&quot;用户注册&quot;);
		frm.setPaddings(25);

		TextField txtUsername = new TextField(&quot;用户名&quot;, &quot;username&quot;);
		TextField txtPassword = new TextField(&quot;密码&quot;, &quot;password&quot;);
		TextField txtEmail = new TextField(&quot;邮箱&quot;, &quot;email&quot;);
		TextField txtPhone = new TextField(&quot;电话&quot;, &quot;phone&quot;);

		txtUsername.setRegex(&quot;^[a-zA-Z]*$&quot;);
		txtUsername.setRegexText(&quot;用户名必须为字母！&quot;);
		txtUsername.setAllowBlank(false);

		txtPassword.setPassword(true);
		txtPassword.setRegex(&quot;^[a-zA-Z]*$&quot;);
		txtPassword.setRegexText(&quot;密码必须为字母！&quot;);
		txtPassword.setAllowBlank(false);

		txtEmail.setVtype(VType.EMAIL);
		txtEmail.setVtypeText(&quot;请输入合法的邮箱地址！&quot;);
		txtEmail.setAllowBlank(false);

		txtPhone.setRegex(&quot;^\\d*$&quot;);
		txtPhone.setRegexText(&quot;电话必须为数字！&quot;);
		txtPhone.setAllowBlank(false);

		frm.add(txtUsername);
		frm.add(txtPassword);
		frm.add(txtEmail);
		frm.add(txtPhone);

		Panel buttonPanel = new Panel();
		buttonPanel.setLayout(new HorizontalLayout(10));

		final AsyncCallback callback=this;
		
		Button btnSave = new Button(&quot;保存&quot;);
		btnSave.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				if (frm.getForm().isValid()) {
					RegisterActionAsync action=RegisterAction.Util.getInstance();
					Map formData=getFormDataAsMap(frm.getForm());
					action.saveData(formData, callback);
				} else {
					MessageBox.alert(&quot;错误&quot;,&quot;请验证输入的信息是否正确！&quot;);
				}
			}
		});

		Button btnClear = new Button(&quot;取消&quot;);
		btnClear.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				MessageBox.alert(&quot;取消&quot;, &quot;注册信息保存失败！&quot;);
			}
		});

		buttonPanel.add(btnSave);
		buttonPanel.add(btnClear);

		frm.add(buttonPanel);

		RootPanel.get().add(frm);
	}
	
	public Map getFormDataAsMap(Form form){
		
		String formValues=form.getValues();
		Map formData=new HashMap();
		String[] nameValuePairs=formValues.split(&quot;&amp;&quot;);
		
		for(int i=0;i&lt;nameValuePairs.length;++i){
			String[] oneItem=nameValuePairs[i].split(&quot;=&quot;);
			formData.put(oneItem[0], oneItem[1]);
		}
		
		return formData;
	}

	public void onFailure(Throwable caught) {
		MessageBox.alert(&quot;失败&quot;,&quot;数据保存失败！&quot;);
	}

	public void onSuccess(Object result) {
		MessageBox.alert(&quot;成功&quot;,&quot;数据保存成功！&quot;);
	}
}
</pre>
&nbsp;
<p class="MsoNormal" style="margin-left: 1in;"><span style="color: red;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]-->AsyncCallback <span lang="ZH-CN" style="font-family: 宋体;">接口定义了两个方法：</span>
onSuccess(Object
result) <span lang="ZH-CN" style="font-family: 宋体;">和</span>
 onFailure(Throwable caught)<span lang="ZH-CN" style="font-family: 宋体;">。必须定义一个可以实现这两个方法的类。当执行远程调用时，模型类的实例并将其传递给异步服务方法。最后，服务器端资源完成，然后调用代码中两个方法之一。成功方法的参数是接口和实现中的调用的返回值。</span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">运行一下，看看效果吧！</span>
^o^</p>
<p class="MsoNormal" style="margin-left: 1in;"><span lang="ZH-CN" style="font-family: 宋体; color: red;">备注：</span>
<span style="color: red;"></span>
</p>
<p class="MsoNormal" style="margin-left: 1in; text-indent: 0.5in;"><span lang="ZH-CN" style="font-family: 宋体; color: red;">怎样的字段才是可序列化字段？首先，该字段可属于一个实现了</span>
<span style="color: red;">
com.google.gwt.user.client.rpc.IsSerializable </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">的类型，或者具有一个实现了</span>
<span style="color: red;"> IsSerializable </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">的超类。或者，该字段可以是基本类型之一，其中包括</span>
<span style="color: red;"> Java
</span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">原语，所有原语包装类，</span>
<span style="color: red;">Date </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">和</span>
<span style="color: red;"> String</span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">。序列化类型的数组或集合也是序列化的。但是，如果要将一个</span>
<span style="color: red;"> Collection </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">或</span>
<span style="color: red;"> List </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">序列化，</span>
<span style="color: red;">GWT </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">希望您用一个指定实际类型的</span>
<span style="color: red;"> Javadoc </span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">注释对其评注，以便编译器可以使其最优化。</span>
<span style="color: red;"></span>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://julycn.javaeye.com/blog/191819#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, 11 May 2008 00:03:39 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/191819</link>
        <guid>http://julycn.javaeye.com/blog/191819</guid>
      </item>
      <item>
        <title>Gwt-Ext学习笔记之基础篇</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/191634" style="color:red;">http://julycn.javaeye.com/blog/191634</a>&nbsp;
          发表时间: 2008年05月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p>&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;">Gwt-Ext<span lang="ZH-CN" style="font-family: 宋体;">学习笔记之基础篇</span>
</p>
<p class="MsoListParagraphCxSpFirst" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>一、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">安装</span>
Cypal Studio<span lang="ZH-CN" style="font-family: 宋体;">工具</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">下载</span>
Cypal
Studio <a href="http://code.google.com/p/cypal-studio/">http://code.google.com/p/cypal-studio/</a>
<span lang="ZH-CN" style="font-family: 宋体;">，解压后</span>
Copy<span lang="ZH-CN" style="font-family: 宋体;">到</span>
Eclipse<span lang="ZH-CN" style="font-family: 宋体;">目录下。</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">配置</span>
GWT Home<span lang="ZH-CN" style="font-family: 宋体;">目录，打开</span>
Eclipse<span lang="ZH-CN" style="font-family: 宋体;">的</span>
Window&mdash;Preferences&mdash;Cypal Studio <span lang="ZH-CN" style="font-family: 宋体;">选择</span>
Gwt<span lang="ZH-CN" style="font-family: 宋体;">的目录。</span>
<a href="../../../upload/picture/pic/14049/296c31b5-593d-32e9-abf8-17e131b0b78e.jpg"><span><!-- [if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600"
 o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f"
 stroked="f">
 <v:stroke joinstyle="miter"/>
 <v:formulas>
  <v:f eqn="if lineDrawn pixelLineWidth 0"/>
  <v:f eqn="sum @0 1 0"/>
  <v:f eqn="sum 0 0 @1"/>
  <v:f eqn="prod @2 1 2"/>
  <v:f eqn="prod @3 21600 pixelWidth"/>
  <v:f eqn="prod @3 21600 pixelHeight"/>
  <v:f eqn="sum @0 0 1"/>
  <v:f eqn="prod @6 1 2"/>
  <v:f eqn="prod @7 21600 pixelWidth"/>
  <v:f eqn="sum @8 21600 0"/>
  <v:f eqn="prod @7 21600 pixelHeight"/>
  <v:f eqn="sum @10 21600 0"/>
 </v:formulas>
 <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
 <o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1031" type="#_x0000_t75" style='width:6in;
 height:376.5pt;visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg"
  o:title="CC]M]A$){9J96N}HR4[~XUD"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14049/296c31b5-593d-32e9-abf8-17e131b0b78e.jpg" border="0" height="502" alt="" style="border: 0;" width="576" />
<!-- [endif]--></span>
</a>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;">&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>二、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">建立一个名为</span>
gwtext<span lang="ZH-CN" style="font-family: 宋体;">的</span>
GWT<span lang="ZH-CN" style="font-family: 宋体;">项目</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">新建一个动态</span>
web<span lang="ZH-CN" style="font-family: 宋体;">项目，</span>
File&mdash;New&mdash;Other&mdash;Web&mdash;Dynamic Web Project<span lang="ZH-CN" style="font-family: 宋体;">，在</span>
Configurations<span lang="ZH-CN" style="font-family: 宋体;">中选择</span>
Cypal Studio GWT Project<span lang="ZH-CN" style="font-family: 宋体;">，其他的默认即可。</span>
<span><!-- [if gte vml 1]><v:shape id="Picture_x0020_2"
 o:spid="_x0000_i1030" type="#_x0000_t75" style='width:6in;height:387.75pt;
 visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image003.jpg"
  o:title="D7V5Y}ICZDVT{5(U0(1}X40"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14047/20fcc65c-1d16-3906-8b8a-3085767964d5.jpg" border="0" height="517" alt="" style="border: 0;" width="576" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>三、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">创建</span>
Module<span lang="ZH-CN" style="font-family: 宋体;">模型</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]-->gwtext<span lang="ZH-CN" style="font-family: 宋体;">项目上点击右键</span>
New&mdash;Other&mdash;Cypal Studio&mdash;Module<span lang="ZH-CN" style="font-family: 宋体;">，输入包名</span>
org.gwtext.julycn,<span lang="ZH-CN" style="font-family: 宋体;">类名</span>
Register<span lang="ZH-CN" style="font-family: 宋体;">。</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在</span>
org.gwtext.julycn<span lang="ZH-CN" style="font-family: 宋体;">包下面生产</span>
client<span lang="ZH-CN" style="font-family: 宋体;">包、</span>
server<span lang="ZH-CN" style="font-family: 宋体;">包、</span>
public<span lang="ZH-CN" style="font-family: 宋体;">目录和</span>
Register.gwt.xml<span lang="ZH-CN" style="font-family: 宋体;">、</span>
Register.html<span lang="ZH-CN" style="font-family: 宋体;">；</span>
<span><!-- [if gte vml 1]><v:shape
 id="Picture_x0020_1" o:spid="_x0000_i1029" type="#_x0000_t75" style='width:200.25pt;
 height:189.75pt;visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image004.jpg"
  o:title="D7]`$E$}RDJJ_7RZ5D[MKQK"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14045/620468f6-787d-3869-9172-7f141866b38b.jpg" border="0" height="253" alt="" style="border: 0;" width="267" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在</span>
Register.java<span lang="ZH-CN" style="font-family: 宋体;">的</span>
<span style="color: red;">onModuleLoad()</span>
<span lang="ZH-CN" style="font-family: 宋体;">方法中加入</span>
<span style="color: red;">Window.alert(&quot;This is my first Gwt Demo!&quot;);</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */

public class Register implements EntryPoint {
	public void onModuleLoad() {
			Window.alert(&quot;This is my first Gwt Demo!&quot;);
		}
}
</pre>
&nbsp;
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;"><span style="color: red;"></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>d.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">选择</span>
Run&mdash;Open Run
Dialog&mdash;Gwt Hosted Mode Application,<span lang="ZH-CN" style="font-family: 宋体;">选择</span>
New,<span lang="ZH-CN" style="font-family: 宋体;">新建一个运行实例</span>
gwtext,<span lang="ZH-CN" style="font-family: 宋体;">在</span>
Project<span lang="ZH-CN" style="font-family: 宋体;">中选择</span>
gwtext<span lang="ZH-CN" style="font-family: 宋体;">，</span>
Module<span lang="ZH-CN" style="font-family: 宋体;">会自动选择所要运行的模型类。</span>
<span><!-- [if gte vml 1]><v:shape id="Picture_x0020_3"
 o:spid="_x0000_i1028" type="#_x0000_t75" style='width:468.75pt;height:420pt;
 visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image006.jpg"
  o:title="VI8_ESE7QQ(`I_Q0%][0)}0"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14043/db172cf8-7464-3d5c-87f0-238f2be7bed3.jpg" border="0" height="560" alt="" style="border: 0;" width="625" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>e.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">点击运行，会弹出</span>
Google
Web Toolkit<span lang="ZH-CN" style="font-family: 宋体;">运行窗口。</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>四、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">配置</span>
GWT-Ext<span lang="ZH-CN" style="font-family: 宋体;">环境</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">下载</span>
<a href="http://gwt-ext.googlecode.com/files/gwtext-2.0.3.zip">gwt-ext</a>
<span lang="ZH-CN" style="font-family: 宋体;">和</span>
<a href="http://www.extjs.com/products/extjs/download.php?dl=extjs21">ext</a>
<span lang="ZH-CN" style="font-family: 宋体;">资源</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">加入</span>
gwtext<span lang="ZH-CN" style="font-family: 宋体;">的</span>
gwtext.jar<span lang="ZH-CN" style="font-family: 宋体;">和</span>
ext<span lang="ZH-CN" style="font-family: 宋体;">资源</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -1.5in;"><!-- [if !supportLists]--><span><span><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
i.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">把</span>
gwtext-2.0.3<span lang="ZH-CN" style="font-family: 宋体;">目录下的</span>
gwtext.jar<span lang="ZH-CN" style="font-family: 宋体;">加入到项目中。</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -1.5in;"><!-- [if !supportLists]--><span><span><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
ii.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在项目的</span>
public<span lang="ZH-CN" style="font-family: 宋体;">目录中新建</span>
js<span lang="ZH-CN" style="font-family: 宋体;">文件夹，然后把</span>
ext-2.1<span lang="ZH-CN" style="font-family: 宋体;">目录下的</span>
adapter<span lang="ZH-CN" style="font-family: 宋体;">目录、</span>
resources<span lang="ZH-CN" style="font-family: 宋体;">目录和</span>
ext-all.js<span lang="ZH-CN" style="font-family: 宋体;">、</span>
ext-core.js<span lang="ZH-CN" style="font-family: 宋体;">导入到</span>
js<span lang="ZH-CN" style="font-family: 宋体;">文件夹下。</span>
<span><!-- [if gte vml 1]><v:shape id="Picture_x0020_4" o:spid="_x0000_i1027"
 type="#_x0000_t75" style='width:274.5pt;height:293.25pt;visibility:visible;
 mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image007.jpg"
  o:title="VI8_ESE7QQ(`I_Q0%][0)}0"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14041/fa33c12e-9fe4-3e9d-9324-e7ffec1b6549.jpg" border="0" height="391" alt="" style="border: 0;" width="366" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>c.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">修改</span>
HTML<span lang="ZH-CN" style="font-family: 宋体;">宿主页面</span>
Register.html<span lang="ZH-CN" style="font-family: 宋体;">和模块配置文件</span>
Register.gwt.xml</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -1.5in;"><!-- [if !supportLists]--><span><span><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
i.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在</span>
Register.html<span lang="ZH-CN" style="font-family: 宋体;">文件中加入</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">&lt;link href=&quot;js/resources/css/ext-all.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;/&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;js/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;js/ext-all.js&quot;&gt;&lt;/script&gt;
</pre>
&nbsp;
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1.5in; text-indent: -1.5in;"><!-- [if !supportLists]--><span><span><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
ii.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">在</span>
Register.gwt.xml<span lang="ZH-CN" style="font-family: 宋体;">文件中加入</span>
</p>
<pre name="code" class="java">&lt;inherits name=&quot;com.gwtext.GwtExt&quot;/&gt;</pre>
&nbsp;
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 40.5pt; text-indent: -22.5pt;"><!-- [if !supportLists]--><span><span>五、</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">运行</span>
GWT-Ext<span lang="ZH-CN" style="font-family: 宋体;">实例</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>a.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">修改</span>
Register.java<span lang="ZH-CN" style="font-family: 宋体;">模型文件</span>
,<span lang="ZH-CN" style="font-family: 宋体;">内容如下：</span>
</p>
<p>&nbsp;</p>
<pre name="code" class="java">/**
 * @author 七月天
 *
 */
public class Register implements EntryPoint{
	public void onModuleLoad() {
		createComponents();
	}

	private void createComponents() {
		final FormPanel frm = new FormPanel();
		frm.setDraggable(true);
		frm.setWidth(300);
		frm.setTitle(&quot;用户注册&quot;);
		frm.setPaddings(25);

		TextField txtUsername = new TextField(&quot;用户名&quot;, &quot;username&quot;);
		TextField txtPassword = new TextField(&quot;密码&quot;, &quot;password&quot;);
		TextField txtEmail = new TextField(&quot;邮箱&quot;, &quot;email&quot;);
		TextField txtPhone = new TextField(&quot;电话&quot;, &quot;phone&quot;);

		txtUsername.setRegex(&quot;^[a-zA-Z]*$&quot;);
		txtUsername.setRegexText(&quot;用户名必须为字母！&quot;);
		txtUsername.setAllowBlank(false);

		txtPassword.setPassword(true);
		txtPassword.setRegex(&quot;^[a-zA-Z]*$&quot;);
		txtPassword.setRegexText(&quot;密码必须为字母！&quot;);
		txtPassword.setAllowBlank(false);

		txtEmail.setVtype(VType.EMAIL);
		txtEmail.setVtypeText(&quot;请输入合法的邮箱地址！&quot;);
		txtEmail.setAllowBlank(false);

		txtPhone.setRegex(&quot;^\\d*$&quot;);
		txtPhone.setRegexText(&quot;电话必须为数字！&quot;);
		txtPhone.setAllowBlank(false);

		frm.add(txtUsername);
		frm.add(txtPassword);
		frm.add(txtEmail);
		frm.add(txtPhone);

		Panel buttonPanel = new Panel();
		buttonPanel.setLayout(new HorizontalLayout(10));

		
		Button btnSave = new Button(&quot;保存&quot;);
		btnSave.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				if (frm.getForm().isValid()) {
					MessageBox.alert(&quot;成功&quot;,&quot;信息提交成功！&quot;);
				} else {
					MessageBox.alert(&quot;错误&quot;,&quot;请验证输入的信息是否正确！&quot;);
				}
			}
		});

		Button btnClear = new Button(&quot;取消&quot;);
		btnClear.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				MessageBox.alert(&quot;取消&quot;, &quot;注册信息保存失败！&quot;);
			}
		});

		buttonPanel.add(btnSave);
		buttonPanel.add(btnClear);

		frm.add(buttonPanel);

		RootPanel.get().add(frm);
	}
}
</pre>
&nbsp;
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;"><span style="color: red;"></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in; text-indent: -0.25in;"><!-- [if !supportLists]--><span><span>b.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!-- [endif]--><span lang="ZH-CN" style="font-family: 宋体;">运行效果；点击如下按钮，查看效果</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;"><span><!-- [if gte vml 1]><v:shape id="Picture_x0020_5"
 o:spid="_x0000_i1026" type="#_x0000_t75" style='width:267pt;height:204pt;
 visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image009.jpg"
  o:title="@U]~I]}8C)~78LQR@T3FIP9"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14053/76658f2a-2ac2-32e6-8be1-3bbc19ed2043.jpg" border="0" height="272" alt="" style="border: 0;" width="356" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;"><span><!-- [if gte vml 1]><v:shape id="Picture_x0020_6"
 o:spid="_x0000_i1025" type="#_x0000_t75" style='width:310.5pt;height:316.5pt;
 visibility:visible;mso-wrap-style:square'>
 <v:imagedata src="file:///C:\DOCUME~1\Eric\LOCALS~1\Temp\msohtmlclip1\01\clip_image010.jpg"
  o:title="VI8_ESE7QQ(`I_Q0%][0)}0"/>
</v:shape><![endif]--><!-- [if !vml]--><img src="../../../upload/picture/pic/14051/36f13e16-88bb-3999-987a-54e5ad36ddd5.jpg" border="0" height="422" alt="" style="border: 0;" width="414" />
<!-- [endif]--></span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 1in;">&nbsp;</p>
<p class="MsoListParagraphCxSpLast" style="margin-left: 1in;"><span lang="ZH-CN" style="font-family: 宋体; color: red;">备注：本文只是一个简单的</span>
<span style="color: red;">Demo</span>
<span lang="ZH-CN" style="font-family: 宋体; color: red;">，如果有问题，请跟帖。想要更多的人帮助你，请先帮助更多的人</span>
<span style="color: red;"></span>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://julycn.javaeye.com/blog/191634#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, 10 May 2008 01:25:07 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/191634</link>
        <guid>http://julycn.javaeye.com/blog/191634</guid>
      </item>
      <item>
        <title>不错的歌曲，支持奥运，来自ANTI-CNN，转载</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/185696" style="color:red;">http://julycn.javaeye.com/blog/185696</a>&nbsp;
          发表时间: 2008年04月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="v080324_desTag">
<div class="des">不错的歌曲，反对CNN，支持奥运！！</div>
<div class="des"><br /></div>
<div class="des"><span class="t">视频描述：</span>
</div>
<div class="des">
<p class="gray wordwrap"><span id="videoMEMO">ANTI-CNN网站隆重推出，在新浪首发！<br />
《中国的复兴不可阻挡》<br />
词曲：邱国兴 
演唱：熊磊<br />
音乐制作：中盛唱片公司制作<br />
谁在说谎<br />
把中国绘成妖魔之邦<br />
把暴行说成是和平<br />
把文明和忍让说成野蛮<br />
谁在狂妄<br />
对中国内政信口雌黄<br />
惟恐不乱挑事端<br />
把阳光抹黑说成阴暗<br />
中国的复兴不可阻挡<br />
我们的前途不可限量<br />
挑拨让我们更团结<br />
伪善让眼睛更亮<br />
中国的复兴不可阻挡<br />
我们的未来必定灿烂<br />
逆境让我们更自强<br />
冬雪让梅花更香</span>
</p>
<p class="gray wordwrap">转载，地址：http://you.video.sina.com.cn/b/12556597-1367459121.html</p>
</div>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://julycn.javaeye.com/blog/185696#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, 23 Apr 2008 08:45:03 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/185696</link>
        <guid>http://julycn.javaeye.com/blog/185696</guid>
      </item>
      <item>
        <title>第一章：Seam简介</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/183753" style="color:red;">http://julycn.javaeye.com/blog/183753</a>&nbsp;
          发表时间: 2008年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;"><span style="font-size: 14pt; color: #ff6600;"><a href="../../blog/182221"><span style="color: #ff6600;">Seam</span>
<span style="font-family: 宋体; color: #ff6600;"><span lang="EN-US">开发工具参考指南</span>
</span>
<span style="color: #ff6600;">(</span>
<span style="font-family: 宋体; color: #ff6600;"><span lang="EN-US">目录</span>
</span>
<span style="color: #ff6600;">)</span>
</a>
</span>
</p>
<p class="MsoNormal" align="center" style="text-align: center;"><span lang="EN-US" style="font-size: 14pt;">&nbsp;</span>
</p>
<p class="MsoNormal" align="center" style="text-align: center;"><span style="font-size: 14pt; font-family: 宋体;">第一章：</span>
<span lang="EN-US" style="font-size: 14pt;">Seam</span>
<span style="font-size: 14pt; font-family: 宋体;">简介</span>

</p>
<p class="MsoNormal" style="margin-left: 1cm; text-indent: -1cm;"><!--  [if !supportLists]--><span lang="EN-US"><span>1.1.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--  [endif]--><span style="font-family: 宋体;">什么是</span>
<span lang="EN-US">Seam?</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt;"><span lang="EN-US">Seam</span>
<span style="font-family: 宋体;">是一个功能全面的</span>
<span lang="EN-US">JavaEE</span>
<span style="font-family: 宋体;">应用框架。如今，它又是其中最热门的企业级</span>
<span lang="EN-US">Java</span>
<span style="font-family: 宋体;">框架。</span>
<span lang="EN-US">Seam</span>
<span style="font-family: 宋体;">深度集成许多其他基于标准或开源的框架</span>
<span lang="EN-US">(</span>
<span style="font-family: 宋体;">例如：</span>
<span lang="EN-US">JSF</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">EJB3</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">JMS</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">Web Services</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">jBPM</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">JBoss Rules</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">Ajax4jsf</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">RichFaces</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">Facelets</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">Spring</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">iText</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">Quartz</span>
<span style="font-family: 宋体;">，</span>
<span lang="EN-US">TestNG</span>
<span style="font-family: 宋体;">，等</span>
<span lang="EN-US">)</span>
<span style="font-family: 宋体;">，为开发者提供一个单一的编程模型，以便可以通过简单的注释</span>
<span lang="EN-US">POJOs </span>
<span lang="EN">(Plain Old
Java Objects)</span>
<span style="font-family: 宋体;">来</span>
<span style="font-size: 10pt; font-family: 宋体; color: black;">驾驭所属的框架。</span>
<span style="font-size: 10pt; font-family: &quot;MS Shell Dlg&quot;; color: black;">Seam</span>
<span style="font-size: 10pt; font-family: 宋体; color: black;">处理复杂的企业应用程序与许多组件框架</span>
<span style="font-size: 10pt; font-family: 宋体; color: black;">，</span>
<span style="font-size: 10pt; font-family: 宋体; color: black;">使开发者的工作变得更轻松。</span>
</p>
<p class="MsoNormal" style="margin-left: 1cm; text-indent: -1cm;"><!--  [if !supportLists]--><span lang="EN-US"><span>1.2.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--  [endif]--><span style="font-family: 宋体;">关于</span>
Seam<span style="font-family: 宋体;">的其他相关资源</span>
</p>
<p class="MsoNormal" style="margin-left: 21pt;"><span lang="EN"><a href="http://www.jboss.com/products/seam" target="_top"><span style="font-family: Verdana;">Seam Framework</span>
</a>
</span>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://julycn.javaeye.com/blog/183753#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Apr 2008 14:33:50 +0800</pubDate>
        <link>http://julycn.javaeye.com/blog/183753</link>
        <guid>http://julycn.javaeye.com/blog/183753</guid>
      </item>
      <item>
        <title>Seam 开发工具参考指南</title>
        <author>julycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://julycn.javaeye.com">julycn</a>&nbsp;
          链接：<a href="http://julycn.javaeye.com/blog/182221" style="color:red;">http://julycn.javaeye.com/blog/182221</a>&nbsp;
          发表时间: 2008年04月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;"><strong><span style="font-size: 20pt; line-height: 115%; font-family: 黑体; color: #ff6600;">Seam<span lang="ZH-CN">开发工具参考指</span>
</span>
</strong>
<strong><span style="font-size: 20pt; line-height: 115%; font-family: 黑体; color: #ff6600;">南(目录)</span>
</strong>
</p>
<p class="MsoNormal" align="center" style="text-align: center;">&nbsp;</p>
<p class="MsoNormal" align="center" style="text-align: center;"><span style="font-family: 宋体;">Copyright @2007 Red Hat <span>&nbsp;&nbsp;&nbsp;</span>
<span lang="ZH-CN">翻译 七月天 </span>
<a href="http://www.javaos.com.cn/">http://www.javaos.com.cn</a>
</span>
</p>
<div style="padding: 0in 0in 1pt; border: medium medium 1.5pt none none solid -moz-use-text-color -moz-use-text-color windowtext;">
<p class="MsoNormal" style="border: medium none; padding: 0in;"><span style="font-family: 宋体;">版本</span>
<span style="font-family: 宋体;">:2.0.0.GA</span>
</p>
<p class="MsoNormal" style="border: medium none; padding: 0in;"><span style="text-decoration: underline;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
</p>
</div>
<p class="MsoListParagraphCxSpFirst" style="margin-left: 0.25in; text-indent: -0.25in;"><!--    [if !supportLists]--><span><span>1.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--    [endif]--><span style="font-family: 宋体;">简介</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.55in; text-indent: -0.3in;"><!--    [if !supportLists]--><span><span>1.1.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--    [endif]--><span style="font-family: 宋体;">什么是</span>
Seam<span style="font-family: 宋体;">？</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.55in; text-indent: -0.3in;"><!--    [if !supportLists]--><span><span>1.2.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--    [endif]--><span style="font-family: 宋体;">关于</span>
Seam<span style="font-family: 宋体;">的其他相关资源</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.25in; text-indent: -0.25in;"><!--    [if !supportLists]--><span><span>2.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--    [endif]--><span style="font-family: 宋体;">通过新建项目向导，创建</span>
Seam<span style="font-family: 宋体;">项目</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.55in; text-indent: -0.3in;"><!--    [if !supportLists]--><span><span>2.1.<span style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal; font-family: &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;
</span>
</span>
</span>
<!--    [endif]--><span style="font-family: 宋体;">创建独立的</span>
Seam Web<span style="font-family: 宋体;">项目</span>
</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0.55