UML软件工程组织

J2EE Server下的第一个EJB程序(图文进阶篇)
 (选自Java Research)
作者:翁驰原
编按:为了帮助国内J2EE初学者,写了这篇文章,期望能够对广大Java爱好者有所帮助。
文章内容:
1、本文一步步图文并茂的教读者配置出一个标准的J2EE开发环境
2、启动cloudscape数据库的cloudview,并建立数据库
3、让读者开发第一个EJB程序
4、设置EJB的datasource、部署应用程序等。


开发环境:
开发环境使用SUN的j2sdk1.4和j2sdkee1.3.1(注:关于j2sdk的版本,只要是1.3.1_02以后的都可以)。数据库:j2sdkee自带的cloudscape数据库。
第一、配置系统环境
确认你下载了j2sdk1.3.1_02以上的jdk版本和j2sdkee.1.3.1这些软件可以到sun的网站上去找http://java.sun.com 目前j2se的最高版本是j2sdk1.4。然后安装上述软件。我的安装目录是在H:盘。在安装之前如果你以前装有不同版本的jdk,请先卸载,然后再安装。安装好以后,请设置classpath.windows下的设置如下:为了方便,所以加入大部分的路径。
set JAVA_HOME=h:\ j2sdk1.4
set J2EE_HOME=h:\j2sdkee1.3.1
set classpath=h:\ j2sdk1.4\jre\lib\jaws.jar;
h:\ j2sdk1.4\lib\dt.jar;
h:\j2sdk1.4\lib\tools.jar;
h:\j2sdkee1.3.1\lib\ejb10deployment.jar;
h:\j2sdkee1.3.1\lib\j2ee.jar;
h:\j2sdkee1.3.1\lib\jhall.jar;
h:\j2sdkee1.3.1\lib\j2eetools.jar;
h:\j2sdkee1.3.1\lib;
上面是我的机器上的目录,如果你安装在不同的目录上的话,请自行改变
如果操作系统是win98,要运行这个文件或者重新启动才可以生效.
这样可以顺利的启动j2ee,在dos窗口下运行%j2ee_home%\bin\j2ee -verbose命令如果顺利的话,就会看到在DOS窗口中出现J2EE server startup complete的提示(如下图)。

打开浏览器敲入地址http://localhost:8000/index.html可以看到首页就说明配置正确并成功启动了J2EE应用服务器。(如下图)

第二、启动数据库
加入如下的路径
h:\j2sdkee1.3.1\lib\system\cloudutil.jar;h:\j2sdkee1.3.1\lib\cloudscape\cloudclient.jar;
h:\j2sdkee1.3.1\lib\cloudscape\rmijdbc.jar;h:\j2sdkee1.3.1\lib\system\cloudscape.jar;
关键的问题出在如何调出cloudscape数据库的图形管理界面!你在命令行方式下敲入java COM.cloudscape.tools.cview很可能会出现错误。什么原因呢?第一、你要看看你的jdk版本对不对,是不是1.3.1_02以上或者1.4的。第二、关键中的关键,原来sun的j2ee里的cloudview是不能在他附带的cloudscape4.0.6下工作的(真不知道sun在搞什么东东 :))
这里是在ibm网站上的一句原话:The Java 2 SDK, Enterprise Edition v. 1.3.1 includes Cloudscape 4.0.6 but includes a version of Cloudview which will not function with the 4.0.6 system。所以同志门就自己去下一个吧!这里还需要两个jar文件。下载地址是
cloudview.jarjd.jar把这两个文件放在j2sdkee1.3.1下的cloudscape目录下,我这里还需要加两个classpaht路径
h:\j2sdkee1.3.1\cloudscape\cloudview406.jar;
h:\j2sdkee1.3.1\cloudscape\jh.jar
OK!一起大功告成!现在看看怎么启动cloudview,在命令行下键入
java -Dcloudscape.system.home=%j2ee_home%\cloudscape COM.cloudscape.tools.cview
这里-Dcloudscape.system.home是设置数据库存放的路径,这个路径可以在建立数据库的时候改变
%j2ee_home%\cloudscape是cloudscape的默认工作目录
也可以将-Dcloudscape.system.home后的路径去掉,不过要记住,要将数据库建在改路径下,否则j2ee server找不到它!好了,接下来你会发现一个图形界面。用file——>new 菜单来新建一个数据库(如下图)

很多数据库的管理模式都差不多,比如cloudview和sqlserver、db2的控制中心使用方法基本相同。在弹出的菜单中输入你所要创建的数据库名。在这个例子里输入ExampleDB。按directory按钮选择目录在j2ee的安装目录下的cloudscape目录(如下图)

