Eclipse + Jboss AS 7.1 建立 EJB3.0之JPA工程(下)

 

8. 建立 Session Bean 和 Bean Interface


  • 右击ejbModule -> New -> Session Bean (EJB 3.x)html

  • 输入包名com.ibytecode.businesslogicjava

  • 输入类名ProjectBean
  • 选择状态为Stateless
  • 选择Remote Business Interface并输入com.ibytecode.business.IProject
  • business interface将会在另外一个包(com.ibytecode.business)中生成
  • 点击Finishmysql

9. 编写 Bean 和 Interface


  • 打开“Bean Interface”而且复制下面的代码
  • Interface 能够是 @Remote或者@Local。这里,咱们选择@Remote (Remote 与 Local 的区别
     1 package com.ibytecode.business;
     2 import java.util.List;
     3 import javax.ejb.Remote;
     4 
     5 import com.ibytecode.entities.Project;
     6 
     7 @Remote
     8 public interface IProject {
     9     void saveProject(Project project);
    10     Project findProject(Project project);
    11     List<Project> retrieveAllProjects();
    12 }
    View Code
  • 打开 Bean 并复制下面的代码
  • Bean 类型能够是 @Stateful 或 @Statess,这里使用@Statess (Stateful 与 Statess 的区别
     1 package com.ibytecode.businesslogic;
     2 
     3 import java.util.List;
     4 import javax.ejb.Stateless;
     5 import javax.persistence.EntityManager;
     6 import javax.persistence.PersistenceContext;
     7 import javax.persistence.Query;
     8 
     9 import com.ibytecode.business.IProject;
    10 import com.ibytecode.entities.Project;
    11 
    12 @Stateless
    13 public class ProjectBean implements IProject {
    14 
    15     @PersistenceContext(unitName = "JPADB")
    16     private EntityManager entityManager;
    17     
    18     public ProjectBean() {   }
    19 
    20     @Override
    21     public void saveProject(Project project) {
    22         entityManager.persist(project);
    23     }
    24 
    25     @Override
    26     public Project findProject(Project project) {
    27         Project p = entityManager.find(Project.class, project.getPnumber());
    28         return p;
    29     }
    30 
    31     @Override
    32     public List<Project> retrieveAllProjects() {
    33         
    34         String q = "SELECT p from " + Project.class.getName() + " p";
    35         Query query = entityManager.createQuery(q);
    36         List<Project> projects = query.getResultList();
    37         return projects;
    38     }
    39 }
    View Code  
  • 下一步,咱们将配置数据源

10. Persistence.xml


server是如何知道,EntityManager API 应该在哪一个数据库 save / update / query 实体对象?(由于在Jboss 中配置的数据源可能有多个,咱们这里就要指定standalone.xml 中配置的某个 'datasource jndi-name'
“persistence.xml”文件能够完整且灵活的配置 EntityManager
“persistence.xml”是 JPA 中一个标准的配置文件,应该被放置在META-INF目录下。在该文件中应该定义一个persistence unit节点并设置一个惟一的name属性,该name属性将被EntityManager使用。
右击META-INF -> New -> Other -> XML -> XML file,输入文件名persistence.xml,并粘贴以下内容:sql

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="JPADB">
    <jta-data-source>java:/MySQLDS</jta-data-source>
        <properties>
            <property name="showSql" value="true"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>
    </persistence-unit>
</persistence>

在JBoss AS中,默认的JPA provider是Hibernate,jta-data-source指向此持久元映射到的数据库的JNDI名称。java:/MySQLDS指向MySQL DB数据源。咱们将在下一步设置这个数据源。数据库

11. 在JBoss AS 7中配置MySQL数据源


1.1. 下载 MySQL connector


点此连接下载,解压获得MySQL Connector J JAR.api

11.2. 向AS 7中添加Module


AS 7 经过module体系来实现类的独立加载,咱们须要建立一个新的包含 “MySQL Connector J JAR”文件的模块.
在你的 AS 7 的根目录下,按照modules/com/mysql/main的层次创建文件夹,而后复制“MySQL Connector J JAR”文件到main文件中。
而后在XML文件中定义此模块,新建module.xml并粘贴下面的代码:服务器

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.0" name="com.mysql">
  <resources>
    <resource-root path="mysql-connector-java-5.1.18-bin.jar"/>
  </resources>
  <dependencies>
    <module name="javax.api"/>
  </dependencies>
</module>

注意:
这个新的模块目录包含了如下内容:session

- module.xml
- mysql-connector-java-5.1.18-bin.jar

JAR文件的名称根据实际进行修改app

JAR的版本高于(包括)5.5.30会在后面出现问题less

11.3. 建立驱动引用


如今,咱们须要在main应运服务器的配置文件(standalone.xml,路径:JBossAS_Home/standalone/configuration)中创建对module的引用。
找到<drivers>元素,并添加新的驱动:

<drivers>
    <driver name="mysqlDriver" module="com.mysql">
        <xa-datasource-class>
            com.mysql.jdbc.Driver
        </xa-datasource-class>
    </driver>
</drivers>

11.4. 向驱动添加数据源


打开应运服务器配置文件“standalone.xml”,找到<datasources>元素并添加新的数据源:

<datasource jndi-name="java:/MySQLDS" pool-name="MySQLDS" enabled="true" use-java-coMD2ntext="true">
    <connection-url>
        jdbc:mysql://localhost:3306/YOUR-DATABASE-NAME
    </connection-url>
    <driver>mysqlDriver</driver>
    <security>
        <user-name>YOUR-MYSQL-USERNAME</user-name>
        <password>YOUR-MYSQL-PASSWORD</password>
    </security>
</datasource>

注意:

再上面的代码中,使用你的 database 名称,MySQL的 username 和 password.

<datasources>元素中,jndi-name=”java:/MySQLDS”应该和“persistence.xml”中的java:/MySQLDS匹配.

<driver>mysqlDriver</driver>应该和“persistence.xml”中的<drivers><driver name=”mysqlDriver” …>…</driver></drivers>匹配

如今,咱们尝试启动 JBOSS ,若是出现如下异常:

 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 29) JBAS014612: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("jdbc-driver" => "mysqlDriver")

  ..........

解决方法:

1. 5.1.30 版本的 mysql-connector-java-x.x.xx-bin.jar

2. 在 standalone.xml 的 <datasources> 下的 <drivers> 下添加:

  <driver-class>com.mysql.jdbc.Driver</driver-class>

12. 部署 EJB JPA project


在server上部署“FirstJPAProject”工程有两种方法:

1. 右键 EJB project -> "Run As" -> "Run On Server". 选择 "JBoss 7.1 Runtime Server", 点击 "Finish".
2. 在 "Servers" 视图中右键 "JBoss 7.1 Runtime Server" -> "Add and Remove…" ->选择EJB JAR文件 -> "Add" -> "Finish".

 

你也能够从Jboss的管理后台部署EJB组件:

  1. 右键 EJB project -> "Export" . 选择 "EJB Jar file", 输入保存路径,点击 "Finish".

  2. 进入 Jboss 后台: "1ocalhost:8080",选择"Administration Console"

  3."Manage Deployments" -->"Add Content",选择"jar"文件,完成,并将状态设置为"Enable"。

 

13. 启动/重启 服务器


右键 “JBoss 7.1 Runtime Server” 点击 “start”,若是JNDI 映射和和部署都是正确的,你将在控制台看到下面一句话:

Deployed "FirstJPAProject.jar"

14. 建立 Client


  • 接下来的这一步咱们将写一个远程的 Java client application (with main()) 访问和调用部署在服务器上的 Bean
  • Client 使用 JNDI 技术查找 Bean 的代理服务器并调用其方法。

14.1. 建立 JNDI InitialContext


经过 InitialContext 得到 Context

  • 全部的命名服务操做都是在“javax.naming.Context”的接口的实现者上进行的。所以,和命名服务器开始交互的起点是:经过提供给服务器启动服务所需的明确的属性来得到上下文。在咱们的示例中,就是Jboss应用服务器。(原文是“All naming service operations are performed on some implementation of the javax.naming.Context interface. Therefore, the starting point of interacting with the naming service is to obtain a Context by providing the properties specific to the server implementation being used. In our case it is, JBoss Application Server.)(点此了解 javax.Naming 软件包
  • 为了产生一个 javax.naming.InitialContext,咱们须要用 properties 从环境中初始化它。JNDI 经过下面两个来源来校验property的值
    • 使用 InitialContext 的带参构造方法,取决于所提供的环境
    • 在 classpath 中的 jndi.properties 源文件

注意:这里咱们将使用第一种方法

对于 JBoss AS 7,咱们须要设置“Context.URL_PKG_PREFIXES”属性为“org.jboss.ejb.client.naming” 来获得 InitialContext 。

下面的工具类能够产生 JBoss AS 上的 InitialContext,而且能够被全部的 application 重用。不然,在全部的 client 中都要复制代码。

  • 右键 ejbModule -> New -> Class
  • 输入包名 com.ibytecode.clientutility
  • 输入类名 JNDILookupClass
  • 点击 Finish

复制下面的代码:

 1 package com.ibytecode.clientutility;
 2 
 3 import java.util.Properties;
 4 import javax.naming.Context;
 5 import javax.naming.InitialContext;
 6 import javax.naming.NamingException;
 7 
 8 public class JNDILookupClass {
 9 
10     private static Context initialContext;
11 
12     private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";
13 
14     public static Context getInitialContext() throws NamingException {
15         if (initialContext == null) {
16             Properties properties = new Properties();
17             properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);
18 
19             initialContext = new InitialContext(properties);
20         }
21         return initialContext;
22     }
23 }
View Code

 

 

14.2. 建立 client class


  • 右键 ejbModule -> New -> Class
  • 输入包名 com.ibytecode.client
  • 输入类名 EJBApplicationClient
  • 勾选 main() 方法选项
  • 点击 Finish

复制下面的代码:

 1 package com.ibytecode.client;
 2 
 3 import java.util.List;
 4 
 5 import javax.naming.Context;
 6 import javax.naming.NamingException;
 7 
 8 import com.ibytecode.business.IProject;
 9 import com.ibytecode.businesslogic.ProjectBean;
10 import com.ibytecode.clientutility.JNDILookupClass;
11 import com.ibytecode.entities.Project;
12 
13 public class EJBApplicationClient {
14     
15     public static void main(String[] args) {
16         IProject bean = doLookup();
17         
18         Project p1 = new Project();
19         p1.setPname("Banking App");
20         p1.setPlocation("Town City");
21         p1.setDeptNo(1);
22         
23         Project p2 = new Project();
24         p2.setPname("Office Automation");
25         p2.setPlocation("Downtown");
26         p2.setDeptNo(2);
27 
28         // 4. Call business logic
29         //Saving new Projects
30         bean.saveProject(p1);
31         bean.saveProject(p2);
32         
33         //Find a Project
34         p1.setPnumber(1);
35         Project p3 = bean.findProject(p1);
36         System.out.println(p3);
37         
38         //Retrieve all projects
39        System.out.println("List of Projects:");
40         List<Project> projects = bean.retrieveAllProjects();
41         for(Project project : projects)
42             System.out.println(project);
43         
44         
45     }
46 
47     private static IProject doLookup() {
48         Context context = null;
49         IProject bean = null;
50         try {
51             // 1. Obtaining Context
52             context = JNDILookupClass.getInitialContext();
53             // 2. Generate JNDI Lookup name
54             String lookupName = getLookupName();
55             // 3. Lookup and cast
56             bean = (IProject) context.lookup(lookupName);
57 
58         } catch (NamingException e) {
59             e.printStackTrace();
60         }
61         return bean;
62     }
63 
64     private static String getLookupName() {
65         /*The app name is the EAR name of the deployed EJB without .ear 
66         suffix. Since we haven't deployed the application as a .ear, the app 
67         name for us will be an empty string */
68         String appName = "";
69 
70         /* The module name is the JAR name of the deployed EJB without the 
71         .jar suffix.*/
72         String moduleName = "FirstJPAProject";
73 
74         /* AS7 allows each deployment to have an (optional) distinct name. 
75         This can be an empty string if distinct name is not specified.*/
76         String distinctName = "";
77 
78         // The EJB bean implementation class name
79         String beanName = ProjectBean.class.getSimpleName();
80 
81         // Fully qualified remote interface name
82         final String interfaceName = IProject.class.getName();
83 
84         // Create a look up string name
85         String name = "ejb:" + appName + "/" + moduleName + "/" + 
86                 distinctName     + "/" + beanName + "!" + interfaceName;
87         return name;
88     }
89 }
View Code

 

 

14.3. 配置 EJB 客户端上下文属性


一个 EJB 客户端上下文包含了执行远程 EJB 调用的上下文环境信息。他是一个 JBoss AS 特有的 API。一个 EJB 客户端上下文能够和多个 EJB 接收者关联在一块儿,每一个 EJB 接收者能够处理多个 EJB 调用
每一个 EJB 接收者都知道它能够操做的 EJB 集合,每一个 EJB 接收者都知道使用哪一个 server 目标来处理对 Bean 的调用。server 的IP地址和远程服务端口应该在放置在客户端 classpath 的 properties file 中明确给出。而后这个 properties file (EJB client context) 会被 JNDI 的实现类内部使用,去执行在 Bean 代理服务器上的调用。

在应用程序的 classpath 中建立一个“jboss-ejb-client.properties” 文件,咱们能够把它放在应用程序的 ejbModule 文件夹下,该文件中包含如下属性:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
    remote.connections=default
    remote.connection.default.host=localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
 remote.connection.default.username =YOUR_JBOSS_COSOLE_USERNAME
 remote.connection.default.password =YOUR_JBOSS_COSOLE_PASSWORDYOUR_JBOSS_COSOLE_PASSWORD

14.4. 给 client 添加所需的 JAR 文件来运行客户端程序


  • Run菜单或Run图标中打开`Run Configurations…

  • 在左面板中Java Application的下面选择客户端应用程序(EJBApplicationClient),而后打开classpath标签。(若是你没有看见你的客户端应用程序,先运行一遍它。)选择User Entries而后点击“Add External JARs”。

  • 添加下面的 JAR 文件(jboss 7不须要)

JAR 名称 位置
jboss-transaction-api_1.1_spec-1.0.0.Final.jar AS7_HOME/modules/javax/transaction/api/main/
jboss-ejb-api_3.1_spec-1.0.1.Final.jar AS7_HOME/modules/javax/ejb/api/main/
jboss-ejb-client-1.0.0.Beta10.jar AS7_HOME/modules/org/jboss/ejb-client/main/
jboss-marshalling-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/main/
xnio-api-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/main/
jboss-remoting-3.2.0.CR6.jar AS7_HOME/modules/org/jboss/remoting3/main/
jboss-logging-3.1.0.Beta3.jar AS7_HOME/modules/org/jboss/logging/main/
xnio-nio-3.0.0.CR5.jar AS7_HOME/modules/org/jboss/xnio/nio/main/
jboss-sasl-1.0.0.Beta9.jar AS7_HOME/modules/org/jboss/sasl/main/
jboss-marshalling-river-1.3.0.GA.jar AS7_HOME/modules/org/jboss/marshalling/river/main/

你也能够经过”Build path”(右键 EJB Project->Properties,在左边选择Java Build Path,而后中间的标签栏选择“Libraries”,最后在右边选择“ Add External JARs”)

若是你使用的是 JBoss Application Server (AS) 7.1.0 Final 版本,只须要添加一个客户端 JAR 文件(jboss-client-7.1.0.Final.jar)便可,它位于“AS7_HOME/bin/client”目录下

此示例工程的目录结构以下图所示:

14.5. 运行客户端程序



相关文章
相关标签/搜索