内容


使用 Rational Application Developer V7.5 版本来进行资源注入

克服 Java Persistence API 结构对存储过程中 OUT 参数不能支持的难题

Comments
Rational® Application Developer 试用版  |   在线试用 Rational® Application Developer
获取免费的 Rational 软件工具包系列,下载更多的 Rational 软件试用版

概述

本文提供了对 Java™ Platform,Enterprise Edition 的简略介绍,并展示了平台是怎样帮助您降低开发难度的。为了让一个典型的开发任务变得更加简单,您可以使用 IBM® Rational® Application Developer v7.5 for WebSphere®。

一个具体的实例将会演示,怎样快速地创建一个完整的 Java 平台,Enterprise Edition 程序,并将其部署到 WebSphere v7.0。

Java Platform,Enterprise Edition

Java Platform,Enterprise Edition,或者 JEE,是以 Java 编程语言实施和部署企业程序的一种标准工具。最新的工具的是 Java 平台,Enterprise Edition 版本 6。有了 JEE 及其特性和功能,开发员就可以关注于构件的业务逻辑性方面,不用再为基础和集成任务而发愁了。有了 JEE,注释功能就减少了出错代码,并使得部署描述器的选择更加自由。

JEE 5 中引入的持续性结构是 Java Persistence API(JPA)结构。JPA 有一个非常重要的限制:JPA 并不能完全支持对带有 OUT 参数的存储过程的访问。

大多数的机构将它们的数据存储在关系数据库中,出于很多原因考虑根据存储过程来设计它们的信息系统。一般来说,工人们长年累月地调试存储的程序;丢弃原有方案并开发一个更好的方案,是禁止的。Java 编程语言提供了 JDBC API,它定义了怎样访问一个关系数据库。在一个企业程序中,数据源对象是通过 JNDI 查找操作来获得的。当数据源对象可以得到时,程序可以继续做 JDBC 访问。就算已经知道了做 JNDI 查找的序列,处理 JNDI 例外的操作会添加一系列标准代码。

资源注入,也叫做关系注入,是控制转化的一种特定形式。通过使用注释,您可以引用对源、EJB 以及需要的地方的引用。该注释减少了标准代码,并解决了前面所提到过的不方便之处。

当以下容器-管理构件使用注入时,JEE 5 可以透明地处理注入:

  • Servlet(servlets、servlet 筛选器、事件监听器)
  • JSP(标记处理器、标记事件监听器)
  • JSF(范围管理的 beans)
  • EJB(beans,拦截)
  • Java API for XML Web Services(JAX-WS;末端处理器 )
  • Java 平台(主(静态),登录回馈处理器)

注入只限制于 Java 平台中定义的首个类构造,包括以下的构造 :

  • SessionContext 对象
  • DataSource 对象
  • EntityManager 界面
  • TimerService 界面
  • 其他的企业 beans
  • Web 服务
  • 信息查询与话题
  • 源适配器的链接库
  • 环境条目限制于 String、Character、Byte、Short、Integer、Long、Boolean、Double 与 Float。

JEE 5 中的注入部分并不适用于任何普通的旧 Java 对象(POJO)。

接下来的代码行显示了减少了标准代码的资源注入,它简化了代码开发。

