为 WebSphere Business Space 开发使用 Apache Wink 从 REST 服务中检索数据的自定义树形 iWidget

开发一个 iWidget 来显示树形结构,并将它部署到由 WebSphere® 驱动的 Business Space 中。实际上,本文中将要开发的 iWidget 是一个查看器,它通过调用 RESTful Web 服务来获取数据,该服务返回 JSON 格式的数据。本文将介绍 Dijit Tree、Dijit TabContainer 以及调用 RESTful 服务的 Apache Wink 框架。

Venkat Yadavalli, 助理 IT 架构师, IBM

Venkat Yadavalli 是 IBM India 的一名助理 IT 架构师。他有近 7 年的使用 SOA 和 J2EE 技术开发企业应用程序的经验。



Vanya Jain, 软件工程师, Progress Software

Vanya Jain 是 Progress Software 的一名软件工程师,此前曾在 IBM 工作过。她有近 3 年的使用 J2EE 和 Web 服务技术开发应用程序的经验。



2011 年 10 月 31 日

概述

WebSphere 驱动的 Business Space 为跨 IBM WebSphere Business Process Management 产品组合的业务用户提供了全面的用户体验。Business Space 是一个基于浏览器的图形用户界面,它提供可定制和可协作的环境来监控、检查和管理一些公共业务流程,比如人工任务流、建模和性能指示器。通过创建一些 mashup,业务用户可以使用他们想采用的方式来查看他们想要查看的内容。

mashups 是 Web 应用程序(或 widget)的组合,配置在业务空间的页面上,可提供来自多个来源的内容。

iWidget 是基于浏览器的组件模型,可封装 Web 内容,并且可用于内容显示框架。它可以充当您创建的任何 Web 内容的包装器,这些 Web 内容包括 servlet、Java™ Server Pages (JSP) 文件、HTML、PHP 或 CGI。iWidget 组件提供了一个用来包装 Web 内容的描述符,可以将该描述符放在另一个可以呈现它的应用程序中。

iWidget 是包含已呈现的标记的 XML 文件,iWidget 受到 JavaScript 文件支持,可用来编写动态客户端脚本;它还受到 CSS 文件的支持,可用来设置标记的样式。JSP、HTML 和 HTML 片段都可以包含标记,标记也可以用 Ajax 编写。将 iWidget 放入框架中后,即可根据 widget 包装器中的规定生成并接收客户端事件。

iWidget 包含一个定义文件,可定义 iWidget 的名称、范围和内容。定义文件包含两个文件:

  • 一个 XML 文件,指定了 widget 资源、数据、事件和 HTML 标记模式。
  • 一个定义了一个类 JavaScript 文件,可以通过将该类实例化来提供 iWidget 功能。

iWidget 规范提供一个标准事件机制 iEvent,允许来自完全不同的源的 iWidget 相互通信。该规范还提供一个内容机制 iContext,用它来控制页面的整体管理,包括页面级控制、布局、协调、标准和用户定义服务。有关详细信息,请参阅 iWidget Specification v1.0 (PDF)。


样例概述

在本文中,您将开发一个 iWidget,以树形结构显示数据,并将其部署到 Business Space 中。这个 iWidget 实际上是一个数据查看器,所查看的数据来自某个存储库。数据是通过 RESTful Web 服务提取的,客户端和服务提供者之间的数据交换模式是 JSON。

您将用到以下 Dojo widget:

  • Dijit Tree,包含 ItemFileReadStore(充当存储)和 ForestStoreModel(充当模型)
  • Dijit TabContainer

图 1 描述了我们想要实现的目标:一个运行在 Business Space 中的 iWidget,它从存储库中提取数据,并以树形结构显示数据。

图 1. Business Space 中的 iWidget
Business Space 中的 iWidget

查看图 1 的大图

本文使用的样例代码可以从 下载 部分下载。


安装软件包

本节介绍本文的先决条件,以及安装在 IBM WebSphere Integration Developer 中开发 iWidget 所需的程序包的步骤。

先决条件

您需要安装以下软件来开发和部署本文的 iWidget。

用于开发的软件:

  • IBM WebSphere Integration Developer V7。
  • 供 RESTful Web 服务使用的 Apache Wink 客户端模块 JAR(在此处下载)。
  • IBM Dojo 框架(可以在 WebSphere Integration Developer 内部启用)。

用于部署的软件:

  • WebSphere Process Server 上的 Business Space。
  • Apache Wink 运行库(在此处下载)。

