Xdoclet生成SessionBean 和 EntityBean代码

来源:互联网 发布:黑色沙漠女法捏脸数据 编辑:程序博客网 时间:2024/06/06 04:55

xDoclet 简介

使用XDoclet,你能够在J2EE环境下更加高效地工作,你所看到的Bean以及Bean之间的关系将更加简单,许多繁杂的事情将远离你的EJB开发过程。

XDocletRickard Oberg创建的EJBDoclet工具发展而来,它的设想很简单:避免为每个EJB提供多个文件,而是从单一Bean类文件中提供组件需要的所有信息。那么,这是如何实现的呢?Java没有.NET吹嘘的“属性”,但JavaJavadoc标记。我们可以把一个特殊的@标记放入Javadoc注释,然后让一个Doclet工具处理这些标记。由工具为指定的Bean生成合适的XML描述器文件和接口文件。XDoclet建立在EJBDoclet思想的基础上,但适用范围不再局限于EJB。现在,我们已经可以用XDoclet生成Web服务、Web应用描述器,甚至还可以对它进行扩展,满足自己的特殊需要。

 

@标记有一个标准的格式,包含一个“名称空间”以及一个属于该名称空间的“标记名称”。标记的属性以“名字=值”的形式在标记中指定。下面是一个例子:

 

/**

* @namespace:tag name="value" name2="value2" ...

*/

 

当前可用的名称空间包括:

ejb 标准的EJB信息(非厂商私有的信息)

jboss 面向JBoss应用服务器的信息。

weblogic 面向BEA Weblogic应用服务器的信息。

webSphere 面向IBM WebSphere应用服务器的信息。

orion 面向Orion应用服务器(Oracle)的信息。

castor Castor框架生成映射信息。

mvcsoft MVCSoft EJB 2.0持久化管理器生成文件。

soap 生成SOAP描述器。

struts 生成struts-config.xml

web Web应用生成web.xml配置文件。

jsp 生成标记库扩展描述器信息。

从上面的清单可以看出,除了EJB之外,XDoclet还提供了许多其它方面的支持(因此它的名字也从EJBDoclet变成了XDcolet)。

myEclipse中的配置

以下本文使用eclipse结合myeclipse插件,进行ejb的开发和演示。安装好eclipsemyeclipse以后,就可以新建项目进行ejb project的开发。

1. 新建立EJB Project

 

输入工程名称:myEJB,注意,src是默认的源码输出文件夹,因为在myeclipse中很多xdoclet配置文件的输出文件目标路径默认值都是该文件夹,所以建议大家不要修改这个默认值。

 

新建立项目后,由于目前没有ejb-jar.xml的配置文件,所以会有一个warning信息:

 

这个警告信息会在xdoclet运行生成ejb-jar.xml文件后消失。

2. 鼠标右键选择新建的myejb项目,弹出窗口中选择properties

 

进入到myeclipse-xdoclet,准备进行项目的xdoclet配置

 

增加一个标准的配置,然后选择ejb的标准配置

 

这个操作将生成ejb代码的选项都进行默认的配置,不依赖于任何的应用程序服务器

 

不过我这个演示是用的jboss的服务器,所以还需要增加jboss的选项,右键点上图中的ejbdoclet的根节点,选择add来增加ejb的生成项目,在出现的选择列表中,选择jboss

 

然后配置新增加的jboss的选项,一般来说,有如下4项需要填写,见下图标记部分:

 

其中,

version表明你用的jboss的版本,我用的是jboss-4.0.3,但是只需要标记4.0即可,如果你使用的是3.2.*的版本,那就填写成为3.2

第二个是你在jboss中配置的datasource的名称

第三个是你用到的数据源映射名称,这个名称是不能够任意填写,必须按照jboss配置文件中填写,配置文件在C:jboss-4.0.3serverdefaultconfstandardjbosscmp-jdbc.xml(我的jboss安装目录)我测试用的是mysql,所以填写mySQL。如果是oracle9i的数据库,则为Oracle9i,更加详细的信息,察看standardjbosscmp-jdbc.xml文件

最后一个是生成jboss.xmljbosscmp-jdbc.xml的目标文件夹,一般生成到src/META-INF文件夹。

