EJB 3.0 Enterprise Bean

 

本文档介绍了有关使用 EJB 3.0 技术(作为 Java EE 5 平台的一部分)开发企业应用程序的基础知识,同时说明了 EJB 3.0 技术是如何简化企业应用程序的开发过程的。本文档使用的是 NetBeans IDE 5.5 Beta 版。

请注意此发行版本是 Beta 版。要获取最新的完整发行版本,请转至 NetBeans 下载页并下载 NetBeans IDE 5.0。

预计所需时间:30 分钟

先决条件

本文档假定您已经具备以下技术的一些基本知识或编程经验:

  • Java 编程
  • NetBeans IDE

本教程所需的软件

在学习本教程之前,您需要在计算机中安装以下软件:

  • NetBeans IDE 5.5 Beta(下载
  • Java Standard Development Kit (JDK) 版本 5.0(下载
  • Sun Java System Application Server Platform Edition 9(下载

在学习本教程之前,您需要在 IDE 中注册 Sun Java System Application Server 的本地实例。

教程练习


建立企业应用程序项目

本练习的目的是:创建包含一个 EJB 模块和一个 Web 模块的 NewsApp 企业应用程序项目。NewsApp 应用程序使用消息驱动 Bean 接收和处理 Servlet 发送到队列中的消息。该应用程序使用 Servlet 将消息发送到消息驱动 Bean 并显示消息。

创建企业应用程序

  1. 选择 "File" > "New Project" (Ctrl-Shift-N)。从 "Enterprise" 类别中选择 "Enterprise Application"。
  2. 将项目命名为 NewsApp,并将服务器设置为 "Sun Java System Application Server"。
  3. 将 J2EE 版本设置为 "Java EE 5",然后选中 "Create EJB Module" 和 "Create Web Application Module"(如果未选中)。
  4. 单击 "Finish"。

小结

在本练习中,我们创建了包含一个 EJB 模块和一个 Web 模块的 Java EE 5 企业应用程序。

对 EJB 模块进行编码

在本练习中,我们将在 EJB 模块中创建对象。我们将创建实体类、消息驱动 Bean 和会话 Facade。我们还将创建一个持久性单元,以便为容器提供用于管理实体的信息,以及消息驱动 Bean 将使用的 Java 消息服务 (Java Message Service, JMS) 资源。

创建持久性单元

首先,我们将创建一个持久性单元,它用于定义在应用程序中使用的数据源和实体管理器。

  1. 右键单击 EJB 模块,然后选择 "New" > "File/Folder"。
  2. 从 "Persistence" 类别中,选择 "Persistence Unit",然后单击 "Next"。
  3. 保留缺省的持久性单元名称。
  4. 对于 "Persistence Provider",请使用 TopLink(default)
  5. 对于 "Data Source",请使用缺省的数据源 jdbc/sample
  6. 确保为持久性单元选中了 "Use Java Transaction APIs" 复选框,并将 "Table Generation Strategy" 设置为 "Create",这样便可以在部署应用程序时创建基于实体类的表。
  7. 单击 "Finish"。

"New Persistence Unit" 向导

单击 "Finish" 后,IDE 将创建 persistence.xml,并在源代码编辑器中将其打开。

创建 NewsEntity 实体类

在本练习中,我们将创建 NewsEntity 实体类。实体类是一个简单的 Java 类。在创建实体类时,IDE 会添加 @Entity 标注以将该类定义为实体类。当创建了类后,我们将在该类中创建字段以表示表中所需的数据。

每个实体类都必须具有一个主键。在创建实体类时,IDE 会添加 @Id 标注以声明要用作主键的字段。此外,IDE 还会添加 @Generated 标注以指定主 Id 的键生成策略。

要创建 NewsEntity 类,请执行以下操作:

  1. 在 "Project" 窗口中右键单击 EJB 模块,然后选择 "New" > "File/Folder" 以打开 "New File" 向导。
  2. 从 "Persistence" 类别中选择 "Entity Class",然后单击 "Next"。
  3. 键入 NewsEntity 作为类名,键入 ejb 作为包名,并将 "Primary Key Type" 保留为 Long。单击 "Finish"。

单击 "Finish" 后,将在源代码编辑器中打开实体类 NewsEntity.java。在源代码编辑器中,请执行以下操作:

  1. 将以下字段声明添加到类中:
      String title;
    String body;
  2. 选择 "Refactor" > "Encapsulate Fields" 以便为每个字段生成 getter 和 setter 方法。在 "Encapsulate Fields" 对话框中,确保选中了字段 idtitlebody 的 getter 和 setter 复选框。
  3. 在 "Encapsulate Fields" 对话框中单击 "Next",然后在 "Output" 窗口的 "Refactoring" 标签中单击 "Do Refactoring"。IDE 将为各字段添加 getter 和 setter 方法,并将字段的可视性更改为 private
  4. 保存对文件所做的更改。

在接下来的步骤中,我们将创建 NewMessage 消息驱动 Bean。

创建 NewMessage 消息驱动 Bean

现在我们将在 EJB 模块中创建 NewMessage 消息驱动 Bean。我们将使用 "New Message-Driven Bean" 向导创建 Bean。在该向导中,将在 "Mapped Name" 字段中输入 jms/NewMessage,以便将资源注入到类中。

要创建 NewMessage 消息驱动 Bean,请执行以下操作:

  1. 在 "Project" 窗口中右键单击 EJB 模块,然后选择 "New" > "File/Folder" 打开 "New File" 向导。
  2. 从 "Enterprise" 类别中,选择 "Message-Driven Beans",然后单击 "Next"。
  3. 键入 NewMessage 作为类名。
  4. 从包下拉列表中选择 ejb
  5. 在 "Mapped Name" 字段中输入 jms/NewMessage,然后单击 "Finish"。

单击 "Finish" 后,将在源代码编辑器中打开新建的消息驱动 Bean 类 NewMessage.java。您可以看到该类具有以下标注:

  @MessageDriven(mappedName = "jms/Queue")

此标注向容器说明:该组件是一个消息驱动 Bean 并且该 Bean 使用 JMS 资源。JMS 资源被映射到目标的 JNDI 名称,Bean 从该目标中接收消息。 "New Message-Driven Bean" 向导已为我们创建了 JMS 资源。通过 EJB 3.0 API,我们可以从 Bean 类中查找 JNDI 名称空间中的对象,这样就不需要配置部署描述符来指定 JMS 资源了。

利用 EJB 3.0 软件,我们可以使用标注将资源直接引入类中。现在,我们准备使用标注将 MessageDrivenContext 资源引入类中,然后注入 PersistenceContext 资源,EntityManager API 将使用该资源来管理持久性实体实例。我们要在源代码编辑器中将标注添加到类中。

  1. 通过在字段声明列表中添加以下带标注的字段,将 MessageDrivenContext 资源注入到类中:
      @Resource
    private MessageDrivenContext mdc;
  2. 在代码中单击鼠标右键,然后从弹出式菜单中选择 "Persistence" > "Use Entity Manager",将实体管理器引入类中。
    这会在源代码中添加以下标注:
      @PersistenceContext
    private EntityManager em;
    并在代码中生成以下方法:
      public void changeMyName(Object object) {
    // TODO:
    // em.persist(object);
    }
  3. 按如下所示修改 changeMyName 方法:
      public void save(Object object) {
    em.persist(object);
    }
  4. 通过将以下代码添加到主体中来修改 onMessage 方法:
        ObjectMessage msg = null;
    try {
    if (message instanceof ObjectMessage) {
    msg = (ObjectMessage) message;
    NewsEntity e = (NewsEntity) msg.getObject();
    save(e);
    }
    } catch (JMSException e) {
    e.printStackTrace();
    mdc.setRollbackOnly();
    } catch (Throwable te) {
    te.printStackTrace();
    }
  5. 按 Alt-Shift-F 组合键生成所有必要的 import 语句。在生成 import 语句时,我们希望导入 jms 库。
  6. 保存该文件。

创建会话 Bean

接下来,我们将为 NewsEntity 实体类创建一个会话 Facade。要创建会话 Facade,请执行以下操作:

  1. 右键单击 EJB 模块,然后选择 "New" > "File/Folder"。
  2. 从 "Persistence" 类别中,选择 "Session Facade",然后单击 "Next"。
  3. 从可用的实体类列表中,选择 "NewsEntity",单击 "Add",然后单击 "Next"。
  4. 检查是否将源代码包设置为 ejb,并创建了本地接口。
  5. 单击 "Finish"。

单击 "Finish" 后,将创建会话 Facade 类 NewsEntityFacade.java,并在源代码编辑器中将其打开。IDE 还将创建本地接口 NewsEntityFacadeLocal.java

EJB 3.0 技术通过减少所需的代码量来简化会话 Bean 的创建。您可以看到,标注 @Stateless 用于将类声明为无态会话 Bean 组件,并且该类不再需要实现 javax.ejb.SessionBean 的语句。此外,代码也更为简洁了,因为利用 EJB 3.0 技术,业务方法不再需要使用代码来声明其抛出了所检查到的异常。

您会看到,在创建会话 Facade 时,PersistenceContext 资源已直接注入到会话 Bean 组件中。

小结

在本练习中,我们已对 EJB 模块中的实体类和消息驱动 Bean 进行了编码,然后为实体类创建了会话 Facade。此外,我们还创建了应用程序使用的 JMS 资源。

对 Web 模块进行编码

现在,我们将在 Web 模块中创建 Servlet ListNewsPostMessage。这些 Servlet 将用于读取和添加消息。

创建 ListNews Servlet

在本练习中,我们将创建一个用于显示数据的简单 Servlet。我们将使用标注从 Servlet 中调用实体 Bean。

  1. 右键单击 Web 模块项目,然后选择 "New" > "Servlet"。
  2. 键入 ListNews 作为类名。
  3. 输入 web 作为包名,然后单击 "Finish"。

单击 "Finish" 后,将在源代码编辑器中打开类 ListNews.java。在源代码编辑器中,请执行以下操作:

  1. 在源代码中,单击鼠标右键,然后选择 "Enterprise Resources" > "Call Enterprise Bean"。
  2. 在 "Call Enterprise Bean" 对话框中,选择 "NewsEntityFacade",然后单击 "OK"。单击 "OK" 后,将使用 @EJB 标注在 Servlet 中注入实体 Bean 资源。
  3. 取消代码的注释,并通过将下面以粗体显示的代码行添加到 processRequest 方法的主体中来修改该方法:
      out.println("<h1>Servlet ListNews at " + request.getContextPath () + "</h1>");

    List news = newsEntityFacade.findAll();
    for (Iterator it = news.iterator(); it.hasNext();) {
    NewsEntity elem = (NewsEntity) it.next();
    out.println(" <b>"+elem.getTitle()+" </b><br />");
    out.println(elem.getBody()+"<br /> ");
    }
    out.println("<a href='PostMessage'>Add new message</a>");


    out.println("</body>");
  4. 按 Alt-Shift-F 组合键为类生成所有必要的 import 语句。在生成 import 语句时,我们希望从 util 包中导入类。
  5. 保存对文件所做的更改。

创建 PostMessage Servlet

在本练习中,我们将创建用于传递消息的 PostMessage Servlet。我们将使用标注将所创建的 JMS 资源直接注入 Servlet 中,并且指定变量名称及其映射到的名称。然后,添加用于发送 JMS 消息的代码,以及用于在 HTML 表单中添加消息的代码。

  1. 右键单击 Web 模块项目,然后选择 "New" > "Servlet"。
  2. 键入 PostMessage 作为类名。
  3. 输入 web 作为包名,然后单击 "Finish"。

单击 "Finish" 后,将在源代码编辑器中打开类 PostMessage.java。在源代码编辑器中,请执行以下操作:

  1. 通过添加以下字段声明,使用标注来注入 ConnectionFactoryQueue 资源:
      public class PostMessage extends HttpServlet {
    @Resource(mappedName="jms/NewMessageFactory")
    private ConnectionFactory connectionFactory;
    @Resource(mappedName="jms/NewMessage")
    private Queue queue;

  2. 现在,通过将下面以粗体显示的代码添加到 processRequest 方法中,添加用于发送 JMS 消息的代码:
      response.setContentType("text/html;charset=UTF-8");

    // Add the following code to send the JMS message
    String title=request.getParameter("title");
    String body=request.getParameter("body");
    if ((title!=null) && (body!=null)) {
    try {
    Connection connection = connectionFactory.createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer messageProducer = session.createProducer(queue);

    ObjectMessage message = session.createObjectMessage();
    // here we create NewsEntity, that will be sent in JMS message
    NewsEntity e = new NewsEntity();
    e.setTitle(title);
    e.setBody(body);

    message.setObject(e);
    messageProducer.send(message);
    response.sendRedirect("ListNews");

    } catch (JMSException ex) {
    ex.printStackTrace();
    }
    }


    PrintWriter out = response.getWriter();
  3. 现在,将对输出 HTML 的代码取消注释,并添加用于添加消息的 Web 表单。将下面以粗体显示的代码行添加到 processRequest 方法中:
      out.println("Servlet PostMessage at " + request.getContextPath() + " ");

    // Add the following code to add the form to the web page
    out.println("<form>");
    out.println("Title: <input type='text' name='title'><br/>");
    out.println("Message: <textarea name='body'></textarea><br/>");
    out.println("<input type='submit'><br/>");
    out.println("</form>");


    out.println("</body>");
  4. 按 Alt-Shift-F 组合键为类生成所有必要的 import 语句。在选择 ConnectionConnectionFactorySessionQueue 的 import 语句时,将导入 java.jms 库。
  5. 保存对文件所做的更改。

运行项目

现在可以运行项目了。在运行项目时,我们希望浏览器打开包含 ListNews Servlet 的页面。可以通过在企业应用程序的属性对话框中指定该页的 URL 来实现这一目的。该 URL 是应用程序的上下文路径的相对 URL。输入相对 URL 后,可以从项目窗口中生成、部署并运行应用程序。

要设置相对 URL 并运行应用程序,请执行以下操作:

  1. 在 "Projects" 窗口中,右键单击 "NewsApp" 企业应用程序节点,然后从弹出式菜单中选择 "Properties"。
  2. 在 "Categories" 窗格中选择 "Run"。
  3. 在 "Relative URL" 文本字段中,键入 /ListNews。
  4. 单击 "OK"。
  5. 在 "Projects" 窗口中,右键单击 "NewsApp" 企业应用程序节点,然后选择 "Run Project"。

运行项目时,将在浏览器中打开 ListNews Servlet,该 Servlet 用于显示数据库中的消息列表。如果您是第一次运行项目,则数据库为空,但是您可以单击 "Add Message" 来添加消息。

ListNews Servlet 页

当您使用 PostMessage Servlet 添加消息时,消息会发送到消息驱动 Bean 以写入到持久性存储中,并会调用 ListNews Servlet 来显示数据库中的消息。由 ListNews 检索的数据库中的消息列表通常不包含新消息,这是因为消息服务是异步的。


注:以上内容来自网络,本人不承担连带责任

文章转自:http://blog.chinaunix.net/u/14788/showart_215066.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值