安装 WebSphere Integration Developer V7 中的程序包

WebSphere Integration Developer V7 和 Rational® Application Developer V7.5 都提供了 iWidget 开发框架。对于本文,我们将使用 WebSphere Integration Developer。在提到 Integrated Development Environment (IDE) 时,我们指的是 WebSphere Integration Developer。安装 WebSphere Integration Developer 时,请务必包含 Web 开发工具,如图 2 所示。

图 2. 安装程序包
安装程序包

查看图 2 的大图

本文使用的 WebSphere Integration Developer V7 的版本和构建 ID 分别是 Version 7.0.0 和 Build ID 7.0.0-20091130_1326,如图 3 所示。

图 3. WebSphere Integration Developer 的版本
WebSphere Integration Developer 的版本

创建和配置 Web 项目

iWidget 开发的第一步是创建容器项目。首先要创建一个 Web 项目。

  1. 选择 File => New => Dynamic Web Project 新建一个 Web 项目,如图 4 所示。
    图 4. 新建一个 Web 项目
    新建一个 Web 项目

    查看图 4 的大图

  2. 在 Dynamic Web Project 向导中,选择 WebSphere Process Server v7.0 作为目标运行库,选中 Add the project to an EAR,如图 5 所示。
    图 5. 指定项目细节
    指定项目细节
  3. 单击 Finish
  4. 右键单击新项目并选择 Properties => Project facets,选中以下选项,如图 6 所示:
    • Dynamic Web Module
    • Java
    • JavaScript Toolkit
    • Dojo Toolkit
    • WebSphere Web (Co-existence)
    • WebSphere Web(Extended)
    图 6. 配置项目属性
    配置项目属性

    查看图 6 的大图

    此操作将安装 Dojo Toolkit。完成该操作后,会在 WebContent 文件夹中创建一个 Dojo 文件夹,如图 7 所示。

    图 7. 包含 Dojo 文件夹的 WebContent 文件夹
    包含 Dojo 文件夹的 WebContent 文件夹

    查看图 7 的大图

现在,您完成了在 WebSphere Integration Developer 中开发 iWidget 需要的配置。


创建 iWidget

下面将在上一节中创建的动态 Web 项目中创建 iWidget。为此,请完成以下步骤:

  1. 右键单击新 Web 项目,选择 New => Other => iWidget,如图 8 所示。
    图 8. 新建 iWidget
    新建 iWidget
  2. 指定 iWidget 名称,选择 Simple Widget 作为 iWidget 类型,如图 9 所示。因为您只对创建查看器感兴趣,因此请保持 Edit mode 复选框未选中。选中这个复选框则向 IDE 表明 iWidget 将同时拥有查看和编辑模式。

    要了解关于模式和模式之间切换的更多信息,请参阅 iWidget Specification v1.0 (PDF)。

    图 9. 创建一个简单 iWidget
    创建一个简单 iWidget

    iWidget 创建后,编辑器应该如图 10 所示。

    图 10. iWidget 编辑器
    iWidget 编辑器

    查看图 10 的大图

    DemoProject1.xml 文件是 iWidget 配置文件,包含以下事项的相关信息:

    • 可用和受支持模式
    • iWidget 发布的事件
    • iWidget 处理的事件
    • iWidget 使用的资源
  3. 现在您需要创建 DemoProject1.js,这个 JavaScript 文件用于处理 iWidget 的事件和生命周期方法。为此,请右键单击 WebContent 文件夹并选择 New => Dojo Class,如图 11 所示。
    图 11. 创建一个 Dojo 类
    创建一个 Dojo 类
  4. 指定 Dojo 类的名称为 DemoProject1,文件名为 DemoProject1.js,如图 12 所示。为便于使用,下载 部分提供了这个文件。
    图 12. 创建一个用于事件处理的 JavaScript 文件
    创建一个用于事件处理的 JavaScript 文件
  5. 现在需要修改 DemoProject1.xml 文件,以便将 DemoProject1.js 文件配置为 iWidget 的控制器类。在 iWidget 编辑器中,请选择 Web 项目,并将 iScope 属性的值指定为 DemoProject1(与 .js 文件同名),如图 13 所示。
  6. 要将 .js 文件添加为 iWidget 的资源,请选择 Web 项目,然后单击 Add
    图 13. 配置 iWidget 控制器
    配置 iWidget 控制器
  7. 选择 Resource 并单击 OK,如图 14 所示。
    图 14. 将 .js 文件添加为 iWidget 的资源
    将 .js 文件添加为 iWidget 的资源
  8. 在下一个对话框中,分别将资源的 SrcId 参数指定为 jsIdDemoProject1.js,如图 15 所示。
    图 15. 关联资源和 iWidget
    关联资源和 iWidget
  9. 选择 File => Save 以保存 DemoProject1.xml。

    将 >DemoProject1.js 文件添加为 iScope 类,这支持它处理生命周期方法,以及 iWidget 的其他事件。

  10. 现在为 iWidget 添加内容。DemoProject1.xml 文件包含用来以编程方式添加 Dojo widget 的容器。在我们的示例中,您将以编程方式创建 widget,因此,DemoProject1.xml 将只包含一些 HTML div 标记,那些标记充当将在运行时添加的 dojo widget 的占位符。

    从 iWidget 编辑器中选择 Content (view) 部分并添加下列内容(参见图 16):

    <div id="_IWID_LoadingDiv"></div>
    <div id="_IWID_ContentDiv"></div<
    图 16. 创建 iWidget 占位符
    创建 iWidget 占位符
    添加 div 元素是为了显示用来加载和添加运行时内容的消息。请注意 id 属性值的使用惯例。建议遵循同样的惯例, 以便稍后可以根据需要以编程方式在代码中修改它。

