jboss seam学习2

9. 卓越的工具支持

对于一个聚焦于开发者生产力的应用框架,开发工具的支持至关重要。Seam发布了一个基于命令行的生成器,称作 SeamGen。SeamGen类似于Ruby-On-Rails中的生成器,它支持诸如从一个数据库生成完整CRUD应用的功能,聪明的开发者会通过诸如“编辑/保存/在浏览器重新载入”的步骤、有测试支持的特性,来改进web应用。

但更重要的是,SeamGen生成项目不依赖于主流的Java集成开发环境,如Eclipse和NetBeans。有了SeamGen,开发者可以随时入门。

10. 让我们开始编码吧

总而言之,Seam为JavaEE应用削减了开发费用,同时,增加了Java EE 5.0不具有的强大的新功能。在下节(节选自本书第二章),我们将给您展示一些实际代码例子来阐述Seam如何工作的。你能通过网站http://www.michaelyuan.com/seam/下载到本书中所有的例子的源代码。

Seam Hello World

JBoss Seam是EJB3和JSF中间的粘合剂,这是Jboss Seam最基本的和最广泛的应用。通过被Seam管理的组件,Seam允许这两个框架之间无缝(不是有意双关的)的集成。它为整个web应用拓展了基于注解的EJB3 POJO编程模型。在层与层之间,没有了必需的手动JNDI查找,没有了冗长的JSF支持bean的声明,没有了过多facade方法,没有了艰辛的对象传递,快哉!

继续在Seam中使用JavaEE模式

在传统的java EE应用中,一些设计模式,例如JNDI查找、XML声明组件、值对象、facade是被强制使用的。Seam用基于注解的POJO消除了这些人为的需求。但是,当Seam应用中真正需要它们的时候,仍然可以自由地使用这些模式。

编写一个Seam web应用概念上很简单。你只需要编码出下列组件:

  • 实体对象代表数据模型。实体对象可能是JPA或者Hibernate中的POJO对象。它们自动地映射到关系数据库表。
  • SF web页面展示了用户界面。页面通过表单捕获用户的输入,并且显示结果。表单域与其数据显示数据库表,这些表被映射到实体bean或者实体bean的集合上。
  • EJB3 会话bean或者注解过的Seam POJO可以作为JSF Web页面的UI事件处理器。它们处理封装在实体bean中的用户输入,为下一步(或者页面)生成显示的数据对象。

所有以上组件均由Seam自行管理,它们在运行时被自动注入到正确的页面或者对象。例如,当用户单击按钮提交一个JSF表单,Seam就会自动解析表单域并构造一个实体bean。然后,Seam将实体bean传入同样被Seam构造的事件处理器会话bean中来处理。开发者不需要在代码中管理组件的生命周期和组件之间的相互关系。依赖处理过程中,没有样板代码和XML文件。

本章中,我们使用hello world一例来明确展示Seam如何粘合一个web应用。该例子工作如下:用户能在web表单中输入其名字来“问候”Seam。一旦她提交了表单,应用则保存她的名字到一个关系数据库中,并且显示所有已经“问候”过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/。

为了运行本书中的例子,我们建议您使用JEMS GUI安装程序安装一个与Seam兼容的JBoss AS。您可以从http://labs.jboss.com/portal/jemsinstaller/downloads下载JEMS安装程序。如果您需要更多安装JBoss AS和应用部署帮助,请参见附录A,“安装和部署JBoss AS”

欢迎使用示例作为模板,快速开始你自己Seam项目(参见附录B “使用应用示例作为模板”)。或者,你能使用命令行工具Seam Gen (参见第四章“快速应用开发工具”)自动生成项目模板,包括所有的配置文件。本章中,我将花少量的时间来阐释源代码项目中的目录结构。相反,我们将集中讨论代码和配置,这也是开发者建立一个Seam 应用必需的。如此,我们就能将知识应用到任何一个项目结构,而不需要受模板的限制。

源代码目录

一个Seam应用由java类和XML或文本配置文件组成。本书的项目例子中,java源代码文件在src目录中,网页在view 目录中,所有的配置文件都在resources目录中。更多信息请看附件B,使用应用示例作为模板。

1. 创建一个数据模型

