先决条件
本文适用于对Web编程技术(HTML,JavaScript,Ajax,XML,XSLT)有基本了解并具有使用Dojo JavaScript工具箱开发小部件的经验的开发人员。 要部署样本窗口小部件,您将需要基本的管理技能和权限,这些技能和权限是在IBMWebSphere®Application Server上部署Web应用程序WAR所必需的。 Business Glossary REST API是IBM InfoSphere产品的受支持部分。 您按照本文中的步骤开发的其他客户端组件都基于常见的Web编程技术,但未正式作为IBM产品的一部分得到支持。
总览
IBM InfoSphere Business Glossary使您可以创建,管理和共享企业词汇表和分类系统。 Business Glossary通过使用基于REST(表示状态传输)的服务的API公开了丰富的功能。 REST是一种用于设计Web服务的开放式体系结构,它使对Web 2.0技术有基本了解的开发人员可以快速构建应用程序。
本文提供了有关如何构建可嵌入到任何网页中的基于REST的组件的分步说明。 该示例组件称为BGTerm Finder小部件。 它是一种轻量级的工具,可以快速发现和修改公司的业务词汇。
以下是两个示例业务场景,这些场景演示了如何使用组件:
- 主题专家汤姆(Tom)正在审查其公司的业务词汇表,并惊讶地发现“ 实际净现值 ”一词的定义不准确。 他立即使用BGTerm Finder小部件查找术语并进行实时编辑以更正其定义。
- 销售主管Lorraine遇到“ 实际净现值 ”一词时,正在阅读商业智能报告。 她需要了解在公司中如何专门定义该术语。 她使用BGTerm Finder小部件查找术语并研究其上下文和定义。
图1显示了BGTerm Finder小部件的两个屏幕截图。 第一个屏幕快照显示用户已搜索字符串“ act”并打开了“实际净现值”一词的详细视图。 第二个屏幕截图显示用户已经单击了用于编辑术语的图标。
图1. BGTermFinder Widget屏幕截图
REST API
业务词汇表REST API允许客户端应用程序访问和编写业务词汇表内容。 REST是API的首选技术,因为它具有比其他分布式技术更多的优势。 最重要的是,它轻巧且可互操作。
该API将词汇表内容公开为资源。 这些资源通过使用URI进行寻址,并由驻留在服务器上的XML模式定义的XML文档表示。
API资源
Business Glossary REST API可以接收的资源分为两个主要集合:
- 实体资源集-该资源集包含有关业务词汇表实体的详细信息,例如类别,术语,管理者,自定义属性和其他资产。 Read API支持所有这些实体。 类别,术语和自定义属性也受Write API及其创建,更新和删除功能的支持。 有关更多信息,请参见REST API文档。
- 运营资源集-此资源集为开发客户端应用程序提供了易于使用的通用操作,例如:
- 自动完成。 词汇表中的完成建议,带有前缀(支持通配符)。
- 随处搜索。 搜索算法类似于IBM InfoSphere Business Glossary Anywhere中使用的算法(不支持通配符)。
- 搜索。 通过该操作,可以在词汇表中搜索特定的图案。 用户可以控制搜索到的特征和类别以及结果的排名(支持通配符)。
API交易
API事务由HTTP请求和响应组成。 不同的操作在请求中需要不同种类的HTTP方法。 URI和HTTP方法的组合定义了将要发生的操作。 REST接口提供以下HTTP方法:
- POST —创建资源
- GET —阅读资源
- PUT —更新资源
- 删除-删除资源
小部件设计
样本BGTerm Finder小部件遵循Web应用程序的模型-视图-控制器(MVC)架构模式。 以下是每个层及其相关技术的概述:
- 模型(XML)-定义良好的API XML资源代表数据模型。
- 视图(HTML + CSS)-小部件HTML提供结构,而CSS处理样式。
- 控制器(JavaScript)-小部件JavaScript代码执行以下操作:
- 处理用户事件
- 使用AJAX在REST API之间传递资源
- 使用XSL转换将XML资源转换为HTML片段
- 将这些片段注入DOM
- 操作用户界面
图2.小部件设计
模型(XML)
窗口小部件模型是REST API返回的XML资源。 这些资源是由服务器上的XML模式以及REST API定义的XML文档。 样本小部件使用searchResource和termResource资源。
清单1.搜索资源模型XML
<?xml version="1.0" encoding="UTF-8"?>
<searchResource xmlns="http://www.ibm.com/is/bg/rest"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/is/bg/rest
http://bghost:9080/bgrestapi/xsd/searchResource.xsd">
<searchInput>
<pattern>sa*</pattern>
<queriedClasses>
<value>term</value>
</queriedClasses>
<queriedFeatures>
<value>name</value>
</queriedFeatures>
<status>
<value>ACCEPTED</value>
<value>STANDARD</value>
<value>CANDIDATE</value>
<value>DEPRECATED</value>
</status>
<stopAfterFirstFieldMatch>false</stopAfterFirstFieldMatch>
</searchInput>
<results>
<searchResultItem>
<glossaryObject class="term">
<name>Satisfaction Rating Date</name>
<uri>bgrestapi/term/b1c497ce.e1b1ec6c.232160ba.»
06b1b806-d928-48d3.b91b.222f3e221b7c</uri>
<context>
<category>
<name>Customer</name>
<uri>bgrestapi/category/b1c497ce.»
ee6a64fe.f1020ba.46e95446-d922-42ba.9ae4.2440d424e432</uri>
</category>
</context>
</glossaryObject>
<foundInFields>
<field name="name" value="Satisfaction Rating Date"/>
</foundInFields>
<rank>1</rank>
</searchResultItem>
</results>
<pagination>
<pageNumber>1</pageNumber>
<pageSize>10</pageSize>
<numberOfPages>1</numberOfPages>
<numberOfResults>1</numberOfResults>
</pagination>
</searchResource>
清单2.术语资源模型XML
<?xml version="1.0" encoding="UTF-8"?>
<termResource xmlns="http://www.ibm.com/is/bg/rest" .»
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" »
xsi:schemaLocation="http://www.ibm.com/is/bg/rest .»
http://bghost:9080/bgrestapi/xsd/termResource.xsd">
<term>
<name>Satisfaction Rating Date</name>
<uri>bgrestapi/term/b1c497ce.e1b1ec6c.232160ba.»
06b1b806-d928-48d3.b91b.222f3e221b7c</uri>
<context>
<category>
<name>Customer</name>
<uri>bgrestapi/category/b1c497ce.ee6a64fe.f1020ba.»
46e95446-d922-42ba.9ae4.2440d424e432</uri>
</category>
</context>
<authorization>RWD</authorization>
<createdBy>
<uri>bgrestapi/user/bob</uri>
<id>builder</id>
</createdBy>
<createdOn>2009-05-04 04:01:59 PDT</createdOn>
<modifiedBy>
<uri>bgrestapi/user/bgauthor</uri>
<id>bgauthor</id>
</modifiedBy>
<modifiedOn>2009-07-08 07:28:42 PDT</modifiedOn>
<assignedTerms/>
<shortDescription>The date on which the modern Satisfaction Rating was .»
assigned to the Customer.</shortDescription>
<longDescription>The date on which the Satisfaction Rating was assigned.»
to the Customer.</longDescription>
<notes/>
<customAttributes/>
<steward class="user">
<name>Jeff Blight Jeff Blight</name>
<uri>bgrestapi/user/Jeff+B</uri>
<id>Jeff B</id>
</steward>
<parentCategory>
<name>Customer</name>
<uri>bgrestapi/category/b1c497ce.ee6a64fe.f1020ba.»
46e95446-d922-42ba.9ae4.2440d424e432</uri>
</parentCategory>
<status>STANDARD</status>
<abbreviation/>
<additionalAbbreviation/>
<example/>
<usage/>
<isModifier>false</isModifier>
<type>NONE</type>
<replacedByTerm/>
<referencedByCategories/>
<relatedTerms/>
<replacedTerms/>
<synonyms/>
<isPreferredSynonymInGroup>false</isPreferredSynonymInGroup>
<preferredSynonym/>
<assignedAssets/>
</term>
</termResource>
查看(HTML + CSS)
上一节中描述的XML模型被转换为HTML片段,并被注入到小部件DOM中。
因为我们正在开发可嵌入到任何网页中的小部件,所以我们希望节省浏览器资源并避免与包含文档的冲突。 以下是HTML和CSS代码如何完成此操作的示例:
- 利用Dojo附加点和附加事件(而不是ID)来简化片段注入
- 使用具有特定前缀的唯一CSS类名称
- 使用Dojo JavaScript工具箱将HTML占用空间最小化
清单3.小部件HTML模板
<div class="bgTermFinderWidget_main"
dojoAttachEvent="onclick : clickHandler">
<h1>InfoSphere <a dojoAttachPoint="bg_link" href="#"
target="_blank" title="Go To Business Glossary Browser">Business
Glossary</a> : Term Finder <img class="bgTermFinderWidget_logo"
src="${imagesPath}/ibm_logo_white.gif" /></h1>
<div class="bgTermFinderWidget_ds">
<div class="bgTermFinderWidget_search">
<div class="bgTermFinderWidget_tempText" dojoAttachPoint="tempText"
dojoAttachEvent="onclick: trySetFocus">Start typing to search...</div>
<input type="text" dojoAttachPoint="searchinput"
dojoAttachEvent="onblur:stopTimer,onfocus:startTimer" value="" /> <img
class="bgTermFinderWidget_searchloader" dojoAttachPoint="searchloader"
src="${imagesPath}/loading.gif" style="display: none" /></div>
<div class="bgTermFinderWidget_resultsPanel">
<div class="bgTermFinderWidget_infoHolder" dojoAttachPoint="infoHolder">
<span class="bgTermFinderWidget_info" dojoAttachPoint="info"></span></div>
<div class="bgTermFinderWidget_searchResults"
dojoAttachPoint="searchResults">
<div class="bgTermFinderWidget_showmore" /></div>
</div>
</div>
<div class="bgTermFinderWidget_itemloaderholder"
dojoAttachPoint="itemloaderholder"><img
class="bgTermFinderWidget_itemloader" dojoAttachPoint="itemloader"
src="${imagesPath}/loading_strip_static2.gif"
onclick="window.location.reload()"
title="Status Indicator | Click to reload widget" /></div>
</div>
</div>
搜索结果
小部件HTML结构中的主要div是SearchResults div。 该div负责根据用户输入的内容显示字词。
结果以SearchResult Model XML格式接收,转换为HTML片段,并附加到SearchResults div中。
HTML搜索结果片段是div标签,由Business Glossary使用的相同存储库ID(RID)唯一标识。 当用户请求时,控制器使用此RID获取完整期限资源。 还使用了一个附加的自定义HTML属性,该属性标识资源的管理者。
清单4.搜索结果HTML
<div dojoattachpoint="searchResults"
class="bgTermFinderWidget_searchResults">
<div class="page">
<div class="node"
rid="bgrestapi/term/b1c497ce.e1b1ec6c.232160ba.06b1b806-d928-48d3.b91b.222f3e221b7c">
<div class="title-closed"><a class="doOpen" href="#">Satisfaction
Rating Date</a><a class="doEdit" href="#"
title="Click to edit Description and Steward">Edit</a></div>
</div>
<div class="node"
rid="bgrestapi/term/b1c497ce.e1b1ec6c.1e1aa0bd.a73f37a7-59c2-42bf.aac9.c05e0ac0c965">
<div class="title-closed"><a class="doOpen" href="#">Source Of
Income Type Identifier</a><a class="doEdit" href="#"
title="Click to edit Description and Steward">Edit</a></div>
</div>
<div class="node"
rid="bgrestapi/term/b1c497ce.e1b1ec6c.16dda0ba.5e5d685e-aa69-4925.afd0.e2d33ce2d0bf">
<div class="title-closed"><a class="doOpen" href="#">Special
Terms Flag</a><a class="doEdit" href="#"
title="Click to edit Description and Steward">Edit</a></div>
</div>
</div>
<div class="bgTermFinderWidget_showmore" /></div>
结果节点
结果节点可以具有以下状态之一:
- 关闭
- 打开查看
- 打开进行编辑
每个状态都有一个不同的表示形式,由CSS控制。 以下三个图显示了每种状态的示例。
图6.关闭—仅显示术语名称
图7.打开查看—显示术语详细信息和编辑图标
图8.打开进行编辑–在编辑模式下使用编辑控件显示术语详细信息和管理者
控制器(小部件JavaScript代码)
小部件的中央部分是控制器。 该控制器由JavaScript代码组成,该JavaScript代码通过调用REST API对用户操作做出React。 然后,通过使用DOM操作,控制器将转换后HTML片段注入到小部件模板中。
DOM操作和冒泡技术
为了理解控制器执行DOM操作的逻辑,本节深入研究了开放节点场景。 编辑节点方案遵循类似的逻辑。
图9.序列流—打开节点
当用户单击关闭的节点时,浏览器会将目标节点的onClick事件冒泡到小部件的控制器代码的主要onClick处理程序。 主处理程序使用RID标识目标节点并调用适当的处理程序方法。
事件冒泡技术提供了将小部件的视图结构与控制器代码断开连接的能力。 该技术还遵循将所有onClick处理集中在一个地方的单选原则。
清单5. Click处理函数
clickHandler : function(evt) {
var targetNode = evt.target;
var className = dojo.attr(targetNode,"class");
if ( className == "doOpen") {
var div = targetNode.parentNode.parentNode;
this.OnItemClick( div );
}
else if ( className == "doEdit") {
var div = targetNode.parentNode.parentNode;
this.OnItemEditClick( div );
}
else if ( className == "editOK"){
var div = targetNode.parentNode.parentNode.parentNode;
this.OnEditOk (div);
}
else if ( className == "editCancel"){
var div = targetNode.parentNode.parentNode.parentNode;
this.OnEditOk (div);
}
else if ( className == "doShowMore" ) {
this.OnPageClick( dojo.attr( targetNode,"page") );
}
},
//Method is called when user clicked to open/close the node
OnItemClick:function( div){
this._currRID = dojo.attr(div,"rid");
var nodesClosedTitle = dojo.query('.title-closed' , div);
var nodesClosedBody = dojo.query('.body-closed' , div);
//Node is closed and never been open
if ( nodesClosedTitle.length > 0 && nodesClosedBody.length == 0){
//Performing Ajax call to term details
this.RequestItemDetails( this._currRID );
}
//Node is closed and was opened before
else if ( nodesClosedTitle.length > 0 && nodesClosedBody.length > 0){
nodesClosedTitle[0].className = "title-open";
nodesClosedBody[0].className = "body-open";
}
//Node is open
else{
var nodesOpenTitle = dojo.query('.title-open' , div);
var nodesOpenBody = dojo.query('.body-open' , div);
if ( nodesOpenTitle.length > 0 && nodesOpenBody.length > 0){
nodesOpenTitle[0].className = "title-closed";
nodesOpenBody[0].className = "body-closed";
}
}
},
如清单6所示,如果从未打开过该节点,则控制器通过调用RestClient.requestItemDetails异步请求术语详细信息。
清单6. RequestItemDetails函数
//Performing AJAX Request to term details
RequestItemDetails:function( rid ){
this.toggleItemLoading(1);
this._bgRestClient.requestItemDetails
( rid,this,this.itemDetailsCallback , this.onError );
},
在清单7中的代码中,控制器的回调方法首先使用XSLProcessor模块生成HTML片段,然后将其注入目标节点。
清单7. itemDetailsEditCallback函数
//Method will be called when AJAX request to term details returns .
itemDetailsEditCallback :function( xml ) {
//Extracting the rid of the term with XPath
var rid = this.extractStringValue »
( xml ,"//rest:termResource/rest:term/rest:uri" );
var div = dojo.query('div[rid=\"'+ rid +'\"]' , this.searchResults )[0];
//Processing XML of term details to create HTML edit fragment to be injected.
var element = this._bgXslProcessor.processItemDetailsEdit( xml );
//Switching display
dojo.query('.doEditBussy' , div)[0].className = "doEdit";
dojo.query('.title-open' ,div )[0].className = "title-edit";
//Injecting the HTML fragment
dojo.place( element , dojo.query('.body-open' ,div )[0] , "replace");
dojo.place( this._selectTag ,dojo.query('.stewardValue' ,div )[0],"only" );
this.toggleItemLoading(0);
},
REST客户端模块
该小部件使用Dojo JavaScript类(BGRestClient)对指定的资源执行异步REST调用。
清单8显示了执行AJAX GET和PUT异步调用的两个主要辅助函数。
清单8. REST客户端代码片段
//Performing AJAX Get Request
__performRequest: function( url , callbackMethod , errorMethod ) {
if ( this._xhr != null ) {
this._xhr.cancel();
}
this._xhr = dojo.xhrGet( { //
// The following URL must match that used to test the server.
url: url,
handleAs: "xml",
timeout: this._timeout, // Time in milliseconds
// The LOAD function will be called on a successful response.
load: callbackMethod,
// The ERROR function will be called in an error case.
error: errorMethod
});
},
//Performing AJAX Put Request
__performPutRequest: function ( url , data , callbackMethod , errorMethod ) {
return dojo.rawXhrPut( { //
// The following URL must match that used to test the server.
url: url,
handleAs: "xml",
putData : data ,
timeout: this._timeout, // Time in milliseconds
// The LOAD function will be called on a successful response.
load: callbackMethod,
// The ERROR function will be called in an error case.
error: errorMethod
});
},
请参阅bgTermFinderWidget.war中包含的BGRestClient.js文件,以查看JavaScript REST客户端的实现。
XSLProcessor模块
XSLProcessor充当跨浏览器包装器,用于将从API接收的XML资源转换为HTML片段。
主要的XSLProcessor转换函数使用浏览器的XSL转换引擎来处理XML。
清单9. XSLProcessor代码片段
__transform:function( xml , xsl ,paramsNames,paramsValues) {
var element = null;
if (dojo.isIE)
{
var template = new ActiveXObject("MSXML2.XSLTemplate");
template.stylesheet = xsl;
var processor = template.createProcessor();
processor.input = xml;
if (paramsNames != null ) {
for( i = 0 ;i < paramsNames.length ; i++){
processor.addParameter(paramsNames[i],paramsValues[i]);
}
}
processor.transform();
element = processor.output;
}
else if (dojo.isFF || dojo.isChrome)
{
xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
var i = 0;
if ( paramsNames != null ) {
for( i = 0 ;i < paramsNames.length ; i++){
xsltProcessor.setParameter(null,paramsNames[i]»
,paramsValues[i] );
}
}
//Performing the transformation of a fragment of xml
element = xsltProcessor.transformToFragment( xml , document)
}
return element;
}
Internet Explorer XSL处理器
Internet Explorer使用Microsoft.XMLDOM.transformNode方法处理具有指定XSL文档的XML节点及其后代。 该方法以转换后的节点的纯文本版本形式返回结果。
Firefox XSL处理器
Firefox通过创建XSLTProcessor的实例,导入XSL文档并使用xsltProcessor.transformToFragment方法执行转换来执行转换。 返回的结果是DOMNode。
XSL
如前所述,本文假定您已经熟悉XSLT开发,但是,请注意,Business Glossary REST API XML资源全部使用以下指定的XML名称空间声明:
http://www.ibm.com/is/bg/rest
开发XSLT时必须考虑该名称空间。 有关示例,请参见清单10。
清单10. REST API名称空间
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rest="http://www.ibm.com/is/bg/rest" >
清单11显示了如何使用声明的rest前缀的示例。
清单11.使用声明的“ rest”前缀
<div class="description">
<xsl:value-of select="rest:termResource/rest:term/rest:shortDescription"/>
</div>
小部件使用的所有XSL文件都包含在js / bg / resources / xsl目录中的bgTermFinderWidget.war文件中。
部署方式
使用以下步骤部署窗口小部件:
- 转到下载部分,然后保存bgTermFinderWidget.war文件。
- 使用WebSphere Application Server Web管理控制台来部署WAR文件。 您必须部署到Business Glossary REST API所在的同一主机上,或者部署到子域主机上。 该部署要求是由于在所有主要浏览器中实施的原始策略相同 。 该策略阻止从一个站点源加载脚本以执行对另一个源站点的AJAX调用。
- 转到已部署的WAR,然后修改Main.html文件中的RestAPIHost属性以匹配主机名。
- 要使用小部件,请打开浏览器并转到:
http:// <主机>:<端口> / bgTermFinderWidget该小部件支持以下浏览器:
- Internet Explorer版本6、7和8
- Firefox版本2和3
- 谷歌浏览器
积分
以下是集成在第三方环境中的BGTerm Finder小部件的示例。
图10. Lotus Mashup集成
如上所示,我们能够使用iWidget标准将示例窗口小部件连接到Lotus Mashup框架内的另一个窗口小部件。
图11. iGoogle
图12. Netvibes
结论
IBM InfoSphere Business Glossary 8.1.1 REST API为您提供了前所未有的能力,可以通过您自己的定制应用程序向用户公开词汇表内容。 我们希望本文中提供给您的示例将使您和您的组织开始通过REST API利用InfoSphere Business Glossary的功能。
翻译自: https://www.ibm.com/developerworks/data/library/techarticle/dm-0909infosphererest/index.html