引言
首先,下载 HelloWorldApp.zip,将其解压缩,得到 HelloWorld.ear,然后单击右侧的步骤 1,开始以下六个步骤。
图 1.在 HTTP 和 JMS 上使用 SOAP 访问 EJB Web 服务
如果想绕过创建和修改 Web 服务这一步,可以下载HelloWorldApp.zip(如果您还没有下载的话)并解压缩得到 HelloWorldSolution.ear。然后按照下面的步骤来测试这个方案:
将 HelloWorldSolution.ear 文件导入到 Application Developer V5.1.1 工作区。 选择 File => Import。 选择 EAR File 然后单击 Next。 在 Enterprise Application Import 窗口,定位到保存 EAR 文件的位置。 选择 HelloWorldSolution.ear,然后单击 Open。 设置 Project Name 为 HelloWorld。 单击 Finish。 将 webservices.jar 文件添加到 HelloWorldWebRouter 的构建路径中。 在 J2EE Perspective's Project Navigator 视图下,右键单击 HelloWorldWebRouter 模块,选择 Properties。 在左侧栏中选择 Java Build Path。 在左侧栏中选择 Libraries 选项卡。 单击 Add Variable。 向下滚动,选择 WAS_50_PLUGINDIR 变量然后单击 Extend...。 选择 file lib => webservices.jar 然后单击 OK。 单击 OK。 将 webservices.jar 文件添加到 HelloWorldJMSRouter 的构建路径中。 在 J2EE Perspective's Project Navigator 视图下,右键单击 HelloWorldWebRouter 模块,选择 Properties。 在左侧栏中选择 Java Build Path。 在左侧栏中选择 Libraries 选项卡。 单击 Add Variable。 向下滚动,选择 WAS_50_PLUGINDIR 变量然后单击 Extend...。 选择 file lib => webservices.jar 然后单击 OK。 单击 OK。 为通过 JMS 传输 SOAP 配置服务器(参阅步骤 2.为通过 JMS 传输 SOAP 配置 WebSphere Application Server 测试环境)。 测试 Web 服务(参阅步骤 6.为两种传输方法测试 Web 服务客户机)。步骤 1.导入 HelloWorld 企业应用程序
HelloWorld Enterprise Application Archive(EAR)这个文件包含一个 EJB 模块——HelloWorldEJB。这个模块里有一个无状态会话 bean——HelloWordSSB。该 bean 有一个 getMessage() 方法,调用这个方法时会返回一个字符串“Hello World”。下载 HelloWorld.ear 按照下面步骤将 EAR 文件导入到 Application Developer 工作区。
步骤 2.为通过 JMS 传输 SOAP 配置 WebSphere Application Server 测试环境
要为 Web 服务实现提供 SOAP/JMS 支持,必须创建所需的 JMS 资源(队列(Queue)、队列连接工厂(Queue Connection Factories)和侦听器端口(Listener Ports))来处理和响应传入的消息。下面的步骤介绍了如何为实现 HelloWorld Web 服务配置所需的 JMS 资源。
创建操作所得的新服务器配置和服务器配置条目如图 2 所示。
图 2.创建新服务器和服务器配置
添加操作所得的 WASQueueConnectionFactory 条目如图 3 所示。
图 3.添加 WASQueueConnectionFactory - HWInboundQCF
添加操作所得的 WASQueueConnectionFactory 条目如图 4 所示。
图 4.添加 WASQueueConnectionFactory - WebServicesReplyQCF
添加操作所得的 WASQueue 条目如图 5 所示。
图 5.添加 WASQueue - HWInboundQ
添加操作所得的侦听器端口条目如图 6 所示。
图 6.添加 Listener Port - HWPort
要点:对于 SOAP/JMS,在 WebSphere Application Server V5.1 测试服务器的类路径中必须包括 urlprotocols.jar 文件。这个文件包含测试应用程序必需的 JMS 协议处理类。
保存对 Server Configuration 的修改然后关闭编辑器。 选择 File => Save。 如果有提示,单击 Yes 合并对服务器配置的修改。 关闭编辑器。我们已经为 SOAP/JMS 成功配置了 WebSphere Application Server V5.1 测试环境。
步骤 3.为通过 JMS 传输 SOAP 创建一个无状态会话 EJB Web 服务
在这一步里,我们使用 Application Developer 创建一个新的 EJB 模块来将 SOAP/JMS 路由到无状态会话 bean Web 服务的实现。然后使用工具创建 Web 服务实现本身。在步骤 4 中将为 SOAP/JMS 和 HTTP/JMS 修改 Web 服务实现。
Application Developer 在 EJB 模块中创建消息驱动 Bean(MDB)。这个 EJB 模块独立于无状态会话 bean Web 服务实现模块。如果有必要,这个 MDB 会通过队列来处理传入消息、调用 Web 服务并发送响应消息。MDB 的创建是在 Application Developer 创建 Web 服务实现的过程中隐式地进行。但是,包含结果 MDB 的 EJB 模块必须在为 SOAP/JMS 创建 Web 服务实现之前创建。
根据本教程的目的,我们将创建一个新的 EJB 模块——HelloWorldJMSRouter,它将 SOAP/JMS 请求路由到 HelloWordSSB Web 服务实现。
在工作区中打开 J2EE Perspective。 创建 JMS Router Module。 在 Project Navigator 视图中,右键单击 HelloWorld Enterprise Application。 选择 New => Other。 在新弹出窗口的左侧栏中单击 EJB。 在新弹出窗口的右侧栏中单击 EJB Project。 单击 Next。 选择 Create 2.0 EJB Project bullet (缺省地被选中)。 单击 Next。 输入“HelloWorldJMSRouter”作为 Project name。 单击 Finish。 如果有提示,单击 OK 修改服务器配置并向 Server Configuration 中添加 Router Module。 为 HelloWorld 无状态会话 Bean 创建 EJB Web 服务。 在 Project Navigator 视图中。 右键单击 HelloWorldEJB EJB 模块。 选择 New => Other。 在新弹出窗口的左侧栏中单击 Web services。 在新的弹出窗口右侧栏格中单击 Web service。 单击 Next。所得的新 XML Web 服务选项如图 7 所示。
图 7.创建新的 XML Web 服务
所得的 Web 服务条目如图 8 所示。
图 8.Web service - EJB Web service
要点:如果使用的是 Application Developer V5.1 (为 WAS 5.0.2 开发的),它会在同一个 EJB 模块中创建一个 MDB 作为无状态会话 bean Web 服务实现。因此,不需要创建新的 EJB Project ,Router Project 会被设置为 HelloWordEJB。在 Application Developer V5.1 中启用 SOAP/JMS 选项和创建 MDB 时必须这样做,这个 MDB 可以通过 HelloWorldEJB Module 的队列来处理传入消息。
所得的服务部署配置条目如图 9 所示。
Figure 9. Service deployment configuration - EJB Web service图 9.服务部署配置 - EJB Web 服务
所得的 Web 服务 EJB 选项条目如图 10 所示。
图 10.Web 服务 EJB 选项 - EJB Web 服务
步骤 4.a.修改 Web 服务部署描述符来为 Web 路由器模块创建端口组件和绑定
在这一步,将为 SOAP/HTTP 传输访问 HelloWorld Web 服务实现创建一个新的端口组件和绑定配置
所得的端口组件条目如图 11 所示:
图 11.Web 服务编辑器 - 端口组件。
所得的端口组件绑定对话框条目如图 12 所示:
图 12.Web 服务编辑器 - 端口组件绑定对话框
原来的 pcBindings 条目:
<pcBindings xmi:id="PCBinding_1068756918823" pcNameLink="HelloWorld" wsdlServiceQnameNamespaceLink="" wsdlServiceQnameLocalnameLink="" scope="Session"> <securityRequestReceiverBindingConfig xmi:id="SecurityRequestReceiverBindingConfig_1068756918823"/> <securityResponseSenderBindingConfig xmi:id="SecurityResponseSenderBindingConfig_1068756918823"/> </pcBindings>
修改后的 pcBindings 条目:
<pcBindings xmi:id="PCBinding_1068756918823" pcNameLink="HelloWorld" wsdlServiceQnameNamespaceLink="" wsdlServiceQnameLocalnameLink="" scope="Session"> *** 这里删除了以下元素 *** </pcBindings> 保存修改并关闭 XML Editor。 选择 File => Save。 关闭 Editor。
这些是 Web 服务部署描述符所需的全部修改。
步骤 4.b.使用必要的端口和绑定配置修改 Web Services Description Language(WSDL)文件
在这一步,将使用所需的端口和绑定定义来修改 HelloWorldSSB.wsdl 文件,以利于 SOAP/HTTP 对 HelloWorld Web 服务实现的请求。
所得的指定绑定条目如图 13 所示。
图 13.WSDL 编辑器 - 端口定义指定绑定
所得的指定端口类型条目如图 14 所示。
图 14.WSDL 编辑器 - 端口定义指定端口类型
<wsdl:binding name="HWSSBPortComponentSoapBinding" type="intf:HelloWorldSSB"> ***从这里开始复制元素**** </wsdl:binding> <wsdl:binding name="HelloWorldSoapBinding" type="intf:HelloWorldSSB"> ***将复制的元素粘贴到这里*** </wsdl:binding> 将 HelloWorldSoapBinding 中 wsdlsoap:binding 元素的传输元素由 JMS 更改为 HTTP,如下所示:
<wsdl:binding name="HelloWorldSoapBinding" type="intf:HelloWorldSSB"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/jms"/> ... </wsdl:binding> 保存对 HelloWorldSSB.wsdl 所作的修改并关闭 WSDL Editor。 选择 File => Save。 关闭 Editor。
以上这些是对 SOAP/JMS 和 SOAP/HTTP 请求 HelloWorld Web 服务实现所需的 HelloWorldSSB.wsdl 文件所做的全部修改。
步骤 4.c.在 HTTP 路由器模块上创建 SOAP
在这一步里,创建附加的 Web 路由器模块来处理对 HelloWorld Web 服务实现的传入 HTTP 请求。
所得的端点启用程序配置条目如图 15 所示。
图 15.Web 服务端点启用程序 - HTTP 路由器
HelloWorldWebRouter Web 模块创建完成,开始处理 SOAP/HTTP 请求。
还可以选择使用 endptEnabler 命令行工具来创建 HelloWorldWebRouter 模块。 WebSphere Application Server 5.1 为开发 Web 服务实现提供了一个如同 Web 服务客户机的命令行工具—— endptEnabler。endptEnabler 命令行工具提供一个便利的向支持 Web 服务的应用程序( EAR 文件 )添加一个或多个路由模块的方法。每一个路由模块都被创建并支持 JMS 或 HTTP 的 服务端点。例如,要创建如上所述的相同的 HTTP 端点,可以使用如下的命令行:
endptEnabler -properties mypropsfile.props HelloWorld.ear
本教程的属性文件包含以下条目:
mypropsfile.props HelloWorldEJB.transports=http HelloWorldEJB.http.routerModuleName=HelloWorldWebRouter HelloWorldEJB.http.contextRoot=/HelloWorldWebRouter
本教程并没有详细描述 endptEnabler 命令行工具。要获取有关endptEnabler 和 命令行选项的详细信息,请参阅 WebSphere Application Server Info Center。endptEnabler 应该在支持 Web 服务的应用程序部署之前就运行于 WebSphere Application Server 5.1。
步骤 5.从相应的 WSDL 生成 Web 服务客户机
在这一步,将创建 Test Client 来测试我们的 Web 服务。
所得的 Web 服务客户机选择结果如图 16 所示:
图 16.Web 服务客户机代理配置
所得的 Web 服务客户机条目如图 17 所示:
图 17.Web 服务客户机环境配置
所得的 Web 服务客户机测试条目如图 18 所示。
图 18.Web 服务客户机测试
我们已经成功的生成了一个 Web 服务测试客户机,使用 SOAP/JMS 和 SOAP/HTTP 这两种传输机制来调用 HelloWorld Web 服务实现。
步骤 6.为两种传输方法测试 Web 服务客户机
所得的服务器选择条目如图 19 所示。
图 19.Web 服务测试客户机服务器选择
调用 getEndPoint 操作所得结果如图 20 所示。
图 20.Web 服务测试客户机 getEndpoint 调用
Result 框中包含着 JMS 端点 URL 字符串。
在 Web Browser 中: 在 Methods 框中单击 getMessage。 在 Inputs 框中单击 Invoke。在 Result 框中显示“Hello World”信息。图 21 显示了调用测试客户机 getMessage 操作所得的结果。
图 21.Hello World
接下来,测试在 HTTP 上使用 SOAP 的 Web 服务。
在 Web Browser 的 Methods 框中,单击 setEndpoint(String)。 要在 HTTP 上使用 SOAP 调用 Web 服务,请在 Inputs 框的端点方框中输入 http://localhost:9080/HelloWorldWebRouter/services/HelloWorld"。 在 Web Browser 中,单击 Invoke。注意:要在 JMS 上使用 SOAP 调用 Web 服务,URL 应该设置为 jms:/queue?destination=jms/HWQ&connectionFactory=jms/HWQCF&targetService=HWSSBPortComponent"。
在 Web Browser 中: 在 Methods 框中单击 getEndpoint。 在 Inputs 框中单击 Invoke。 在 Result 框中包含 HTTP 端点的 URL。 在 Web Browser 中: 在 Methods 框中单击 getMessage。 在 Inputs 框中单击 Invoke。 在 Result 框中显示“Hello World”信息。我们已经成功的测试了 Web 服务实现和使用 SOAP/JMS 和 SOAP/HTTP 传输机制来调用 Web 服务的功能。
故障诊断提示和技巧
问题:
测试应用程序和初始化 TestClient.jsp 时,会发生如下的异常:
[11/12/03 15:40:20:535 EST] 2c057c0b WebGroup E SRVE0026E: [Servlet Error]-[]: java.lang.NullPointerException at org.apache.jsp._Method._jspService(_Method.java:100) at com.ibm.ws.webcontainer.jsp.runtime.HttpJspBase.service(HttpJspBase.java:89) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) .... ....
解答:
没有把 urlprotocols.jar 文件添加到服务器类路径。参见步骤 2.为通过 JMS 传输 SOAP 配置服务器的步骤 11。
问题:
生成 Web 服务时,弹出一个窗口显示如下信息:“IWAB044E unable to get URL for project P/HelloWorldEJB”。
解答:
取消操作,关闭所有打开的编辑器和 Server Configuration 窗口。重新生成 Web 服务。如果问题依然存在,则工作区可能处于不一致状态。请尝试重新启动 Application Developer V5.1.1。
问题:
启动 HelloWorldEJB.jar 文件时,EJB 模块启动失败或是在控制台上纪录如下错误信息:
[11/13/03 17:01:50:743 EST] 4194ef52 WSServerImpl E WSWS1013E: Error: Found illegal scope: binding file=, portComponentName=HelloWorld, scope=. [11/13/03 17:01:51:484 EST] 4194ef52 WSServerImpl E WSWS1035E: Exception caught in createService: context info: wsbFileName=META-INF/ibm-webservices-bnd.xmi implClassName=com.ibm.test.webservices.ejb.HelloWorldSSB wsdlFileName=META-INF/wsdl/HelloWorld.wsdl wsdlContext=<WorkSpaceDir>\HelloWorldEJB\ejbModule \WEB-INF\wsdl\HelloWorld.wsdl portComponentName=HelloWorld. [11/13/03 17:01:52:175 EST] 4194ef52 WSServerImpl E WSWS1002E: Error processing web services deployment descriptor for module: HelloWorldEJB.jar with error: com.ibm.ws.exception. RuntimeError: WSWS1013E: Error: Found illegal scope: binding file=, portComponentName=HelloWorld, scope=. at com.ibm.ws.webservices.component.WSServerImpl.findPortBinding(WSServerImpl.java:679) at com.ibm.ws.webservices.component.WSServerImpl.createService(WSServerImpl.java:780)
[11/13/03 17:10:13:977 EST] 4e3735c8 WSServerImpl E WSWS1035E: Exception caught in createService: context info: wsbFileName=META-INF/ibm-webservices-bnd.xmi implClassName=com.ibm.test.webservices.ejb.HelloWorldSSB wsdlFileName=META-INF/wsdl/HelloWorldSSB.wsdl wsdlContext=<WorkSpaceDir> \HelloWorldEJB\ejbModule\WEB-INF\wsdl\HelloWorldSSB.wsdl portComponentName=HelloWorld. [11/13/03 17:10:14:458 EST] 4e3735c8 WSServerImpl E WSWS1002E: Error processing web services deployment descriptor for module: HelloWorldEJB.jar with error: com.ibm.ws.exception.RuntimeError: There is no deployment descriptor defined for HelloWorld RequestReceiver at com.ibm.ws.webservices.component.WSServerImpl.createRequestReceiverConfig(WSServerImpl.java:1131) at com.ibm.ws.webservices.component.WSServerImpl.createService(WSServerImpl.java:867) at com.ibm.ws.webservices.component.WSServerImpl.ejbMetaDataCreated(WSServerImpl.java:1448) at com.ibm.ws.webservices.component.WSServerImpl.metaDataCreated(WSServerImpl.java:391)
ibm-webservices-bnd.xmi 文件包含一个无效范围或为端口组件 配置的缺省设置—— portComponentName=HelloWorld。检查 HelloWorldEJB => ejbmodule => META-INF => ibm-webservices-bnd.xmi 文件中的如下条目:
<pcBindings xmi:id="PCBinding_1068756918823" pcNameLink="HelloWorld" wsdlServiceQnameNamespaceLink="" wsdlServiceQnameLocalnameLink="" scope=""> <securityRequestReceiverBindingConfig xmi:id="SecurityRequestReceiverBindingConfig_1068756918823"/> <securityResponseSenderBindingConfig xmi:id="SecurityResponseSenderBindingConfig_1068756918823"/> </pcBindings>
解答:
删除安全绑定元素并用下面修改过的条目替换上面的相应条目。参阅步骤 4.a.修改 Web 服务的部署描述符来为 Web 路由模块创建端口组件和绑定中的步骤 7。
<pcBindings xmi:id="PCBinding_1068756918823" pcNameLink="HelloWorld" wsdlServiceQnameNamespaceLink="" wsdlServiceQnameLocalnameLink="" scope="Session"> </pcBindings>
问题:
为 JMS URL 设置端点时, setEndpoint 函数将 URL 修改为无效的 JMS URL。调用 getMessage 操作时,引发如下错误:
WSWS3013E: The JMS endpoint URL is missing one or more of the following required properties: connectionFactory, destination, targetService
例如,设置 endPointURL 为:
jms:/queue?destination=jms/HWQ&connectionFactory=jms/HWQCF&targetService=HWSSBPortComponent
端点被错误的设置为:
jms:/queue?destination=jms/HWQ&connectionFactory=jms/HWQCF&targetService=HWSSBPortComponent
在生成的客户机代码里,检查 Result.jsp 文件中的 markup 方法,该方法是否修改了传递到 setEndpoint(String) 的字符串并且将字符串中出现的 '&' 全部替换为"&" ,如下面的代码段所示:
清单 1.测试客户机代码public static String markup(String text) { if (text == null) { return null; } StringBuffer buffer = new StringBuffer(); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); switch (c) { case '<': buffer.append("<"); break; case '&': buffer.append("&"); break; case '>': buffer.append(">"); break; case '"': buffer.append("""); break; default: buffer.append(c); break; } } return buffer.toString(); }
解答:
修改客户机代码,以使 JMS URL 设置正确并且当将端点设置到 JMS URL 时不会发生错误。可以修改代码,将 buffer.append("&"); 替换为 buffer.append('&'); ,或者删除 case '&': 子句,还可以注释掉相关的代码,如下所示:
清单 2.修改后的测试客户机代码public static String markup(String text) { if (text == null) { return null; } StringBuffer buffer = new StringBuffer(); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); switch (c) { case '<': buffer.append("<"); break; /*Comment this section out for JMS URLs*/ //case '&': // buffer.append("&"); // break; case '>': buffer.append(">"); break; case '"': buffer.append("""); break; default: buffer.append(c); break; } } return buffer.toString(); }
修改代码后,就可以通过改变端点来实现在 JMS 和 HTTP 端点 URL 之间的替换。
结束语
本教程演示了如何使用 Application Developer V5.1.1 和 WebSphere Application Server 5.1 Test Environment 来开发和测试一个名为 HelloWorld 的服务实现,该服务通过 SOAP/JMS 和 SOAP/HTTP 传输无状态 Bean。Application Developer 缩短了通过 JMS 和 HTTP 传输机制实现对 SOAP 的支持所需的时间。
参考资料
Web services for J2EE, V1.0 [JSR-109]
Java API for XML-Based RPC (JAX-RPC) [JSR-101]
使用 WebSphere V5 工具和技术开发和部署 Web 服务——第 1 部分:创建和测试 Web 服务
在 WebSphere Studio Application Developer V5.1 中为 J2EE Web 服务提供支持——第 1 部分:服务器环境
IBM 红皮书:WebSphere V5.1 Application Developer V5.1.1 Web 服务手册
WebSphere Application Server 信息中心
本文地址:http://com.8s8s.com/it/it13322.htm