这时在面板的左面就会发现有了table、view等列表。如果下次启动时候左面的面板不见了,可以选view菜单下的details only后再选一次。然后在Table上点右键选择new子菜单下的table,新建好了一个表后可以在右边的框的name旁边的框内修改表名,这里表名设成employee。在columns这一栏可以按+号新增一个列。也可以选择所要删除的列后按-号。
新建两个列,一个是employeeID、一个是name类型和字段长度如下图所示。选择Data标签可以新增数据,你可以输入一些测试数据。

鼠标右键选择左边窗口的Keys在弹出的窗口里选择new——> key。在右边的窗口修改名字为employeeKey,类型选择primary Key,然后点选EmployeeID字段(如下图),按下面的OK按钮确定,最后按OK按钮关闭cloudview窗口。

接下来启动j2ee自带的cloudscape数据库,这个也简单
在命令行方式下到h:\j2sdkee1.3.1\bin目录下打cloudscape -start可以启动cloudscape数据库如下图

第三、接下来开始写三个范例程序
分别是EmployeeHome.java、EmployeeBean.java、Employee.java。把这三个程序一起放在一个叫first的目录里
(1) EmployeeHome.java
package employee.com;
import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;
public interface EmployeeHome extends javax.ejb.EJBHome {
public Employee create(String employeeID) throws DuplicateKeyException,javax.ejb.CreateException,java.rmi.RemoteException;

public Employee findByPrimaryKey(String employeeID ) throws ObjectNotFoundException,FinderException,RemoteException;

}
这个文件实现了Home 接口。Home接口必须遵守以下的规定:(1)类型必须为interface。(2)必须是public。(3)至少要声明一个create()或者finder方法其中的一个。(4)create和finder方法必须包含java.rmi.RemoteException异常,finder方法必须另外包含java.ejb.FinderException异常。
客户端利用Home interface 取得EJB Object的远端对象参考(Remote interface)什么是Remote interface呢?看下来的程序
(2)Employee.java
package employee.com;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Employee extends javax.ejb.EJBObject {
public String getName()throws java.rmi.RemoteException;
}
这个文件实现了Remote接口。Remote接口必须遵守以下的规定:(1)类型必须为interface。(2)必须是public。(3)必须直接或者间接继承java.ejb.EJBObject。(4)声明的方法必须和Bean class里的方法一样。
(3) EmployeeBean.java
package employee.com;
import java.util.*;
import javax.ejb.*;

public class EmployeeBean implements EntityBean{
public String employeeID;
public String name;
private EntityContext context;
public void setEntityContext (EntityContext context){
this.context=context;
}
public void unsetEntityContext(){
context=null;
}
public String ejbCreate (String employeeID) throws DuplicateKeyException, CreateException{
this.employeeID=employeeID;
this.name="";
return null;
}

public void ejbPostCreate(String employeeID){
}

public void setName(String name){
this.name=name;
}

public String getName(){
return name;
}

public void ejbActivate(){
employeeID=(String) context.getPrimaryKey();
}

public void ejbPassivate(){
employeeID=null;
name=null;
}

public void ejbRemove(){
}

public void ejbLoad(){
}

public void ejbStore(){
}

}

以上是一个EntityBean 和一个远程接口和一个Home接口。
下面写一个JavaBean来调用EntityBean里的方法
EmployeeOut.java
package employee.beans;
import employee.com.*;
import java.util.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import javax.ejb.*;
import java.sql.*;

public class EmployeeOut{
private String id="";
private String name="";
EmployeeHome employeeHome=null;
public EmployeeOut() throws SQLException
{
try{
Context initial = new InitialContext();
Object objref=initial.lookup("ejb/EmployeeEntityBean");
employeeHome=(EmployeeHome)PortableRemoteObject.narrow(objref,EmployeeHome.class);

}catch (Exception ex){
throw new SQLException (ex.toString());
}
}

public String getName(String id) throws Exception
{
try
{
Employee employee=employeeHome.findByPrimaryKey(id);
name=employee.getName();
return name;

}
catch (ObjectNotFoundException notfoundex){
return "notfound";
}
catch (Exception ex){
throw ex;
}

}
}

在dos方式下,更换工作目录至first目录,然后执行下列的编译指令:
javac -d . *.java (注d后面和*前面都有一个空格)
就可以在first下生成一个com目录和一个beans目录里面有编译好了的.class文件。
接下来写一个jsp文件,将jsp文件放在first目录下,通过调用JavaBean里的方法来简洁调用EntityBean里的方法。
login.jsp
<%@page language="java" import ="java.sql.*,employee.beans.*" contentType="text/html; charset=GB2312"%>
<jsp:useBean id="employee" scope="page" class="employee.beans.EmployeeOut">
</jsp:useBean>
<%
String name="";
String id=request.getParameter ("id");
if (id==null)
{
id="";
}
if (!id.equals(""))
{
name=employee.getName(id);
}
%>