下一节将详细介绍 DemoProject1.js 文件的实现细节。


实现 iWidget 的代码

由于我们只对创建查看器感兴趣,因此我们仅关注两个 iWidget 生命周期方法:onLoadonView,如清单 1 和清单 2 所示。

清单 1 中显示了 onLoad 方法的代码片段,它指定该方法初始化和加载 iWidget 操作所需的所有依赖项。

清单 1. onLoad () 函数代码
onLoad:function() {
 try {	
//Consolidated invocations of requires ().Here we can add all those 
//dependencies that will be required for the iWidget
this.loadDependencies();
var newHeight = this.iContext.rootElement.offsetParent.offsetHeight;
var newWidth = this.iContext.rootElement.offsetParent.offsetWidth;
if (newHeight > 0) {
 this.widgetHeight = newHeight;
 }
 if (newWidth > 0) {
 this.widgetWidth = newWidth;
}
   this.widgetPath = this.iContext.io.widgetBaseUri;
   this.imagePath = this.widgetPath + "/images";
   var id = this.iContext.widgetId;
   this.contentDiv = dojo.byId("_"+ id + "_ContentDiv");
   this.loadingDiv = dojo.byId("_" + id + "_LoadingDiv");
  // set up loading message
  this.loadingDiv.innerHTML = "<img src=\"" + this.imagePath + "/loading.gif\"/>"+
  "&nbsp;&nbsp;Loading...";
 } catch (ex) {
    //call the mixed-in exception handler to catch/log 
//any exceptions that occur in here 
     this.handleException(this.CLASSNAME, "onLoad()", ex.message, ex);
 }
}

在调用 onload 之后就会立即调用 onView 方法。清单 2 中显示的代码片段规定:要呈现的任何元素(Dojo widget)都在此方法中创建,并且添加到容器 div 的 DOM 节点上。

清单 2. onView() 函数代码
onView:function() {
     //Display the loading message.
     this.showLoadingMessage();

//This method holds the actual implementation where the Dijit controls are 
//instantiated and added to the contentDiv     
    this.createView();

  //Hides the loading message.      
    this.hideLoadingMessage(); 
}

注意:

  • 可以使用 console.debug 语句来有效调试 JavaScript 代码。
  • 注意,使用 console.* 进行调试时,widget 不会在 Internet Explorer 6 中正常工作。

现在看看 createView 的定义(如 清单 3 所示)和其他相关方法。在这个方法中,您将构建 Dijit Tree widget,声明它的节点选择事件,并构建 TabPanes。