Helloworld应用中的数据模型仅仅是一个有name和id属性的person 类。注解@Entity告诉容器映射该类到一个关系数据库表,每个属性对应表中一个字段,每个person实例相当于表中的一条记录。因为Seam采用非常规的配置方式,容器为表名和字段中仅仅使用类名和属性名。属性id上的@Id@GeneratedValue注解暗示id字段是主键,它的值是应用服务器为每个保存到数据库的peron对象自动生成。

@Entity
@Name("person")
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;}
}

Person类中最重要的注解是@Name,它为这个将要注册于Seam中的Person bean指定了名称。在其他Seam组件中(例如,页面和会话bean)中,开发者能指直接使用“person”来引用被管理的Person bean

2. 将数据模型映射到web表单

在JSF页面中,我们使用Person bean来支持表单输入文本域。#{person.name}符号指代名为“person”的Seam组件的name属性,名为“person”的Seam组件是Person实体bean的一个实例。

<h:form>
Please enter your name:<br/>
<h:inputText value="#{person.name}" size="15"/><br/>
<h:commandButton type="submit" value="Say Hello"
                 action="#{manager.sayHello}"/>
</h:form>

通过以下的实体表单,JSF页面显示了数据库中所有已经向Seam说“hello”的用户。用户名单列表存储在一个名为“fans”的Seam组件中,它是一个List 对象。JSFdataTable通过遍历列表,每一行显示一个Person对象。Fan标记是fans列表的迭代子。

<h:dataTable value="#{fans}" var="fan">
  <h:column>
    <h:outputText value="#{fan.name}"/>
  </h:column>
</h:dataTable>
    

图2.1显示了Hello World网页

当用户点击“Say Hello”按钮提交表单,Seam用输入数据构造了该person组件。然后它调用了名为“manager”的Seam 组件的sayhello()的方法(像这样,#{manager.sayHello}是表单提交按钮的UI事件处理器),这就在数据库中保存了person对象并且刷新了fans列表。名为manager的组件是一个EJB3的会话bean, 我们将在下节讨论该话题。

2. 处理web事件

Seam 中的名为manager的组件是会话bean ManagerAction,正如该类中@Name注解指定的。ManagerAction类personfans两个属性,这两个属性被@In@Out所注解。

@Stateless
@Name("manager")
public class ManagerAction implements Manager {

  @In @Out
  private Person person;

  @Out
  private List <Person> fans; 

注解@In和@Out在Seam编程模型中处于核心。因此,让我们看看到底它们在这里是做什么的。

注解@In告诉Seam,在此会话bean中,执行任何一个方法之前,Seam就会把由JSF表单构造的名为person组件赋给该person字段(通过依赖注入)。开发者能为@In中的注入的组件指定一个任意的名称,但是如果没有指定,如这里所示,Seam会将同类型以及同名称的组件注入到该字段中。注解@Out告诉Seam,在执行任何方法后,Seam会将属性fans值和属性person的值都赋给被Seam管理的同名的组件。在Seam中,我们将这个操作称作 “依赖抛出”。以此,在ManagerAction.sayHello()方法中,我们仅仅需要更新属性fans和属性person的值,它们会自动显示在页面上。

什么是双向映射

在Seam 文件中,有时你就会看到术语“双向映射”。它指的是被Seam管理的组件和Seam管理上下之间的注入和抛出。

因为person属性已经通过注入持有了表单数据,sayHello()方法仅仅是通过JPA EntityManager将它保存到数据库中,JPA EntityManager也是通过@PersistenceContext注入的。当方法返回之后,它便更新了fansperson对象并且把这两个对象抛出。方法sayHello()一般会返回null,预示着在调用之后,更新的数据模型将在当前的JSF页面显示。

  @PersistenceContext
  private EntityManager em;

  public String sayHello () {
    em.persist (person);
    person = new Person ();
    fans = em.createQuery("select p from Person p")
          .getResultList();

    return null;
  }

除了一些细节,我们基本完成了。可能你已经注意到,ManagerAction bean类实现了Manager接口。为了符合EJB3会话bean 规范,我需要一个能列出bean中所有业务方法的方法。下面是接口Manager代码,幸运的是,用任何高级IDE工具都能轻松地自动生成这个接口。

@Local
public interface Manager {
  public String sayHello ();
}

这就是在Hello World例子中需要的所有代码。后面两章小节将涵盖Seam应用的其他方法和配置。如果开发者为了自己的小型数据库应用想立即编码和定制helloworld项目,那么现在就可以跳过本章的剩余部分。

你可能感兴趣的:(bean,应用服务器,jboss,JSF,seam)