这个例子基于OptimalJ自带的CRM应用程序,说明了如何创建一个Web服务,将CRM应用程序的功能开放到互联网上。这个Web服务可以被第三方调用来获得顾客的服务等级信息。这个Web服务包含一个名为getServiceLevel的操作(operation)。输入参数是customerID,返回值是顾客的服务等级(BRONZE、SILVER、或者GOLD)。
1建立新工程
在开始我们的应用程序之前,我们需要为它建立工程、文件存放目录和加载文件系统。
1.1建立工程和目录
使用“project->new”来建立新工程,取名为mdasky。我们需要为应用程序创建一些目录,以分类存放应用程序的模型、代码等。
mdaSky/
工程根目录
myCode
存放中间层(middle
tier)文件,例如EJB层的代码
以及后端(backend
tier)文件,例如DBMS层的文件
myWeb 表示层文件,例如Web应用程序(基于Struts)
SolidDB
存放数据库文件
你也可以只建立mdasky目录,在mount文件系统时建立myCode目录,在生成代码时建立myWeb目录。
在[code model]视图根路径上点击鼠标右键,在弹出菜单中选择“Customize”来个性化定制一些属性,例如Javadoc文档、Java
Libraries、初始加载的供工程使用一些jar包等。
1.2 加载(mount)文件系统
在[code model]视图根节点上点鼠标右键,在弹出菜单中选择“Mount->Local
Directory”,选择我们创建的myWeb目录(而不是myCode目录),这个文件系统就加载到[code model]视图中了。
图1
加载文件系统
2设置数据库
OptimalJ默认安装中提供了SOLID数据库引擎,版本为SOLID3.5,他同时支持Windows和Linux,我们只选择Windows平台进行讲解。为了最终能够测试我们的应用程序,这里需要设置配置License、数据库连接属性,并创建数据库文件。
2.1为数据库配置License并创建数据库文件
数据库的License文件solid.lic放置在$OJ\Solid_db目录下面,将它移动到目录$OJ\SolidSDK35\WindowsNT_Intelx86\bin下面就可以了。
为方便启动数据库,我们为数据库引擎可执行程序创建一个快捷方式,目标文件设置为
$OJ\SolidSDK35\WindowsNT_Intelx86\bin\solid.exe,启动目录设置为存放数据库文件的目录d:\mdasky\SolidDB,以让它启动时自动加载我们的数据库文件。由于我们的目录是空的,所以这时你使用快捷方式启动数据库时,它会自动创建一个新的数据库文件。
点击快捷方式创建数据库,第一次运行会要求输入分类(catalog)、管理员用户名和密码。数据库默认端口是1313,可以在$OJ\
Solid_db\solid.ini文件中更改配置。
图2
设置数据库分类、管理员名称和密码
2.2配置OptimalJ使用SOLID数据库
OptimalJ中已经包含了连接数据库所需要的JDBC2.1驱动程序。选择“Tools—>Options”, 扩展“OptimalJ Configuration.Code.Generation.Databases”选择Solid,输入我们上一步配置的用户名和密码。
图3
配置OptimalJ使用SOLID数据库
2.3 配置测试选项
确认测试环境配置使用的数据库为SOLID。查看“OptimalJ.Configuration.Testing.Database
Configuration”选项,确认“Deployment
Database”为Solid数据库。至此,我们已经成功配置了SOLID数据库,使用它作为测试环境后台数据库。
图11
确认测试选项
3创建Web服务:
3.1导入CRM应用程序
点击“Model—>Import
Application”菜单,在选择文件窗口中选择$OJ\docs\tutorial\crmmodels.jar,点击Next按钮;选择$ProjectDir\myCode来作为待加载(mount)的目录。导入应用程序之后,你的Domain模型如图所示:
3.2定义一个Domain Service Operation
我们将给名为CustomerSvc的Domain Service增加操作getServiceLevel来对它进行扩展。在下面的几个步骤中这个Domain Service将被转化为一个Web服务。CustomerSvc的根类是Customer,类Call和类ServiceAgreement作为根类的成员的方式包含在根类中。
在[Domain Model]视图中,展开“crm.domain.service”节点,选择CustomerSvc,右键点击,选择“New
Child—>DomainServiceOperation”启动向导。点击上面的Add按钮来加入一个Domain Service Operation,名称为getServiceLevel,返回值类型为String。点击下面的按钮来加入一个参数,名称为custid,类型为String,类别为in(表示输入参数)
点击完成,则Domain Service模型的改变如图所示:
3.3生成各种模型
现在我们可以从Domain模型中生成Application模型,从EJB模型中生成Integration模型。
选择“Model—>Update
All Models”,在向导中选择“crm.application”模型包并点击Finish按钮,这将会生成Application模型。
注意事项:这个菜单同时也会自动生成一个Web模型,它对于后面的测试来说非常有用。它同时也可能会生成EJB模型和DBMS模型。如果我们要实现的Web服务需要访问数据库的话,则DBMS模型是必须的。
生成之后的EJB模型如图所示:
选择“Model—>Generate Model—>Generate Web Service
from EJB”启动向导,选择“crm.application.ejb”作为源包并点击Next按钮;选择“crm.integration.webservices”作为目的包并点击Finish按钮。
生成之后的Web服务Integration模型如图:
在[Application
Model]视图中,扩展“application.web”节点并选择Web module,在属性面板中,点击“usedModule”属性,使用Browse按钮来检查其值,其值应该为Web service
server module,即“crm.integration.webservices.ejbWSServerModule”。这个Web服务将会运行在Web应用程序的上下文中。Web module element代表这个Web应用程序。这就是为什么Integration层的WSServerModule在代码生成前必须被分配Web module的usedModule属性的原因。integration.webservices包中的名称为CustomerSvc的WSComponent元素代表了这个Web服务。需要注意的是,OptimalJ不会其他的EJB Session组件(例如ServiceAgreementSvc)生成任何的WSComponent,因为这个组件没有任何的业务逻辑方法,把它开放为一个Web服务是没有意义的。
3.4生成代码、WSDL和XML
Schema
这个时候Application模型和Integration模型已经被定义,我们就进入激动人心的代码生成阶段了。生成代码的同时也会生成Web服务的WSDL文件,包含类型定义的XML
Schema文件。
选择菜单“Model—>Generate
All Code”,此过程中有可能会提示你选择保存生成的代码存放路径,你可以选择一个文件系统并继续。当提示你选择保存生成的Web代码的路径时,选择$ProjectDir\myWeb目录。在[Code Model]视图中,查看$ProjectDir\myCode\crm\integration\webservices
\ejbWSServerModule目录,确保目录中包含服务器端框架(skeleton)代码、名称为ejb_top.wsdl的WSDL文件,名称为ejbxsdschema.xml的XMLSchema文件。本例中,Web服务时从EJB模型中的ejb模型包中产生的。这个模型包的名称将会被作为WSDL文件名(ejb_top.wsdl)、XMLSchema文件名(ejbxsdschema.xml)、WSServerModule名称(ejbWSServerModule)的前缀。WSDL文件同时也被拷贝到了Web context目录中。
3.5实现这个Web服务业务逻辑并编译
这时Web服务的框架代码已经完成了,我们只需要实现这个Web服务的业务逻辑。
在[Code Model]视图中,展开节点
crm.application.ejb.CustomerSvcBean.class
CustomerSvcBean.Methodsand,双击getServiceLevel方法。在源代码编辑窗口中的free block代码段,输入如下一些代码并保存。
(// your code here):
Implementation of getServiceLevel method
1 | returnValue =
"No customer found";
2 | try {
3 |
crm.application.ejb.customersvc.CustomerDataObjectCollection
| c =
getAllFindByProfileOnKey(custid);
4 | Iterator it =
c.iterator();
5 | while (it.hasNext())
{
6 |
crm.application.ejb.customersvc.CustomerDataObject
| cdao =
(crm.application.ejb.customersvc.CustomerDataObject)
| it.next();
7 |
crm.application.ejb.customersvc.ServiceAgreementDataObject
| sadao =
cdao.getServiceAgreementServiceAgreementDataObject();
8 | returnValue =
sadao.getServiceLevel().toString();
9 | };
10 | } catch
(Exception e) {};
同样是在[Code Model]视图中,选择$ProjectDir\myCode\crm,点击鼠标右键,在菜单中选择“Build All”对代码进行编译。
l
方法getAllByFindProfileOnKey返回所有key和profile相匹配的CustomerDataObjects。我们的例子中,只有一个customer匹配,所以collection中只包含一个CustomerDataObject 。
l
方法getServiceAgreementServiceAgreement返回所有跟Customer相关的ServiceAgreement(Customer和ServiceAgreement之间的关系是1:n)
l
方法getServiceLevel返回一个枚举类型,可以通过toString方法来转换为String类型。
3.6测试这个Web服务
代码生成过程中,为Web表示层生成了2个Jsp页面,它提供了简单的用户接口界面来进行getServiceLevel操作。这个测试页面对你在内部测试Web服务非常有用。两个Jsp页面的名称分别为CustomerSvcGetServiceLevelInvokerInput.jsp和CustomerSvcGetServiceLevelInvokerOutput.jsp。在测试之前,要确保SOLID数据库已经运行。
在[Code Model]视图中,使用“crm.application.ejb”包,选择“Test—>Start
EJB Server”菜单,在加载的Web context目录($ProjectDir\myWeb),选择
CustomerSvcGetServiceLevelInvokerInput.jsp文件,点击右键,选择“Execute”执行测试。
输入客户id,有效的值范围为0001、0002、0003和0004,点击Ok按钮来获得数据。
3.7部署这个Web服务
测试完成之后,这个Web服务就可以发布了。你需要做的仅仅就是包含这个Web服务的Web应用程序的URL地址。在Web Context目录中的WSDL文件可以被任何能够访问这个Web应用程序的人得到,根据这个WSDL文件,别人可以了解如何调用你的Web服务。为了使Web服务工作,需要启动应用程序服务器(Application
Server)和Web Server。
To be able to receive calls for your Web service, the application must be
running—start your application server and Web server.
从这个例子中,大家知道了开发一个Web服务的步骤:
• 定义一个Domain Service
• 从Domain模型中生成EJB模型,可选地生成WEB模型和DBMS模型。
• 从EJB模型中生成Web service
connector模型
• 生成Java代码、WSDL文件、XMLSchema文件
• 实现Web服务的业务逻辑
• 编译代码,并发布Web服务
|