清单 3. createView() 函数代码
createView: function(){
console.debug("Entered createView()"); 
//Rewrite the URI of the location of json data. It could be a response 
//from a web service, a static json file or any other json source.
var jsonUrl=this.iContext.io.rewriteURI(<”specify the source of json for the Tree
Store”>);

//Construct the Tree Store, and specify the url for the ItemFileReadStore
this._treeRequirementsStore = new dojo.data.ItemFileReadStore({url:jsonUrl});
//If in onView the _treeRequirements exists, i.e old tree, 
//destroy it and create new
if(this._treeRequirements) {
this._treeRequirements.destroyDescendants();
if(this._treeRequirements.domNode && this._treeRequirements.domNode.parentNode) {
this._treeRequirements.domNode.parentNode.removeChild(this._treeRequirements.domNode);
}
    this._treeRequirements.destroy();
    this._treeRequirements = null;
}  
//Construct the TreeModel, that interfaces with the store to fetch data 
this._treeModel = new dijit.tree.ForestStoreModel({
	store: this._treeRequirementsStore,
	query: {Id: "*"},
	rootId: "treedata",
	rootLabel: "TreeStructureData",
	childrenAttrs: ["children"]
	});
//Construct the Dijit Tree, specify the model, the Tree widget 
//interfaces with the model and gets data for rendering   	
this._treeRequirements = new dijit.Tree({
		id: "_" + this.iContext.widgetId + "_myTree",
		model: this._treeModel,
		onClick :dojo.hitch(this, "handleNodeSelected")
		});
//Add the tree DOM node to the contentDiv
this.contentDiv.appendChild(this._treeRequirements.domNode);

//It’s always important to call the startup (). Without call to startup 
//the tree will not show up.  this._treeRequirements.startup();

 //This method creates the Tab Panes		
  this.createTabContainer();

  console.debug("Exited createView()");
}

下面看看 createTabContainer() 方法的实现,如 清单 4 所示。

清单 4. createTabContainer() 函数代码
createTabContainer: function(){
console.debug("Entered _createTabContainer");
//If tabcontainer object already exists; destroy the object and its descendants	
if(this.divTabContainer) {
this.divTabContainer.destroyDescendants();
if(this.divTabContainer.domNode && 
this.divTabContainer.domNode.parentNode){
this.divTabContainer.domNode.parentNode.removeChild(
this.divTabContainer.domNode);
}
this.divTabContainer.destroyRecursive(false);
this.divTabContainer = null;
}  

//Create the Dijit TabContainer
this.divTabContainer = new  dijit.layout.TabContainer({
id: "_" + this.iContext.widgetId + "_mainTabContainer"});
   
//Create Pane1, there can be many panes depending upon the requirement	 	
if(this.pane1){
        this.pane1.destroy(true);
}
this.pane1 = new dijit.layout.ContentPane({
                 title : 'Properties',
                 id : "_" + this.iContext.widgetId + "_tab1"});
this.pane1.domNode.innerHTML="<b>Properties for the selected Requirement</b>";
   
//Add all the pane/panes to the TabContainer widget		
this.divTabContainer.addChild(this.pane1);
 
//Add the TabContainer dom node to the contentDiv	 		
this.contentDiv.appendChild(this.divTabContainer.domNode);
  
//Finally startup the TabContainer.Its important to startup the widget.
this.divTabContainer.startup();
 
console.debug("Exited _createTabContainer");
}

Tree Widget 的创建过程可以分为三个阶段:


通过 Apache Wink 框架使用 RESTful Web 服务

DemoProject1.js 文件就绪后,就可以构建 servlet 代码 来实际调用 RESTful Web 服务来获取 JSON 格式的数据。我们将用 Apache Wink Client 模块来使用 REST Web 服务。Apache Wink 是一个简单但可靠的框架,可用来构建 RESTful Web 服务。它包含用来开发和使用 RESTful Web 服务的一个 Server 模块和一个 Client 模块。

Wink Server 模块是 Java API for RESTful Web services (JAX-RS) v1.0 规范的一个完整实现。在这个实现的顶端,Wink Server 模块提供了一组额外的特性,用于简化 RESTful Web 服务的开发。

Wink Client 模块是一个基于 Java 的框架,提供了与 RESTful Web 服务进行通信的功能。该框架构建于 Java Development Kit (JDK) HttpURLConnection 之上,添加了一些旨在促进这类客户端应用程序开发的关键特性。

图 17 展示了 Apache Wink 客户端架构。

图 17. Apache Wink Client 概览
Apache Wink Client 概览

在本文的示例中,我们将使用 Apache Wink Client 模块来调用 REST URI,查看构建树形结构所需的 JSON 数据。下载 包中包含了所有需要的 JAR 文件。

有关 Apache Wink 框架的更多信息,请参阅 Apache Wink Developer Guide