<html>
<body bgcolor="#cccccc">
<br><br><br><br>
<form name="f1" action="login.jsp" method="post">
<table width=60% align="center">
<tr><td>编号:<input name=id value="" size=15></td>
<td>姓名:<%=name%></td></tr>
<tr><td><br><br></td></tr>
<tr><td clospan=2 align="center"><input type="submit" name="查询姓名"></td></tr>
</table>
</form>
</body>
</html>
第四、设置datasource 部署J2EE
用文本编辑工具打开%J2ee_home%\config\resource.properties文件,找到jdbcDataSource.4.name=jdbc/DB2
jdbcDataSource.4.url=jdbc:cloudscape:rmi:CloudscapeDB;create=true
这行,在这行下面加上
jdbcDataSource.5.name=jdbc/ExampleDB
jdbcDataSource.5.url=jdbc:cloudscape:rmi:ExampleDB;create=true
各个不同的J2ee版本的Datasource 设置文件不一样,以前的版本有的是在default.properties文件下设置的。
接下来用J2ee自带的部署工具部署应用程序,在dos窗口在键入%j2ee_home%\bin\deploytool打开deploytool工具
选择File---->New---->Application如图选择应用程序存放的地址和名字,名字以ear结尾。接下来输入显示名后按OK关闭小窗口。在左边的Frame里可以看到employeeDisName的符号。(如下图)

用鼠标选上employeeDISName,选择File---->new Enterprise Bean,第一个屏幕是一些介绍,直接按Next,在第下面的屏幕如图,填写JAR Display Name为employeeJAR。

在Contents面板点选旁边的Edit按钮,在弹出的窗口中的Starting Directory里选择first目录,用鼠标按住Ctrl键一起选择在下面的Avaliable Files里选择first下的employee下的com目录里的三个.class文件后,按Add按钮。这时在最下面的Contents of employeeJAR里就会出现这三个类文件。如下图

按OK键关闭窗口后在Contents面板里可以看到employee这个标志。按下next
在Bean Type里选择Entity,在Enterprise Bean Class里选择你的Bean Class EmployeeBean,在Remote Home Interface里选择EmployeeHome ,在Remote Interfaze里选择Employee如图后, 按下Next。

在Prisistence Management里选择Container managed prisistence (1.0),在Fields to be Persisted里把两个字段都选上,在Primary Key Class里改成java.lang.String,在Primary Key Field Name里选上employeeID,如下图所示,按Next。

在接下来的界面都按Next按钮一直到Resource References 面板,点击右边的Add按钮 在Coded Name 和下面的JNDI Name中填写jdbc/ExampleDB,如下图所示。按finish按钮结束。

如下图选择窗口左边的EmployeeBean,按下右侧Entity Tab页次的Deployment Settings按钮。

在Deployment Settings窗口取消Database Table面板里的Create table on deploy和Delete Table on undeploy。按下Database Settings在弹出的窗口里的Database JNDI Name 里填写jdbc/ExampleDB后按OK返回。按下Generate SQL Now 按钮,生成SQL语句,成功的话系统会给出一个提示,这样就生成好了sql语句,选取左边的method里的各个方法可以看到在右边SQL Query里出现相应的SQL语句。(如下图)

将所有SQL语句里的EmployeeBeanTable修改成employee后按下OK关闭窗口。

点选左边的employeeDISName,在右边选择JNDI Name标签,在Application下的JNDI标签中填写ejb/EmployeeEntityBean,这个名字要和EmployeeOut程序里的initial.lookup("ejb/EmployeeEntityBean")一样。(如下图)


接下来添加Web Component
选择File---->new Web Component,第一个窗口直接next,进入WAR File窗口,在WAR Display Name中输入一个显示名:employeeWEB。(如下图)

点击Content下的Edit按钮,弹出Edit Contents of employeeWEB的窗口里,选择first下employee下beans目录下的EmployeeOut.class文件和first目录下的login.jsp文件后点击Add按钮(如下图),按OK关闭窗口。

在WAR File窗口里按Next按钮
在Choose Component Type 窗口里选择jsp按next到Component General Properites 选择Jsp FileName为login.jsp,Web Component Name里输入EmployeeWEB。后按Finish(如下图)

点选左边窗口的employeeDISName,选取右边的Web Context的面板。在Context Root里输入employee,这相当于虚拟目录名。选择Tools----->Deploy Application,在Introduction窗口选择object to Deploy里为employeDISName,Target Server为localhost。按Next后检查JNDI有没有写对,如果正确,按Next。确认Context Root后按Next。最后按Finish开始部署应用程序。部署成功后出现如下图所示的信息。

然后打开IE输入http://localhost:8000/employee/login.jsp 就可以看到数据库的用户的姓名了。
注意事项:如果运行的时候提示找不到表或者字段的话,请把SQL语句里的表名和字段名改成大写的。因为cloudview建立好数据库后默认是大写的。
作者信箱:wengchy@shvns.com
 



版权所有:UML软件工程组织