扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
如果查看 清单 2 中 SaveEntry.java 源文件中的类 Javadoc 标记,将会看到该应用程序中 XDoclet 标记的第一个示例。这些标记定义生成 Struts 部署描述符 struts-config.xml 必需的所有属性。
清单 2. SaveEntry.java Javadoc 类标记
/**
* Save an Entry
*
* @struts.action
* name = "phoneBookEntryForm"
* path = "/pages/SaveEntry"
* scope = "request"
* input = "/pages/EditPhoneNumberPage.jsp"
* unknown = "false"
* validate = "false"
* @struts.action-forward
* name = "success"
* path = "/pages/ListNumbers.do"
* redirect = "true"
*/
该示例代码位于一个 nutshell 中,展示了 /pages/SaveEntry 动作从 EditPhoneNumberPage.jsp 中获取输入,并使用 phoneBookEntryForm 将来自页面的用户输入打包到 Java 代码中。该动作完成之后,它重定向到 /pages/ListNumbers 动作以显示号码列表。
ListNumbers 动作位于 ListNumbers.java 文件中,它使用 清单 3 中的代码调用名为 PhoneBookSession 的 Session EJB。
清单 3. ListNumbers 动作的 execute() 方法的代码段
PhoneBookSessionLocal session =
PhoneBookSessionUtil.getLocalHome().create();
// Call the method
Collection c = session.listEntries();
// Put the retrieved information into the request attributes
// so the page can render them.
request.setAttribute("numbers", c);
在 清单 3 中,可以看到 PhoneBookSessionUtil 类的使用。它是一个 XDoclet 生成的类,用于帮助获得 PhoneBookSession 对象的主接口。创建了一个会话,调用了它的 listEntries() 方法,该方法返回所有电话簿条目的集合。然后请求对象中的 numbers 属性被设置为该集合。这样做的效果是将电话号码放到指定位置,以便用于显示条目的 JSP 可以检索并写出列表,如 清单 4 所示。
清单 4. ListPhoneNumbersPage.jsp 中的 DisplayTag
<display:table name="numbers" requestURI="ListNumbers.do"
scope="request" pagesize="5" id="row_obj">
<display:column property="name" title="Name"/>
<display:column property="phoneNumber" title="Phone"/>
<display:column title="Actions">
<logic:present name="row_obj">
<html:link action="/pages/EditEntry"
paramId="id" paramName="row_obj"
paramProperty="name">Edit</html:link>
<html:link action="/pages/DeleteEntry"
paramId="id" paramName="row_obj"
paramProperty="name"
onclick="return confirmDelete('Number')">
Delete
</html:link>
</logic:present>
</display:column>
...
</display:table>
EJB 层
该应用程序中有两个 EJB 类。第一个类使用容器管理持久性(Container-Managed Persistence,CMP)来提供对简单数据库表 PhoneBookEntryBean 的基于对象的访问。第二个类是一个 Stateless Session bean,它提供业务逻辑。通常需要通过无状态会话 bean 来操作 CMP bean,因为会话 bean 可被设置来提供对数据库的事务处理,从而在发生错误时可以回滚更新。此外,在 Session bean 中执行所有 CMP 操作使得 Web 应用程序无需知道数据库访问层的任何实现细节。所以如果用另一种技术替换该层(比如使用 Hibernate 持久层),将无需更改 Web 应用程序中的代码。
XDoclet 主要用在 EJB 层中以提供部署描述符生成。这对于减少构建此类应用程序所需的维护工作是十分重要的。下载源代码并查看 PhoneBookEntryBean.java 和 PhoneBookSessionBean.java 的类 Javadoc 注释,以了解用于定义 EJB 类的大量 XDoclet 标记。
要生成无状态会话 bean 的方法,添加名为 @ejb.interface-method 的 XDoclet 标记,其视图类型属性可以为 local、remote 或 both。该属性告诉 XDoclet 在会话 bean 的本地接口、远程接口或两种接口中生成相应方法。您还可以控制事务处理类型。参见 清单 5,它是其中一个接口方法的示例,列出电话簿条目并返回它们的值对象表示。
清单 5. PhoneBookSessionBean.java 类的 listEntries() 方法
/**
* List all of the phone book entries.
* @return a collection of PhoneBookEntryValue objects.
*
* @ejb.interface-method view-type="both"
* @ejb.transaction type="Required"
*/
public java.util.Collection listEntries() {
ArrayList values = new ArrayList();
try {
Collection entries = PhoneBookEntryUtil.getLocalHome().findAll();
Iterator i = entries.iterator();
while(i.hasNext()) {
PhoneBookEntryLocal entry = (PhoneBookEntryLocal)i.next();
values.add(entry.getPhoneBookEntryValue());
}
} catch (Throwable ex) {
ex.printStackTrace();
}
return values;
}
结缔组织
在我的文章“将数据库连接到 Geronimo 应用服务器的三种方法”(developerWorks,2005 年 6 月)中详细介绍了 Geronimo 的各种部署计划的重要性。让这么小的应用程序到达功能状态是非常有挑战性的,需要在部署计划中提供许多小选项,还有 XDoclet 标记之间的交互、标记生成的代码,以及部署计划。但是详细介绍这些内容超出了本文的范围。示例程序有许多配置文件和部署计划,几乎所有的这些东西都能在项目的 src/resources 子树中找到。下文简要介绍了这些文件的相关细节,以说明需要进行哪些修改才能让将来的应用程序工作。
ear 子目录包含企业应用程序部署描述符、application.xml 文件和 geronimo-application.xml 文件。在该应用程序中,这些文件被配置以提供应用程序范围的 Java 数据库连接 (Java Database Connectivity, JDBC) 连接器。
婵犵數濮烽。浠嬪焵椤掆偓閸熷潡鍩€椤掆偓缂嶅﹪骞冨Ο璇茬窞闁归偊鍓涢悾娲⒑闂堟单鍫ュ疾濠婂嫭鍙忔繝濠傜墛閸嬨劍銇勯弽銊с€掗柟钘夊暣閺岀喖鎮滈埡鍌涚彋閻庤娲樺畝绋跨暦閸洖鐓涢柛灞剧矋濞堟悂姊绘担绛嬪殐闁搞劋鍗冲畷銏ゅ冀椤愩儱小闂佹寧绋戠€氼參宕伴崱妯镐簻闁靛牆鎳庢慨顒€鈹戦埥鍡椾簼婵犮垺锚铻炴俊銈呮噺閸嬪倹绻涢崱妯诲碍閻庢艾顦甸弻宥堫檨闁告挾鍠庨锝夘敆娓氬﹦鐭楁繛鎾村焹閸嬫捇鏌e☉娆愬磳闁哄本绋戦埞鎴﹀川椤曞懏鈻婄紓鍌欑劍椤ㄥ懘鎯岄崒鐐靛祦閹兼番鍔岄悞鍨亜閹烘垵顏╅悗姘槹閵囧嫰寮介妸褎鍣ョ紓浣筋嚙濡繈寮婚悢纰辨晣鐟滃秹鎮橀懠顒傜<閺夊牄鍔庣粻鐐烘煛鐏炶姤鍠橀柡浣瑰姍瀹曠喖顢橀悩铏钒闂備浇宕垫慨鎶芥⒔瀹ュ鍨傞柦妯猴級閿濆绀嬫い鏍ㄧ☉濞堟粓姊虹涵鍛【妞ゎ偅娲熼崺鈧い鎺嗗亾闁挎洩濡囧Σ鎰板籍閸繄顓洪梺缁樺姇瀵剙螖閸涱喚鍘搁梺鍓插亽閸嬪嫰鎮橀敃鍌涚厱閻庯綆鍋嗘晶顒傜磼閸屾稑绗ч柟鐟板閹煎湱鎲撮崟闈涙櫏闂傚倷绀侀幖顐も偓姘卞厴瀹曞綊鏌嗗鍛紱閻庡箍鍎遍ˇ浼村磿瀹ュ鐓曢柡鍥ュ妼婢ь垰霉閻樿秮顏堟箒闂佹寧绻傚Λ妤呭煝閺囥垺鐓冪憸婊堝礈濮樿泛钃熼柕濞у嫷鍋ㄩ梺缁樺姇椤曨參鍩㈤弴銏″€甸柨婵嗗€瑰▍鍥ㄣ亜韫囨稐鎲鹃柡灞炬礋瀹曢亶顢橀悢濂変紦