Apache Wink Client 框架的部分主要功能如下:

  • 使用可配置的 JAX-RS 提供者序列化和反序列化资源。
  • 对各种内容类型(包括 Atom、JSON、RSS、APP、CSV 和 Multipart)提供内置支持,还提供 Java 中对应的对象模型。
  • 为 SSL 和 HTTP 代理提供支持。
  • 与服务器端框架类似,客户端框架拥有一个可配置的处理程序链,用于操作 HTTP 请求和响应。
  • 默认情况下,使用 java.net.HttpUrlConnection 类来实现其核心 HTTP 传输。
  • 允许轻松定制核心 HTTP 传输机制。

对于本文中的示例,Apache Wink Client 模块的使用范围是:

  • 为连接和读取指定超时时间的能力。
  • 指定预期的响应的媒体类型的能力。
  • 向服务发起一个 GET 请求的能力。
  • 传递查询参数的能力。
  • 指定标头信息的能力。

清单 5 展示如何在 servlet 中使用 Apache Wink 客户端从 RESTful Web 服务中检索数据。

清单 5. doGetData() 函数代码
private void doGetData(HttpServletRequest request,HttpServletResponse response) 
throws IOException {
#1 ClientConfig config = new ClientConfig();  
#2 config.readTimeout(120000);
#3 config.connectTimeout(120000);
#4 RestClient client = new RestClient(config);
#5 PropertyReader propReader = new PropertyReader();
#6 Resource resource = client.resource(propReader.getProperty("getDataURL"));
#7 resource.queryParam("getDataQueryParam",”2424234”);

#8 String getData = resource.accept(MediaType.APPLICATION_JSON).get(String.class);
#9 String prefix = "{'identifier': 'Id', 'label' : 'name', 'items' : ";
#10 String suffix = "}";
#11 String fullData = prefix + getData + suffix;
#12 PrintWriter writer = response.getWriter();
#13 response.setContentType("application/json;charset=UTF-8");
#14 writer.println(fullData);
#15 writer.flush();
}