到这里,xdoclet的配置完成,下面将创建EntityBean的类并根据定义的tag来生成代码。

生成EntityBean代码

 

首先创建一个entitybean,名称为User,如下图所示,需要注意,包名必须最后是.ejb结尾,否则xdoclet不认

 

创建完成后,检查生成的代码,User.java,会发现在类的上方,会出现如下的tag

* @ejb.bean name="User"

* display-name="Name for User"

* description="Description for User"

* jndi-name="ejb/User"

* type="CMP"

* cmp-version="2.x"

* view-type="both"

这些是默认生成的tag,不能完全的符合我们的要求,我们修改成为如下,红色为增加的部分:

* @ejb.bean name = "User"

* type = "CMP"

* cmp-version = "2.x"

* display-name = "User"

* description = "User"

* view-type = "both"

* jndi-name = "ejb/UserHome"

* local-jndi-name = "ejb/UserLocalHome"

* primkey-field = "userId"

* @ejb.persistence table-name = "systemuser"

* @jboss.persistence table-name = "systemuser"

* @ejb:util

* generate="physical"

然后,需要为user entity增加它的几个相关的方法

在相关的地方修改这个抽象的类,修改后,红色为增加的部分:

public abstract class User implements EntityBean {

 

/** The entity context */

private EntityContext context;

 

/**

* @ejb.interface-method view-type = "both"

* @ejb.persistence column-name = "userId"

* @ejb.pk-field

*

* @return

*/

public abstract String getUserId();

/**

* @ejb.interface-method view-type = "both"

*

* @param userId

*/

public abstract void setUserId(String userId);

/**

* @ejb.interface-method view-type = "both"

* @ejb.persistence column-name = "userName"

*

* @return

*/

public abstract String getUserName();

/**

* @ejb.interface-method view-type = "both"

*

* @param userName

*/

public abstract void setUserName(String userName);

/**

* @ejb.interface-method view-type = "both"

* @ejb.persistence column-name = "Password"

*

* @return

*/

public abstract String getPassword();

/**

* @ejb.interface-method view-type = "both"

*

* @param password

*/

public abstract void setPassword(String Password);

好了,entitybean修改成为这样以后就可以生成相关的接口和实现类了

 

如果运行正常,在控制台窗口中会出现如下提示:

Buildfile: F:workspaceMyEJB.xdoclet-build.tmp.xml

N65540:

[ejbdoclet] (XDocletMain.start 47 ) Running <remoteinterface/>

[ejbdoclet] Generating Remote interface for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <localinterface/>

[ejbdoclet] Generating Local interface for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <homeinterface/>

[ejbdoclet] Generating Home interface for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <localhomeinterface/>

[ejbdoclet] Generating Local Home interface for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <dataobject/>

[ejbdoclet] Generating Data Object class for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <valueobject/>

[ejbdoclet] (XDocletMain.start 47 ) Running <entitypk/>

[ejbdoclet] (XDocletMain.start 47 ) Running <entitycmp/>

[ejbdoclet] Generating CMP class for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <entitybmp/>

[ejbdoclet] (XDocletMain.start 47 ) Running <session/>

[ejbdoclet] (XDocletMain.start 47 ) Running <dao/>

[ejbdoclet] (XDocletMain.start 47 ) Running <utilobject/>

[ejbdoclet] Generating Util class for 'com.mycom.myejb.entity.ejb.User'.

[ejbdoclet] (XDocletMain.start 47 ) Running <deploymentdescriptor/>

[ejbdoclet] Generating EJB deployment descriptor (ejb-jar.xml).

[ejbdoclet] (XDocletMain.start 47 ) Running <jboss/>

[ejbdoclet] Generating jboss.xml.

[ejbdoclet] Generating jbosscmp-jdbc.xml.

_xdoclet_generation_:

BUILD SUCCESSFUL

Total time: 8 seconds

如果你在运行中,出现了

N65540:

 

BUILD FAILED

java.lang.UnsupportedClassVersionError: xjavadoc/ant/XJavadocTask (Unsupported major.minor version 49.0)

 

的异常,建议你更换以下eclipsejre环境。例如当我用jdk1.4.2的时候就出现上述异常,更换为jdk1.5后即正常运行。

生成SessionBean代码

 

 

 

 

 

 

修改生成的类为抽象的类

public abstract class UserManager implements SessionBean {

…………….

 

修改UserManagerxdoclet标签为:

* @ejb.bean name="UserManager"

* display-name="Name for UserManager"

* description="Description for UserManager"

* jndi-name="ejb/UserManagerHome"

* type="Stateless"

* view-type="both"

 

下面将增加一个login的方法,将UserManager.java移动到最下方,你会发现xdoclet已经给你创建了一个现有的方法:

/**

* An example business method

*

* @ejb.interface-method view-type = "both"

*

* @throws EJBException Thrown if method fails due to system-level error.

*/

public void replaceWithRealBusinessMethod() throws EJBException {

// rename and start putting your business logic here

}

根据你自己的需要修改这个方法,或者增加新的方法,不过一定要保留它的ejb的标签

例如增加一个方法:

/**

* @ejb.interface-method view-type = "both"

*

* @param username

* @param password

* @return

* @throws EJBException

*/

public boolean login(String username,String password) throws EJBException {

boolean loginresult = false;

if(username.equals("gary") && password.equals("gzllm")){

System.out.println("用户名与密码匹配,允许登录系统");

loginresult = true;

}else{

System.out.println("用户名与密码不匹配,不登录失败");

loginresult = false;

}

return loginresult;

}

然后再次运行xdoclet

 

运行成功后会生成如下图所示结构的代码:

 

这个时候就生成了最常用的SessionBean的代码。

 

部署EJB程序

1、 部署ejb代码,首先需要设置你的应用程序服务器,以下我配置了一个jboss的应用程序服务器。在eclipsewindows菜单下选择preferences,选择myeclipse选项,选择你需要使用的服务器,并配置相关的路径,如下图所示:

2、 Jboss下面的进一步的选项中能够选择运行的模式,可以选择debug模式和run模式,建议现在选择debug模式

3、 JDK选用你正在使用的jdk,点ok配置结束

4、 由于发布的jbossejb程序需要用到mySQL数据库,所以还需要配置一下JBoss,首先拷贝mysql的数据库配置文件,从C:jboss-4.0.3docsexamplesjcamysql-ds.xml拷贝到需要发布的服务器中,修改配置文件数据库连接部分为:
<jndi-name>MyEJB</jndi-name>

<connection-url>jdbc:mysql://192.168.2.26:3306/MyEJB</connection-url>

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

<user-name>root</user-name>

<password>root</password>

<connection-url>jdbc:mysql://192.168.2.26:3306/MyEJB</connection-url>然后启动你自己的mysql的数据库,并创建MyEJB数据库以及相关的User表。

另外,还需要将用到的数据库连接驱动程序mysql-connector-java-3.1.10-bin.jar(我用的mysqljdbc驱动程序是mysql-connector-java-3.1.10)拷贝到应用程序服务器的lib目录中,我的目录是C:jboss-4.0.3serverdefaultlib,否则在启动jboss的时候会报异常:

16:48:25,078 WARN [JBossManagedConnectionPool] Throwable while attempting to get a new connection: null

org.jboss.resource.JBossResourceException: Could not create connection;

- nested throwable: (org.jboss.resource.JBossResourceException: Failed to register driver for: com.mysql.jdbc.Driver;

- nested throwable: (java.lang.ClassNotFoundException:

No ClassLoaders found for: com.mysql.jdbc.Driver))

5、 eclipse的工具栏中找到如图所示的一个按钮

6、 增加一个配置

7、 选择刚才配置的jboss服务器

8、 选择完成。

9、 部署完成

10、 运行ejb,点击部署旁边的一个按钮:

11、 Jboss启动过程中,可以看到,刚才写的ejb部分已经发布成功。在控制台的启动log中,你可以看到类似以下语句:17:00:16,453 INFO [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:name=MyEJB,service=DataSourceBinding' to JNDI name 'java:MyEJB'

17:00:17,312 INFO [EjbModule] Deploying User

17:00:17,812 INFO [EjbModule] Deploying UserManager

17:00:18,250 INFO [BaseLocalProxyFactory] Bound EJB LocalHome 'User' to jndi 'ejb/UserLocalHome'

17:00:18,328 INFO [ProxyFactory] Bound EJB Home 'User' to jndi 'ejb/UserHome'

17:00:22,796 INFO [BaseLocalProxyFactory] Bound EJB LocalHome 'UserManager' to jndi 'UserManagerLocal'

17:00:22,812 INFO [ProxyFactory] Bound EJB Home 'UserManager' to jndi 'ejb/UserManagerHome'

17:00:22,828 INFO [EJBDeployer] Deployed: file:/C:/jboss-4.0.3/server/default/deploy/MyEJB.jar/

说明entitybean sessionbean 部署运行成功。

JBoss的管理界面中,也可以找到如下的关于myejb.jar的部署说明:

 

 

测试EJB程序

1、 新建一个java projectproject name MyEJBTest


在项目的libraries中,将J2EE的包添加到项目中,另外还需要增加一个变量,如下图所示:
然后将新增加的变量也增加到你的项目libories中:

2、 在项目的构建路径中增加对MyEJB项目的引用:

3、 新建一个类Test

4、 编辑生成的Test的类,修改后的代码如下所示:
package com.mycompany.myejb.test;

 

import java.rmi.RemoteException;

import java.util.Properties;

 

import javax.ejb.CreateException;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import javax.rmi.PortableRemoteObject;

 

import com.mycom.myejb.session.interfaces.UserManager;

import com.mycom.myejb.session.interfaces.UserManagerHome;

 

public class Test {

Properties properties;

public Test() {

properties = new Properties();

properties.put("java.naming.factory.initial",

"org.jnp.interfaces.NamingContextFactory");

properties.put("java.naming.factory.url.pkgs",

"org.jboss.naming:org.jnp.interfaces");

properties.put("java.naming.provider.url", "jnp://localhost:1099");

properties.put("jnp.disableDiscovery", "true");

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Test t = new Test();

System.out.println("登录测试结果:" + t.testLogin("gary", "gzllm"));

System.out.println("登录测试结果:" + t.testLogin("errorUser", "gzllm"));

}

public boolean testLogin(String username, String password) {

boolean loginresult = false;

Context ctx;

try {

ctx = new InitialContext(properties);

Object object = ctx.lookup(UserManagerHome.JNDI_NAME);

UserManagerHome userManagerHome = (UserManagerHome) PortableRemoteObject

.narrow(object, UserManagerHome.class);

UserManager userManager = userManagerHome.create();

loginresult = userManager.login(username, password);

} catch (NamingException e) {

e.printStackTrace();

} catch (RemoteException e) {

e.printStackTrace();

} catch (CreateException e) {

e.printStackTrace();

}

return loginresult;

}

}

5、 如上的测试程序测试部署成功的myejb.jar中的login的方法,如果输入的用户名与密码为gary/gzllm则返回true,否则其他的就返回false,运行生成的Test,可以看到如下输出结果:

整个程序测试成功。

总结与补充

1. 由于EJB的一个最基本的设计模式Session Façade,我并没有在测试程序中直接调用User这个entitybean,甚至为了简便,甚至生成了这个类以后就没有使用它。建议在SessionBean中再调用EntityBean,也就是说,你可以在UserManager这个sessionbean中调用User这个EntityBean进行进一步的读取数据库,验证输入的用户名称与密码是否和数据库表中的数据一致,具体的访问操作,在EntityBean中操作。

2. Hibernate的出现,给ejb的使用带来了新的机遇,你可以生成hibernate的相关对象,然后在SessionBean的方法中不调用EntityBean,而是直接调用Hibernate的对象,进行数据库的访问。这将带来更大的灵活性,并能提高程序开发的效率

3. 在测试程序中,可以使用Factory模式,简化SessionBean对象的创建,并能够提高重用。

4. xdoclet不止能够创建ejb的代码,还能够产生hibernate等很多代码,需要进行相关的配置即可,这需要对xdoclet的文档进行进一步的查看与研究,另外还能够自定义tag,例如生成javascript的校验代码。Xdoclet是个好东西,就是用起来很复杂。

5. eclipseexport功能可以输出antbuild.xml文件,不过这个配置文件很基本,你可以根据生成的build配置文件,进一步的扩充,使开发-〉测试-〉打包-〉部署自动化,能提高开发效率。