这一系列由 5 部分组成。在前面的部分中,我们使用快速应用程序开发(Rapid Application Development,RAD)组件创建了 Java Server Faces 表单,并了解了 JSF 如何利用 Web Data Object(WDO)或 Service Data Object(SDO)技术来访问数据。在第 4 部分中,我们将来介绍一下 JSF 如何利用现有的 J2EE 技术。
这一系列文章展示了 WebSphere® Studio V5.1.1 中的 Java™ Server Faces TechnologyPreview 的特征,本文是其中的第 4 部分。该系列文章包括以下几个部分:
- 第 1 部分:创建 JSF Web 项目和页面模板
- 第 2 部分:创建 JSF 提交表单
- 第 3 部分:创建通过 Web Data Objects(WDO,很快就会成为 SDO:Service Data Objects)访问数据的 JSF应用程序
- 第 4 部分:使用 Action Handlers 和 JavaBean 数据组件集成 JSF 应用程序与 EnterpriseJava Beans
- 第 5 部分:使用 Web 服务代理组件创建 JSF Web 服务客户端。
在文章系列的 第 3 部分中,我们看到了 JSF 应用程序如何利用 Service Data Object(SDO)技术来访问数据。在本文中,我们将会看到 JSF如何利用现有的 J2EE 技术。我们将会创建一个调用现有的 EJB 应用程序的 JSF 页面,并在兼顾 JSF 的 RAD 性质的前提下运用 JavaBeanData 控制来显示 EJB 调用结果。另外,我们将会使用 Quick Edits 视图来编写 Action Handler,以便调用现有的无状态会话Bean。
要想完成这些练习,您需要 下载包含在本文中的资料。万一您还没完成第 3 部分,下载文件包含了解决方案;请按照 第3 部分所描述的方法导入该 EAR 文件。要想运行示例,您还需要按照第 3 部分所阐述的方法创建数据库;导入解决方案之后,请按照第 3部分最后一节描述的方法运行应用程序,这样就可在用于此练习的 Server Configuration 中创建 JDBC 数据源。
现在我们来为
第2 部分创建的 Stock Data Page 创建下一个 JSF 结果页面。首先我们导入现有的 EJB JAR 文件,然后创建显示结果的JSF 页面。
- 要想导入 EJB JAR 文件并使它成为现有 EAR 文件的一部分,您需要执行以下的步骤:
- 在 WebSphere Studio Application Developer(以后简称为 Application Developer)中选择
File => Import。
图 1. Application Developer File 菜单
- 选择
EJB JAR file,然后单击
Next。
图 2. File Import 对话框
- 定位到
C:\JSFArticleSeries\Part4\StockSystemEJB.jar。Project 名称应该为
StockSystemEJB。选择现有的EAR 文件
StockSystemEAR。(您必须显式地选择现有的 EAR;它在缺省情况下为
StockSystemEJBEAR,这可能容易让人误解。)单击
Finish。
图 3. EJB Import
- 在弹出 Repair Server Configuration 对话框时,请单击
OK。
图 4. Repair Server Configuration
- 在 WebSphere Studio Application Developer(以后简称为 Application Developer)中选择
File => Import。
- 既然已经将 EJB JAR 文件导入现有的 EAR 之后,现在就需要让它对 WAR 文件可视。可以这样来实现:将 EJB JAR 文件添加到 WAR文件的清单中,这种方式是处理类路径的标准 J2EE 方式之一。Application Developer提供了一种完成这一操作的简单方法:在一个步骤中将 EJB JAR 同时添加到构建时和编译时类路径中。
- 右键单击 Project Navigator 视图中的
PersonalTradeJSFWeb 项目,选择
Properties。
图 5. Project Navigator
- 选择
Java JAR Dependencies。在该对话框中,选中
StockSystemEJB.jar。确保
Use EJB JAR也被选中。(对于 Version 5.1.1,Application Developer 支持会生成 EJB Client JAR)。
图 6. Java JAR Dependencies
- 单击 OK。
- 右键单击 Project Navigator 视图中的
PersonalTradeJSFWeb 项目,选择
Properties。
- 在我们的应用程序中,PersonalTradeJSF 会访问 StockFacadeEJB。StockFacadeEJB与实体 bean 相结合来访问当前股票数据。访问 EJB 时使用 EJB 引用被视为一种最佳实践。虽然 EJB JAR 提供了委托来隐藏 EJB客户端 API 的细节,但它使用了资源引用。由于委托是在 Web 应用程序的上下文里调用的,所以还需要定义引用。
- 在 Project Navigator 中,利用 PersonalTradeJSF 底下的链接打开
Web Deployment Descriptor编辑器。
图 7. 打开 Web Deployment Descriptor
- 选择该编辑器底部的
References选项卡。
图 8. References 选项卡
- 选择 References 页面中的
EJB Local选项卡。
图 9. EJB Local References
- 选择 EJB Local References 选项卡下的
Add。
图 10. 添加 EJB Local references
- 添加名为
ejb/StockFacade的引用。
图 11. 添加 ejb/StockFacade
- 在 Details 部分单击
Browse按钮。
图 12. Details 和 WebSphere Bindings
- 选择
StockFacadeEJB 并单击
OK。
图 13. 选择 StockFacade EJB
- 会话 bean 和绑定信息都必须填写完整。
图 14. Details 和 WebSphere Bindings
- Web 应用程序会使用 EJB 本地接口来访问数据。EJB 本地接口将符号作为输入并返回一个 AccessStockQuoteVO。这是一个带有 getters 和 setters 的简单 JavaBean。
public interface StockFacadeLocal extends javax.ejb.EJBLocalObject { public AccessStockQuoteVO getCurrentStockData(String symbol) throws SymbolNotFoundException, StockException, InvalidSymbolException; ... }
- EJB JAR 提供了一个简单的 Delegate 对象,它隐藏了对象的复杂性。该委托是一个单独的 Java 对象,它提供了一个类似的接口。
public class AccessQuoteDelegate { private StockFacadeLocal stockFacade; public static AccessQuoteDelegate accessQuoteDelegate = null; public static AccessQuoteDelegate getAccessQuoteDelegate() throws StockException { if(accessQuoteDelegate == null) { accessQuoteDelegate = new AccessQuoteDelegate(); } return accessQuoteDelegate; } private AccessQuoteDelegate() throws StockException { InitialContext context; try { context = new InitialContext(); StockFacadeLocalHome home = (StockFacadeLocalHome)context.lookup("java:comp/env/ejb/StockFacade"); stockFacade = home.create(); } catch (NamingException e) { throw new StockException(e.getLocalizedMessage()); } catch (CreateException e) { throw new StockException(e.getLocalizedMessage()); } } public AccessStockQuoteVO getCurrentStockData(String symbol) throws SymbolNotFoundException, StockException, InvalidSymbolException { return stockFacade.getCurrentStockData(symbol); } }
- 在 Project Navigator 中,利用 PersonalTradeJSF 底下的链接打开
Web Deployment Descriptor编辑器。
设置好 EJB对象之后,我们就可以创建 Stock Data 页面,用它来显示调用 StockFacade stockData 方法的结果。
- 首先,我们创建一个新的 JSF 页面来显示提交 Stock Data Request 的结果。
- 在 Application Developer 中,右键单击 PersonalTradeJSF 页面中的
WebContent文件夹,选择
New => Faces JSP File。
图 15. 创建新的 JSF 页面
- 在 File Name 字段中键入
viewStockData.jsp,然后选择 Create from page template。
图 16. New Faces JSP File
- 确保选中
StockPageTemplate.jtpl。单击
Finish。
图 17. Page Template File Selection
- 在 Application Developer 中,右键单击 PersonalTradeJSF 页面中的
WebContent文件夹,选择
New => Faces JSP File。
- 现在我们使用 Visual Palette 来添加标签。
- 在 Faces Visual Palette 中选择
Output组件。
图 18. Visual Palette
- 将 Output 组件添加到页面中。将文本大小设为 18,文本值设为:
View Stock Data。
图 19. 将 Output 添加到 JSP 中
- 在 Faces Visual Palette 中选择
Output组件。
- EJB 返回一个正规的 Java Bean。我们将作为页面数据添加该 Java Bean。
- 转到 Page Data 视图。右键单击
JSP Scripting并选择
New => JavaBean。
图 20. 创建新的 JavaBean
- 在 Add Managed Beans 对话框中选择
New。
图 21. Add Managed Beans 对话框
- 单击
Browse...按钮。
图 22. Create a Managed Bean 对话框
- 查找 AccessStockQuoteVO;它是调用 StockFacade Session Bean 时返回的数据。
图 23. Class Selection 对话框
- 在 Name 字段中键入
stockData,在 Scope 字段中选择 request。
图 24. Create a Managed Bean 值
- 单击
OK。
图 25. Add Managed Bean 值
- 现在 stockData 对该页面已经可用了。
图 26. Page Data
- 转到 Page Data 视图。右键单击
JSP Scripting并选择
New => JavaBean。
- 现在我们就可以将 stockData bean 从 Page Data 视图拖到 JSP 页面中。
- 从 Page Data 视图中选择
stockData对象,将它拖到 JSP 中的 View Stock Data 组件下,如图 27 所示。
图 27. 将 Data Object 拖到 JSP 中
- 选择
Create output components。
图 28. Select drop action 对话框
- JSP 现在就包含了与 JavaBean 相匹配的 JSP 元素了。
图 29. JSP 元素
- 从 Page Data 视图中选择
stockData对象,将它拖到 JSP 中的 View Stock Data 组件下,如图 27 所示。
- 我们需要更新输出组件的属性,以使显示界面对用户更加友好。
- 选中 JavaBean 组件中的任何一个地方。转移到 Attributes 对话框,选择
TABLE,如图 30 所示。在 Table 选项卡中,在 Border 一项中键入
0。
图 30. Attributes 对话框
- 选中
symbol字段标题,将首字母改为大写。
图 31. 选择字段标题
- 此外,在 Attribute 项中,对于每个字段名称 Cell 均选择
Header。
图 32. Cell 属性
- Header 必须为粗体。
图 33. Header 字段
- 修改所有其他的标题元素,如图 34 所示。
图 34. 其余的标题元素
- 选中 JavaBean 组件中的任何一个地方。转移到 Attributes 对话框,选择
TABLE,如图 30 所示。在 Table 选项卡中,在 Border 一项中键入
结果页面创建之后,我们需要为提交页面创建 Action Handler,以便与 EJB相交互。这些完成之后,我们需要收集结果以便配置恰当的导航规则。我们可以使用控制的 Quick Edit 项来将 Server Side Actions添加到应用程序中。
- 添加一个操作到 accessStock.jsp 页面中。
- 打开 accessStock.jsp 页面。
图 35. 打开 accessStock.jsp
- 选择
Submit Stock Request按钮。
图 36. JSP 中的 Submit Stock Request 按钮
- 在 Quick Edit 按钮菜单中选择 Command。
图 37. Quick Edit 菜单
- 代码提供在
下载文件中。将
C:\JSFArticleSeries\Part4\CodeSnippet1.txt中的代码复制到 Quick Edit 窗口的编辑区中。主要的代码段是在try块中,但也包含了一些异常捕获和错误处理的代码:-
try块得到 Delegate 的一个实例,并调用business 方法(该方法也依次调用 StockFacadeEJB)。结果返回 AccessStockQuoteVO。我们将返回结果存储在 stockData名称下的请求作用域中。viewStockData.jsp就是通过该名称期待获得这一结果的。(符号输入是从请示作用域中获得的。)try { com.deploybook.stock.delegate.AccessQuoteDelegate accessQuote = com.deploybook.stock.delegate.AccessQuoteDelegate.getAccessQuoteDelegate(); com.deploybook.stock.vo.AccessStockQuoteVO accessQuoteForm = accessQuote.getCurrentStockData((String)requestScope.get("symbol")); requestScope.put("stockData",accessQuoteForm); }
- 如果我们捕获到一个异常,我们就在按钮组件中添加一个错误方法。
codebehind对象根据属性中配置的名称实例化页面中的每个组件。然后返回 failure。如果没有对失败返回值配置导航的话,它就会返回到同一个页面。我们可以添加一个链接到按钮控制的错误组件。catch (com.deploybook.stock.exceptions.StockException e) { e.printStackTrace(System.err); context.addMessage(buttonEx1, new javax.faces.application.MessageImpl( javax.faces.application.Message.SEVERITY_ERROR, "Stock Not found", "Symbol Not Found or invalid" )); return "failure"; } catch (com.deploybook.stock.exceptions.SymbolNotFoundException e) { e.printStackTrace(System.err); context.addMessage(buttonEx1, new javax.faces.application.MessageImpl( javax.faces.application.Message.SEVERITY_ERROR, "Stock Not found", "Symbol Not Found or invalid" )); return "failure"; } catch (com.deploybook.trade.exception.InvalidSymbolException e) { e.printStackTrace(System.err); context.addMessage(buttonEx1, new javax.faces.application.MessageImpl( javax.faces.application.Message.SEVERITY_ERROR, "Stock Not found", "Symbol Not Found or invalid" )); return "failure"; }
- 如果所有的执行都成功完成,那么我们返回success。然后再来配置导航。
return "success";
-
- Quick Edit 应该包含这些代码,如图 38 所示。
图 38. 包含代码的 Quick Edit 对话框
- Java 代码会自动添加,打开
accessStock.java即可确认是否自动添加代码。
图 39. 打开 accessStock.java
图 40. accessStock.java 代码
- 打开 accessStock.jsp 页面。
- 现在我们需要指定导航规则。我们并不需要第 3 部分所做的那样,让提交操作对执行结果进行硬编码,而只需指定返回导航结果的操作处理程序。
- 在依旧选中该按钮的前提下,切换到 Attribute 视图。选择
Navigation选项卡,然后单击
Add按钮。
图 41. Navigation 属性
- 选择
viewStockData.jsp作为 Page 的值。在 Alias 字段中键入
success(它也是由操作处理程序返回的)。在 ActionRef 字段中选择 cb_accessStock.buttonEx1Action。
图 42. Add Navigation Rule 对话框
- 我们并不需要为控制指定操作结果,因为操作会控制它。
图 43. 添加的 Navigation 属性
- 在依旧选中该按钮的前提下,切换到 Attribute 视图。选择
Navigation选项卡,然后单击
Add按钮。
- 我们已经为按钮组件将错误存储为消息了,因此我们需要在提交页面中建立一个错误组件。
- 在 Faces Component 面板中选择
Display Error组件。
图 44. Visual Palette
- 将它拖到 JSP 页面中 Access Stock 标题和输入表单之间的地方。
图 45. 将错误组件添加到 JSP 中
- 选中输出组件,然后切换到 Attribute 视图。在
For validation errors on项的 Id 字段中选择
buttonEx1。
图 46. 输出组件属性
- 在 Faces Component 面板中选择
Display Error组件。
在测试应用程序之前,我们还需要对服务器配置做两个更新。然后再来测试成功的和错误的场景。
- 我们需要创建一个验证别名,并使 CMP 支持生成的 WDO 数据源。这就可以让 EJB JAR 中的实体像 WDO 对象那样使用同一个数据源了。
- 转到 Servers 视图,方式是选中 Web 透视图底部的
Servers选项卡。双击服务器来打开 Server Configuration编辑器。
图 47. 打开 Server Configuration 编辑器
- 选择 Server Configuration 编辑器的
Security选项卡。
图 48. Server Configuration 编辑器选项卡
- 单击 JAAS Authentication Entries 旁边的
Add。
图 49. JAAS Authentication Entries
- 在 Alias 字段中键入
DBUser。在 User ID 和 Password 字段中键入db2admin(或者键入任何您要在创建数据库时使用的密码)。
图 50. 添加新的用户 ID 和密码
图 51. 添加的 JAAS 验证实体
- 切换至 Data source 透视图。
图 52. 选择 Data source 选项卡
- 在 Server Settings 下选择
WDO DB2 JDBC Provider,然后单击 Data source 列表中的
Edit按钮。
图 53. Server Settings
- 在 Container-managed authentication alias 字段中选择
DBUser,并选中
Use this data source in container managed persistence (CMP)的复选框。
图 54. 编辑数据源
- 单击 Save并关闭服务器编辑器。
- 转到 Servers 视图,方式是选中 Web 透视图底部的
Servers选项卡。双击服务器来打开 Server Configuration编辑器。
- 现在开始运行应用程序:
- 在 Project Navigator 中右键单击
accessStock.jsp并选择
Run on Server。
图 55. 运行应用程序
- 选中
Deploy EJB beans,然后单击
Finish。
图 56. Select Tasks 对话框
- 在字段中键入
IBM并单击 Submit Stock Request。
图 57. 用有效数据进行测试
- 返回如图 58 所示的结果。
图 58. 成功的测试结果
- 返回提交页面,并键入
IBB作为 Enter Stock 的值。
图 59. 用无效数据进行测试
- 页面中会显示错误信息,如图 60 所示。(控制台也会显示业务异常栈踪迹。)
图 60. 测试结果失败
- 停止服务器。
- 在 Project Navigator 中右键单击
accessStock.jsp并选择
Run on Server。
在本系列的这一部分中,我们为您显示了 JSF 如何使用 RAD性质的任何业务层代码。特别是,我们为现有的 Enterprise JavaBean 集设计了一个 JSF 前台。另外,我们还使用 Quick Edits视图来将 Action Handling 添加到我们的 JSF 应用程序中,同时也添加了错误处理。在本系列的结束篇中,我们将编写一个基于 JSF 的Web 服务客户端来显示如何在集成场景中使用 JSF。
作者真诚感谢 Beverly DeWitt 对本文所做出的贡献。
| 名字 | 大小 | 下载方法 |
|---|---|---|
| JSFArticleSeriesP4.zip | 12.2 MB | HTTP |