清单 5 中:

  • 代码的第一部分(#1 - #4)负责创建用来调用 REST 服务的 RestClient。
  • 第二部分(#5 - #7)包含了一些自定义类方法(比如 PropertyReader),它们使用资源束 (resource bundle) 从一个属性文件读取资源 URI 的值。
  • 第三部分(#8)发出一个 GET 请求,其中 MediaType 是 JSON,我们预期的响应将是一个 JSON 字符串。
  • 第 4 部分(#9 - #15)构建 ItemFileReadStore 能够识别且 dijit.Tree 能够呈现的 JSON 字符串。最后,由于这是一个 servlet,我们会设置相应的内容类型,并使用来自 PrintWriter 的数据刷新它。

有关详细信息,请参见本文 下载 部分提供的样例代码。

一旦 iWidget 准备就绪之后,就可以将应用程序部署到 Business Space 服务器。我们会使用 Jython 脚本将我们的应用程序从 IBM WebSphere Integration Developer v7.0 部署到一台单独的服务器中。


在 Business Space 中打包并注册自定义 widget

部署之前,需要在 Business Space 中打包并注册自定义 iWidget。要在 Business Space 中使用自定义 widget,则需要在 Business Space 中注册它们,并且必须部署包含自定义 widget 的企业应用程序。关于自定义 widget 的注册信息存储在一些注册文件中,其中包括包含关于 widget 和 widget 目录的信息的目录文件,以及指定 widget 使用的端点的端点文件。

创建端点文件

端点文件规定了某个特定端点的特征。每个端点都通过其 ID 标识,并通过 <url> 标记指向一个 URL。一个端点可以有多个版本,可通过 <version> 标记对它们进行区分。下载 部分提供了一个样例端点文件,如清单 6 所示。

清单 6. 样例端点文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- START NON-TRANSLATABLE -->
<tns:BusinessSpaceRegistry xmlns:tns="http://com.ibm.bspace/BusinessSpaceRegistry"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://com.ibm.bspace/BusinessSpaceRegistry 
BusinessSpaceRegistry.xsd ">

<tns:Endpoint>
<tns:id>{demoproject}demoprojectWidgetRoot</tns:id>
<tns:type>{demoproject}demoprojectWidgetRoot</tns:type>
<tns:version>1.0.0.0</tns:version>
<tns:url>/DemoProject/</tns:url>
<tns:description>Location of widget root for Ap233Widget</tns:description>
</tns:Endpoint>

</tns:BusinessSpaceRegistry>
<!-- END NON-TRANSLATABLE -->

使用清单 6 中的内容创建一个名为 demoProjectEndpoints.xml 的端点文件。可以在任何位置创建这个端点文件,但为简单起见,请右键单击 DemoProject 并创建一个名为 endpoints 的文件夹,然后将端点文件放在该文件夹中。

创建目录文件

目录文件指定 widget 目录和 widget。widget 可以划分为不同的类别。类别可通过名称进行标识,一个类别包含一列条目,指定属于该类别的 widget。每个 widget 条目都通过一个 ID 来标识。

<definition> 标记指向 widget 的定义文件。标记 <icon><preview><previewThumbnail> 指向一些图像,可以使用它们来表示 Business Space 中的可用 widget 列表中的 widget。widget 目录使用的是 demoProjectEndpoints.xml 中指定的端点(endpoint://{demoproject}demoprojectWidgetRoot)。

目录文件还为每个 widget 指定一个帮助主题。清单 7 展示了一个样例目录文件。

清单 7. 样例目录文件
<?xml version="1.0" encoding="UTF-8" ?>
<catalog>
     <category name="DemoProjectWidget">
	<title>
		<nls-string lang="en">DemoProjectWidget</nls-string>
	</title>
	<description>
		<nls-string lang="en">DemoProject Widget</nls-string>
	</description>
	<entry id="DemoProjectWidget" unique-name="DemoProjectWidget">
	<title>
		<nls-string lang="en">DemoProject Widget</nls-string>
	</title>
	<description>
		<nls-string lang="en">DemoProject Widget</nls-string>
	</description>
	<shortDescription>
		      <nls-string xml:lang="en">DemoProject Widget</nls-string>
	</shortDescription>
<help>
endpoint://{com.ibm.bspace}bspaceWidgetHelpRootId/index.jsp?topic=/ap233viewer.help/
ap233viewer_help.html
</help>
 <icon>endpoint://{demoproject}demoprojectWidgetRoot/images/book.gif</icon>
<preview>
endpoint://{demoproject}demoprojectWidgetRoot/images/demoproject_preview.GIF
</preview>
<previewThumbnail>
endpoint://{demoproject}demoprojectWidgetRoot/images/book.gif
</previewThumbnail>
 <metadata name="com.ibm.bspace.version">1.0.0.0</metadata>
 <metadata name="com.ibm.bspace.owner">
International Business Machines Corp.
 </metadata>
<definition>
endpoint://{demoproject}demoprojectWidgetRoot/DemoProject1.xml
</definition>
/entry>
</category>
</catalog>

使用清单 7 中的内容创建一个名为 catalog_demoProject.xml 的目录文件。请右键单击 DemoProject 并创建一个名为 catalog 的文件夹,然后将文件放在文件夹中。

创建用于端点注册的 Jython 脚本文件

前面创建了注册文件,现在需要创建 Jython 管理脚本。创建一个名为 install 的文件夹,将 Jython 脚本放入其中。

使用清单 8 中的内容创建一个名为 installDemoProjectEndpoint.py 的 Jython 脚本。

清单 8. 样例端点文件
import sys
resourcePath = ‘<path to the demoProjectEndpoints.xml  file separated by  \\>'
AdminTask.updateBusinessSpaceWidgets('[-nodeName qnode -serverName server1 -endpoints "' 
+ resourcePath + '"]')

注意:

  • 使用 Jython 脚本时,总是使用双反斜杠作为文件路径的分隔符。
  • 在我们的示例中,我们将注册过程分为几个步骤。端点和 widget 在 Business Space 中独立注册;因此,我们会使用 updateBusinessSpaceWidgets 命令。
  • 您可能需要更改 nodeNameserverName,使其与您的环境匹配。

创建用于目录注册的 Jython 脚本

使用清单 9 中的内容创建一个名为 installDemoProjectCatalog.py 的 Jython 脚本。

清单 9. 样例目录注册文件
import sys
catalogPath = '<path to catalog_demoProject.xml  file separated by \\>'
AdminTask.updateBusinessSpaceWidgets('[-nodeName qnode -serverName server1 -catalogs "' 
+ catalogPath + '"]')

将 iWidget 部署到 Business Space 服务器

现在,所有的脚本和 xml 文件都已创建,是时候通过运行 Jython 脚本来注册自定义 widget 了。

注册端点

要运行刚刚创建的 Jython 脚本,请完成下面的步骤,如图 18 所示。

  1. 右键单击 installDemoProjectEndpoint.py
  2. 单击 Run As => Administrative script
  3. 选择 WebSphere Process Server v7.0 作为脚本运行时环境,并指定一个配置文件名。
  4. wsadmin arguments 输入 -connType NONE,并根据需要指定安全证书。
    图 18. 为脚本创建一个运行配置
    为脚本创建一个运行配置

    查看图 18 的大图

  5. 执行以下步骤,验证端点的注册:
    1. 登录 Integrated Solutions Console。
    2. 选择 Resources => Resource Environments => Resource Environment Providers
    3. 选择 Mashups_Endpoints => Custom Properties
    您应该看到与 widget 相关的端点,如图 19 所示。
    图 19. 服务器控制台中的已注册端点
    服务器控制台中的已注册端点

    查看图 19 的大图

注册目录文件

执行以下步骤来注册目录文件:

  1. 执行上一节中的相同步骤,但运行 installDemoProjectCatalog.py 作为管理脚本。
  2. 要验证 catalog_DemoProject.xml 的注册,请完成以下步骤:
    1. 登录 Integrated Solutions Console。
    2. 选择 Resources => Resource Environments => Resource Environment Providers
    3. 选择 Mashups_BlobConfigService => Custom Properties
    4. 确认有一个 catalog_DemoProject.xml 条目,如图 20 所示。
    5. 如果目录端点没有显示在 Integrated Solutions Console 中,则需要重新启动服务器。
      图 20. 服务器控制台中的已注册目录
      服务器控制台中的已注册目录

      查看图 20 的大图

最后,按照 部署 REST 服务 中描述的流程在服务器上安装企业应用程序(EAR 项目)。

部署 REST 服务

本文提供的 源代码 包含一个样例 RESTful 服务(DemoProjectService.war)。要部署这个文件,请完成下面的步骤:

  1. 登录 Integrated Solutions Console,如图 21 所示。
    图 21. 登录 Integrated Solutions Console
    登录 Integrated Solutions Console
  2. 选择 Applications => Application Types => WebSphere Enterprise Applications,如图 22 所示。
    图 22. 选择要安装的企业应用程序
    选择要安装的企业应用程序

    查看图 22 的大图

  3. 单击 Install,如图 23 所示。
    图 23. 安装 WAR 文件
    安装 WAR 文件

    查看图 23 的大图

  4. 单击 Local file system 并浏览到 DemoProjectService.war,然后单击 Next,如图 24 所示。
    图 24. 选择要部署的 WAR 文件
    选择要部署的 WAR 文件

    查看图 24 的大图

  5. 选择 Fast Path,单击 Next,如图 25 所示。
    图 25. 选择 Fast Path 部署
    选择 Fast Path 部署

    查看图 25 的大图

  6. 在下一个屏幕上,单击 Next,如图 26 所示。
    图 26. 配置安装选项
    配置安装选项

    查看图 26 的大图

  7. 再次单击 Next,如图 27 所示。
    图 27. 将模块映射到服务器
    将模块映射到服务器

    查看图 27 的大图

  8. 指定 /DemoProjectServiceContext Root,单击 Next,如图 28 所示。
    图 28. 映射 Web 模块的上下文的根目录
    映射 Web 模块的上下文的根目录

    查看图 28 的大图

  9. 单击 Finish
    图 29. 查看部署配置
    查看部署配置

    查看图 29 的大图

  10. 您将看到一条消息,这表明安装正在进行,如图 30 所示。
    图 30. 安装正在进行
    图 30. 安装正在进行

    查看图 30 的大图

  11. 安装完成后,单击 Save directly to the master configuration,如图 31 所示。
    图 31. 将更改保存到主配置
    将更改保存到主配置

    查看图 31 的大图

  12. 在 Deployed Applications 视图中,检查 DemoProjectService.war,然后单击 Start,如图 32 所示。
    图 32. 启动已部署的应用程序
    启动已部署的应用程序

    查看图 32 的大图

  13. 要验证服务部署,请打开 Web 浏览器并指向以下 URL:http://localhost:9082/DemoProjectService/rest/demodata。然后根据您的服务器环境更改端口号。

    注意:

    • 要与 Web 服务和其他 Web 资源交互,可以安装一个浏览器扩展(比如 POSTER for Firefox)来执行一个测试 POST。有关详细信息,请参见 参考资料 部分。
    • 要检查 JSON 结构,可以安装一个浏览器扩展(比如 JSONView for Firefox),以便 JSON 工作负载直接在浏览器屏幕上显示。要了解更多信息,请参见 参考资料 部分。
    如果看到类似于图 33 和图 34 中的响应,则说明服务已经成功部署。
    图 33. 返回数据的 RESTful 服务
    返回数据的 RESTful 服务

    查看图 33 的大图

    图 34. 来自 RESTful 服务的 JSON 响应
    来自 RESTful 服务的 JSON 响应

    查看图 34 的大图


使用 WebSphere Integration Developer 中的 Universal Test Client 测试 widget

可以在开发过程的不同阶段测试 widget。WebSphere Integration Developer V7 提供了一个 Universal Test Client (UTC),可使用 UTC 在 Business Space 中注册 iWidget 之前测试它们。Mozilla® Firebug(一个 Mozilla Firefox® 插件)是可用来测试 widget 的另一个工具,该工具提供了一些额外的调试可能性。例如,Mozilla Firebug 会显示页面加载时的所有 HTTP 请求,还会显示 JavaScript 代码执行时出现的错误。

注意:确保已经像 部署 REST 服务 中所述的那样部署了 RESTful Web 服务 WAR。

UTC 支持在 Business Space 中注册 widget 之前在沙箱模式下测试它们,这允许您单独测试 widget。例如,要使用 UTC 测试 DemoProject widget,请执行以下步骤。

  1. 在 Enterprise Explorer 中右键单击 widget 定义文件 DemoProject1.xml
  2. 选择 Run As => Run on Server
  3. 从列表中选择一个服务器,然后单击 Finish

UTC for iWidget 是一个 JSP,用于从 widget 定义文件读取内容。要联合使用 UTC 和 Mozilla Firebug,则必须在 Mozilla Firefox 中打开 JSP。要获取 UTC for iWidget JSP 的 URL,请右键单击 Universal Test Client for iWidgets 并选择 Properties。URL 显示在 Address 字段中。

图 35 展示了 UTC 中的 iWidget。

图 35. UTC 中的 iWidget
UTC 中的 iWidget
  1. 请执行以下步骤,在 Mozilla Firefox 中启用 Mozilla Firebug:
    1. 从 Firefox 浏览器窗口中选择 Tools => Add-ons
    2. Add-ons 窗口中,选择 Get Add-ons 选项卡。
    3. 在搜索字段中,键入 Firebug 并单击 Enter
    4. 选择 Firebug Add-on 并单击 Add to Firefox
    5. 单击 Install
    6. 安装该附件后,可以通过浏览器窗口右下角的小虫图标小虫图标启用它。
  2. 在 Mozilla Firefox 中打开 Universal Test Client for iWidgets JSP 的 URL,如图 36 所示。
    图 36. Firefox 中的 iWidget
    Firefox 中的 iWidget

注意:要了解关于 iWidget 调试和故障诊断的信息,请参见 参考资料 部分。

请执行以下简单步骤,以查看 Business Space 中的 widget:

  1. 在 WebSphere Integration Developer 的 Servers 视图中,右键单击服务器名并选择 Launch => Business Space,然后登录。
  2. 选择顶部的 Manage Space,然后单击 Create Space,将新空间命名为 Demo Space
  3. 在 Space Manager 窗口中,选择 Demo Space 并单击 Edit Page
  4. 将 DemoProject widget(已注册到服务器)拖到页面上。然后运行 DemoProject widget,在一个树形结构中显示数据,如图 37 和图 38 所示。
    图 37. Business Space 中的 iWidget
    Business Space 中的 iWidget

    查看图 37 的大图

    图 38. 在树形结构中显示数据的 iWidget
    在树形结构中显示数据的 iWidget

    查看图 38 的大图


结束语

在本文中,您了解了如何在 Websphere Integration Developer 中开发 iWidget。您创建了一个 iWidget,它实际上是一个查看器,可使用 RESTful Web 服务从一个存储提取数据。本文展示了在 WebSphere Business Space 中部署和运行 iWidget 的具体步骤。本文还描述了 Apache WINK 框架,以及如何使用该框架的 Client 模块与 RESTful Web 服务进行通信。


下载

描述名字大小
可部署 REST 服务DemoProjectRESTService.war5MB
样例项目交换文件DemoProjectWidgetPI.zip13.2MB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=768624
ArticleTitle=为 WebSphere Business Space 开发使用 Apache Wink 从 REST 服务中检索数据的自定义树形 iWidget
publish-date=10312011