清单 1. 使用 JNDI 来查看一个容器管理的数据源
public testGetDSConnection () {

try {
        // Obtain the initial Java Naming and Directory Interface 
        // (JNDI) context.
        InitialContext initCtx = new InitialContext ();
        // Perform JNDI lookup to obtain the resource.
        // Get the DataSource.
        DataSource ds = (DataSource) 
            initCtx.lookup("java:comp/env/jdbc/Sample"); 
        // Get a connection and execute the query.
        Connection conn = ds.getConnection();
    ...

    } catch (NamingException ex) {
        // Handle failure. 
    }
清单 2. 得到一个资源注入的数据源对象
private @Resource DataSource ds;

public testGetDSConnection () {
    // Get a connection and execute the query.
    Connection con = ds.getConnection();
    ...
}

Rational Application Developer for WebSphere

Rational Application Developer for WebSphere 是一种用于设计、开发以及部署程序的 Java 集成式开发环境(IDE)。7.5 版本完全支持 JEE 5 规格。查看该篇 developersWorks 文章中最新的特性的概述:IBM Rational Application Developer V7.5 中的新特性

前提条件

为了按照本文中的范例进行操作,您必须对 Rational Application Developer for WebSphere 有基本的熟悉。另外,您还必须安装以下的构件 :

  1. Rational Application Developer V7.5 与来自 WebSphere 家族的以下程序服务器
    • IBM WebSphere Application Server v7.0
    • IBM WebSphere Application Server v6.1 与 EJB 3.0 特性包
  2. IBM DB2® 及其范例数据库和存储的程序

下面的 下载资源 部分包含了一个项目交换文件。在部署程序之前,您要编辑特定数据库对话 bean 中存储的程序变革。

通过 JDBC 来访问一个储存的程序

您可以在 DB2 安装位置中 README 文件内,找到安装一个存储过程、汇编与运行范例 Java 测试程序的指导:sqllib\samples\java.

图 1. README 文件位置
 Windows Explorer 中的 README 文件位置
Windows Explorer 中的 README 文件位置

JPA 限制

JPA 不能访问拥有 OUT 参数的存储过程。这种限制非常重要,因为大多数有用的存储过程都有一个 OUT 参数,该参数向访问程序提供了一些数据。

sqllib\samples\java\jdbc 目录中的 SpClient.java 范例程序,演示了怎样访问各种存储的程序,包括一些有 OUT 参数的程序。

按照 README 文件中的指导,您可以生成如图 2 所示的范例 SpClient 程序。

图 2. SpClient 程序的输出
命令行环境中的 SpClient 输出
命令行环境中的 SpClient 输出

访问一个带有资源注入的存储过程

您可以使用 Rational Application Developer for WebSphere 来创建一个 JEE 程序。您使用注释来向数据源添加引用,有了它您就不用创建一个 EJB 部署描述器了。因为您并不需要创建一个 EJB 部署描述器,所以您需要生成一个 WebSphere Bindings 部署描述器来完成数据源捆绑。您必须拥有该捆绑部署描述器来在 IDE 中进行测试。您还需要创建一个简单的 Web 模块,来访问对话 bean,并最终在运行 WebSphere Application Server v7 或者 v6.1 的服务器上部署和测试程序。

创建一个 JEE 程序

图 3 显示了怎样启动 EAR Application Project 向导。

  1. 点击 File > New > Enterprise Application Project
  2. 输入一个项目名。
图 3. EAR Application Project 向导
 EAR Application Project 向导中的输入区域
EAR Application Project 向导中的输入区域
  1. 点击 Next
  2. 点击 New Modules
图 4. 新的 JEE 模块
创建 JEE 模块的选择
创建 JEE 模块的选择
  1. 只选择 EJB 模块与 Web 模块。
  2. 点击 Finish 两次。

添加一个对话 bean

  1. 选择 EJB 模块。
  2. 选择 File > New > Session Bean
图 5. Create EJB 3.0 Session Bean 向导
 Create EJB 3.0 Session Bean 向导中的区域
Create EJB 3.0 Session Bean 向导中的区域
  1. 给包和类命名。
  2. 点击 Next 两次。
  3. 清除 Add bean to Class Diagram 复选框的选择。
  4. 点击 Finish

创建一个资源注入

Rational Application Developer for WebSphere 提供了一个集成化的编辑器,它可以得到代码帮助、确认、快速修复与重构的支持。

  1. 打开您在前面所创建的对话 bean 源代码,并从代码行 3 中添加以下的代码。
清单 3. 注释中的资源注入
@Stateless
public class MySession implements MySessionLocal {
@Resource
DataSource ds;
  1. 点击 Ctrl+Alt+O 来自动组织导入声明。
  2. 创建一个稍后将会被客户端程序所访问的公共方法。
  3. 添加如代码行 4 所示的代码。
清单 4. EJB 方法
public void CallStoredProc(){
        try {
        System.out.print("\nTesting Database Resource Injection");
                Connection con = ds.getConnection();
                double outMedian = 0;
        // call INOUT_PARAM stored procedure using the median returned
        // by the call to OUT_PARAM
    System.out.println("\nCall stored procedure named INOUT_PARAM");
    System.out.println("using the median returned by the call to " + 
                                 "OUT_PARAM");
              callInoutParameter(con, outMedian);
            
                } catch (SQLException e) {
                        e.printStackTrace();
                }
  }
}
  1. 从代码行 5 添加 callInoutParameter(con, outMedian)方法,可以从 SpClient.java 程序中直接得到它。
清单 5. SpClient 存储的程序访问
private void callInoutParameter(Connection con, double median) {
                try {
                        // prepare the CALL statement for INOUT_PARAM
                        String procName = "INOUT_PARAM";
                        String sql = "CALL James." + procName + "(?)";
                        CallableStatement callStmt = con.prepareCall(sql);

                        // set input parameter to median value passed back by OUT_PARAM
                        callStmt.setDouble(1, median);

                        // register the output parameters
                        callStmt.registerOutParameter(1, Types.DOUBLE);

                        if (median == 99999.99) {
                        System.out.println("-- The following error is expected! --");
                        }
                        callStmt.execute();

                        // retrieve output parameters
                        double inoutMedian = callStmt.getDouble(1);

                        System.out.println(procName + " completed successfully");
                        System.out.println("Median salary returned from " + procName
                                        + " = " + inoutMedian);

                        // clean up resources
                        callStmt.close();

                } catch (SQLException e) {
                        System.out.println(e.getMessage());
                }
        }
  1. 使用 CallStoredProc 方法:右击 CallStoredProc,然后选择 Java EE Tools > Promote Method。该操作向 Business Interface 添加方法签名,使得客户端能够访问方法。
图 6. 方法使用
使用方法的菜单选择
使用方法的菜单选择
  1. 选择 CallStoredProc() 方法。
图 7. 选择方法来使用
使用可用方法的列表
使用可用方法的列表
  1. 点击 Ok
  2. 保存类源。

生成 WebSphere Bindings 部署描述器

  1. 右击 EJB 模块。
  2. 选择 Java EE > Generate WebSphere Bindings Deployment Descriptor
图 8. 生成 WebSphere Bindings 部署描述器
WebSphere Bindings 部署描述器菜单
WebSphere Bindings 部署描述器菜单
  1. 有了 Deployment Descriptor 编辑器中的 Bindings 部署描述器(meta-data\ibm-ejb-jar-bnd.xml),点击 Add
图 9. 配置 WebSphere Bindings 部署描述器
 配置 EJB Bindings 编辑器中的捆绑
配置 EJB Bindings 编辑器中的捆绑
  1. 选择 Session,并点击 Ok。
  2. 选择您在前面所创建的对话 bean。
  3. 点击 Next
  4. 选择 Resource Reference,并点击 Next
  5. 向导会自动检查源,并返回可以绑定的适当源。
  6. 选择源(默认的名是包名 .Class 名或者数据源名)。
  7. 点击 Next
  8. 输入绑定名(图 10)。这是服务器上数据源定义所使用的相同 JNDI 名(图 11)。使用 WebSphere Administrative Console 来配置数据源。数据源会连接至安装范例数据库与存储过程的 DB2 服务器上。
图 10. 绑定名
 Session Bean 绑定的名字区域
Session Bean 绑定的名字区域
图 11. WebSphere Administrative Console 上数据源 JNDI 名
 Administrative Console Data 源页面
Administrative Console Data 源页面
  1. 点击 Finish
  2. 保存 WebSphere Binding 部署描述器。
图 12. EJB 绑定描述器
 EJB 绑定描述器中的名字与绑定名
EJB 绑定描述器中的名字与绑定名

测试 Web 客户端

  1. 点击 Web Module Properties > Java EE Module Dependencies,并选择 EJB 模块。
图 13. Java EE 模块依赖关系
向模块添加附属的设置
向模块添加附属的设置
  1. 点击 File > New > Servlet,并在 Web Module 中创建一个 servlet,来打开 New Servlet 向导。
  2. 再次使用资源注入,来使 servlet 引用对话 bean(代码行 6)。
清单 6. 使 servlet 引用对话 bean 的资源注入
private static final long serialVersionUID = 1L;
@EJB
MySessionLocal mySession;
  1. 在 servlet 引用对话 bean 之后,访问如代码行 7 所示的方法。
清单 7. 访问方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
                throws ServletException, IOException {
                mySession.CallStoredProc();
        }

部署并测试程序

  1. 启动 WebSphere 服务器。
  2. 运行服务器上的工件:在 Enterprise Explorer 视图中点击 Run As> Run on Server
  3. 选择 servlet。
图 14. 运行服务器上的工件
运行服务器上工件的选项
运行服务器上工件的选项
  1. 选择 Started WebSphere 服务器。
  2. 点击 Finish。

该操作会在服务器上部署程序,并在浏览器中运行 servlet。然后 servlet 会访问 EJB,它会访问存储的程序。注意操控台输出(代码行 7)显示了与访问 图 2 所示 JDBC 程序存储过程相同的输出。

清单 8. 操控台输出
[5/18/10 15:11:55:562 EDT] 00000013 ApplicationMg A   WSVR0221I: Application started: 
ResourceInjectedEAR
[5/18/10 15:11:55:562 EDT] 00000013 CompositionUn A   WSVR0191I: Composition unit 
WebSphere:cuname=ResourceInjectedEAR in BLA WebSphere:blaname=ResourceInjectedEAR started.
[5/18/10 15:11:55:593 EDT] 00000013 AppBinaryProc I   ADMA7021I: Distribution of 
application ResourceInjectedEAR completed successfully.
[5/18/10 15:11:55:609 EDT] 00000013 FileRepositor A   
ADMR0009I: Document cells/jamescNode05Cell/applications/ResourceInjectedEAR.ear/deltas/
ResourceInjectedEAR/delta-1274209912171 is created.
[5/18/10 15:11:55:656 EDT] 00000013 FileRepositor A   
ADMR0010I: Document cells/jamescNode05Cell/applications/
ResourceInjectedEAR.ear/deployments/
ResourceInjectedEAR/deployment.xml is modified.
[5/18/10 15:11:55:718 EDT] 00000013 FileRepositor A   
ADMR0010I: Document cells/jamescNode05Cell/applications/
ResourceInjectedEAR.ear/deployments/
ResourceInjectedEAR/META-INF/ibm-application-runtime.props is modified.
[5/18/10 15:12:12:265 EDT] 00000020 servlet       I 
com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: 
[ResourceInjectedEAR] [/ResourceInjectedEARWeb] [MyServlet]: Initialization successful.
[5/18/10 15:12:12:593 EDT] 00000020 SystemOut     O 
Testing Database Resource Injection
[5/18/10 15:12:12:593 EDT] 00000020 PrivExAction  W   
J2CA0144W: No mappingConfigAlias found for ConnectionFactory or DataSource jdbc/Sample.

[5/18/10 15:12:19:015 EDT] 00000020 WSRdbDataSour W   DSRA9542W: The JDBC Driver
 that is configured with the data source for the Application Server does not support
  the extending data source properties feature. The Application Server will not honor
   the extended data source properties.

[5/18/10 15:12:19:046 EDT] 00000020 InternalGener I   
DSRA8203I: Database product name : DB2/NT

[5/18/10 15:12:19:046 EDT] 00000020 InternalGener I   
DSRA8204I: Database product version : SQL09010

[5/18/10 15:12:19:062 EDT] 00000020 InternalGener I   
DSRA8205I: JDBC driver name  : IBM DB2 JDBC Universal Driver Architecture

[5/18/10 15:12:19:078 EDT] 00000020 InternalGener I   
DSRA8206I: JDBC driver version  : 3.1.57

[5/18/10 15:12:19:078 EDT] 00000020 InternalDB2Un I   
DSRA8212I: DataStoreHelper name is: 
com.ibm.websphere.rsadapter.DB2UniversalDataStoreHelper@78387838.

[5/18/10 15:12:19:093 EDT] 00000020 WSRdbDataSour I   
DSRA8208I: JDBC driver type  : 4


Call stored procedure named INOUT_PARAM
[5/18/10 15:12:19:359 EDT] 00000020 SystemOut     
O using the median returned by the call to OUT_PARAM
[5/18/10 15:12:22:734 EDT] 00000020 SystemOut     
O INOUT_PARAM completed successfully
[5/18/10 15:12:22:734 EDT] 00000020 

SystemOut O Median salary returned from INOUT _PARAM = 76858.2

致谢

作者感谢 Hamid Kalantari 与 Robert Weisz 对本文所做的评审工作。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=505360
ArticleTitle=使用 Rational Application Developer V7.5 版本来进行资源注入
publish-date=08052010