 | 级别: 中级 John Feller, 经理,Emerging Technologies Toolkit Development 团队, IBM Chris Gladd, 准专业级实习程序员, IBM
2009 年 7 月 27 日 学习如何使用 IBM® Rational® Host Access Transformation Services 提取 3270 或 5250 数据,然后使用这些数据构成一个 Atom 数据提要。IBM Mashup Center 可以将这个数据提要与其他数据源合并起来,从而为业务用户创建一个新的情景应用程序。我们通过一个例子展示如何从 3270 金融应用程序提取数据、创建 Atom 提要、为提要创建目录,以及使用该数据为信贷员创建一个信息指示板。
目前,很多企业信息都保存在主机应用程序中,并且通过 3270 或 5250 控制台访问它们。如果这些主机数据的格式允许它们与其他数据轻松合并的话,不管存在于企业内部还是 Internet 上,业务用户都能够通过浏览器界面利用它们帮助解决业务问题。我们在本文中描述了一个用例,其中 3270 数据应用程序中存在非常有价值的金融信息,而信贷员希望提取该数据以创建一个新的基于 Web 的混搭应用程序。混搭应用程序是轻量级的 Web 应用程序,它由来自多个源的信息或特性合并而成,能够提供新的功能和洞察力。可以分离和打包绿屏(3270)应用程序的有用部分,然后在混搭应用程序框架中使用它们,从而为业务用户提供新的业务见解。
首先,在混搭应用程序框架中使用主机的内容之前,必须将它们格式化为数据提要。本文提供一个分步指南,演示如何使用 Rational® Host Access Transformation Services (HATS) 为主机内容生成 Atom 提要。由 Ramakrishnan Kannan、Prasad Nagaraj 和 Saikrishna Vaidyanathan 撰写的 developerWorks® 文章 “使用 HATS 为大型机应用程序产生 Atom feed” 演示了如何使用 3270 数据创建 Atom 提要。本文通过另一个例子扩展了他们的概念,使用 IBM Mashup Center 创建了一个情景 Web 应用程序。
场景概述
某银行的金融服务信贷员需要访问一些数据,以确定当前的银行客户能否获得新的汽车贷款。在绿屏 3270 主机应用程序中,这位信贷员能够找到这位客户的当前账户余额。然后,她必须通过 Web 应用程序获取该账户持有者的信用额度。她可以通过另一个应用程序了解贷款人所在的地区的汽车失窃报告。现在,为了确定这位客户是否能够获得新的汽车贷款,信贷分析员需要使用 3 种不同的应用程序(信贷员)访问所需的信息。本文主要关注如何从 3270 应用程序提取数据。假设 IBM Mashup Center 提要生成器已经将信用额度和汽车失窃报告转换为数据提要,或者可以通过 Web 浏览器访问这些数据。
目前,账户余额信息是通过 3270 应用程序访问的,如图 1 所示。
图 1. 3270 应用程序数据
您可以使用 IBM Rational Host Access Transformation Services (HATS) 创建 Atom 数据提要。然后可以将数据提要与其他数据合并,从而为信贷员创建一个复合的指示板应用程序,如图 2 所示。
图 2. 复合指示板应用程序
HATS Atom 提要详解
下面是一个分步指南和一些代码模板例子,您可以遵循指导从 3270 应用程序提取数据并放到混搭应用程序中。
创建一个新的 HATS 项目
创建一个使用默认设置的 Rational Host Access Transformation Services (HATS) 项目。下面是实现步骤:
- 在 Connections Settings 窗口中输入主机名。所有其他字段以默认填充;您可以根据需求修改它们。单击 Finish。图 3 显示了一组连接设置;您的设置可能与此不同。
图 3. HATS Create a Connection 窗口
记录宏
通过以下步骤记录一个用于查询信息的宏:
- 右键单击您的主连接,然后单击 Open HATS Host Terminal 和 main。
您应该会看到如图 4 所示的 3270 应用程序屏幕。
图 4. 在 HATS 主机终端环境中的 3270 应用程序登录屏幕
- 在屏幕的顶部单击 Record 按钮,然后为宏提供一个名称。
- 单步调试您希望使用的流程,然后通过单击 Add Extract Action 按钮选择希望从每页提取的数据。如图 5 所示。
图 5. 选择提取 3270 数据的区域
- 为每个提取操作选择 Extraction Format 选项 “Extract this region as a list of strings”,这样在随后的列表中每行都是一个不同的条目。所有其他值都是默认设定的。单击 Finish。
图 6. Edit Extract 窗口
创建 Integration Object
通过以下步骤从宏创建一个 Integration Object:
- 右键单击宏并选择 Create Integration Object 选项。
- 在 Integration Object 下面打开新的 Java™ 源代码;它与这个宏同名。(见本文附录清单 A-1 中的样例代码)。
- 注意顶部已定义的 HAOVariables。在实例化这些变量时将它们的最后一个参数从 HAO_VARIABLE_SIMPLE 改为 HAO_VARIABLE_ARRAY。通过更改该参数,您可以得到所提取行的数组,而不是一个由很多行组成的字符串。按照以下做法更改参数:
-
从:
HAOVariable inquiry1 =
new HAOVariable("","inquiry1","inquiry1",false,"",0,0,63,7,HAO_VARIABLE_SIMPLE);
-
更改为:
HAOVariable inquiry1 =
new HAOVariable("","inquiry1","inquiry1",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
- 现在为每个返回 your_inquiry.oMultiValues 的查询添加一个 Getter 类型的向量。请查看清单 1 的代码。
清单 1. 查询结果数组的 Getter
public Vector getInquiry1AsVector()
{
hPubErrorOccurred = 0;
if (HPubTracingOn) { Ras.trace( className, "getInquiry1 array: ",
inquiry1.stringValue); }
return (inquiry1.oMultiValues);
}
|
创建 Model 1 Web 页面
接下来,通过从 Integration Object 右键单击集成对象并选择 Create Model 1 Web Pages 选项创建 Model 1 Web 页面。如图 7 所示。
图 7. Create Model 1 Web Pages 窗口
一直使用默认设置,最后单击 Finish 在 Model 1 Pages 目录下创建一个 JSP 页面。
更改 JSP 页面
接下来,更改 JSP 页面以输出 Atom 提要。遵循以下步骤:
- 现在,在 Web Content - Model 1 Pages 目录下有了一个 JSP 页面;双击查看源代码。
- 使用所提供的 JSP 文件 InquiryMacroOutput.jsp(见本文附录的清单 A-2)作为样例,然后用您自己的 JSP 代码(输出 Atom 提要)代替原有的 JSP 代码。不要担心关于参数化 ArrayList 的警告,因为 JSP 不处理参数化。
测试 JSP 页面
要测试 JSP 页面,请进入其端点并查看 Atom 提要。
如果您使用的是 Microsoft® Internet Explorer 浏览器,您进入的页面应该如图 8 所示。
图 8. 从 JSP 页面生成的 Atom 提要
添加新的 Atom 提要
要将新的 Atom 提要添加到 IBM InfoSphere™ MashupHub,请遵循以下步骤:
- 打开 InfoSphere MashupHub 并单击 MashupHub Homepage 的 Create 部分下面的 New Feed。
- 选择图 9 中 departmental 下列出的 Existing RSS or Atom Feed (Registration)。然后单击 Next。
图 9. 在 IBM Mashup Center 中创建新提要的面板
- 输入您创建的 JSP 页面的 URL,然后单击 Next。见图 10。
图 10. 在 MashupHub 提要创建窗口中指定 Atom 提要 URL
- 给新提要添加一个 Title 或 Description,以及添加其他与该提要相关的标记,然后单击 Finish。
- 现在,提要已经保存到 InfoSphere MashupHub Catalog。您可以通过选择 Add to Lotus Mashups 选项将其添加到 IBM Lotus Mashups。
- 输入您的 Lotus Mashups 服务器的位置,然后单击 Next。
- 您还可以更改 Title、Description、Category 或 Feed Viewer 选项,然后单击 Finish。
使用提要在 Lotus Mashups 中构建混搭应用程序
遵循以下步骤使用您的提要在 Lotus Mashups 中构建一个混搭应用程序:
- 打开 Lotus Mashups,并可选地为您的混搭应用程序选择一个新页面。
- 单击 Go to Edit 按钮开始构建混搭应用程序。
- 从工具栏中选择您的提要;默认情况下,它显示在工具栏的 Collaboration 选项中,如图 11 所示。将您的提要拖拽到页面上。如果有必要,可以调整它的大小。
图 11. Mashup Center 中显示 3270 数据的 Atom 提要的数据查看器小部件
- 在工具栏上单击 Favorites 选项,然后添加希望在混搭应用程序中使用的 OpenStreetMap 和其他小部件。在我们的示例中,有一些提要提供特定区域的 Credit Report History 和 Car Theft Reports。在这里要用到 OpenStreetMap 和 Website Displayer 小部件。将来自 3270 数据表的元素连接到这些新的小部件中,从而创建一个能够满足您的业务需求的定制应用程序。
- 当单击提要中的一个条目时,您应该会在地图上看到相应的汽车失窃信息,以及在 Website Displayer 小部件中看到信用报告信息,如图 12 所示。
图 12. 完成后的 Loan Officer Dashboard 混搭应用程序
结束语
IBM Mashup Center 和 Rational Host Access Transformation Services 使您能够在其他基于 Web 的应用程序中使用 3270 或 5250 应用程序中的数据。本文为如何提取 3270 数据并创建一个新的情景应用程序提供了逐步指南。此外,还提供了代码模板,您可以适当修改它们,以从各种 3270 应用程序中提取数据。
附录:代码清单
清单 A-1. 集成对象(InquiryMacro.java)的代码
import java.util.Vector;
import com.ibm.HostPublisher.IntegrationObject.*;
import com.ibm.HostPublisher.Server.Ras;
public class InquiryMacro extends HPubHODCommon
{
public static float getIOTemplateVersion()
{ return 7.0F; } // Template version - HATS 7.0
public static String getIOTemplateType()
{ return "-DEFAULT"; } // Template type - Host Default
public static String getIOVersionInfo()
{ return "(IBM)"; } // Version info - IBM supplied
public static String getIOTemplateRevision()
{ return ":1.1"; } // Template revision per version - internal value
public String hPubIOVersion= getIOBaseVersion()+";"+getHPubBeanType()+
getIOTemplateType()+getIOTemplateVersion()+
getIOTemplateRevision()+getIOVersionInfo();
public String getIOVersion() { return hPubIOVersion; }
// Generated Objects altered to export their data as
//HAO_VARIABLE_ARRAY instead of HAO_VARIABLE_SIMPLE
HAOVariable inquiry1 =
new HAOVariable("","inquiry1","inquiry1",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
HAOVariable inquiry2 =
new HAOVariable("","inquiry2","inquiry2",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
HAOVariable inquiry3 =
new HAOVariable("","inquiry3","inquiry3",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
HAOVariable inquiry4 =
new HAOVariable("","inquiry4","inquiry4",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
HAOVariable inquiry5 =
new HAOVariable("","inquiry5","inquiry5",false,"",0,0,63,7,HAO_VARIABLE_ARRAY);
****************************************************
******** Automatically Generated Code Not Shown ********
****************************************************
/* Added Getters to return the inquiries as a Vector */
public Vector getInquiry1AsVector()
{
return (inquiry1.oMultiValues);
}
public Vector getInquiry2AsVector()
{
return (inquiry2.oMultiValues);
}
public Vector getInquiry3AsVector()
{
return (inquiry3.oMultiValues);
}
public Vector getInquiry4AsVector()
{
return (inquiry4.oMultiValues);
}
public Vector getInquiry5AsVector()
{
return (inquiry5.oMultiValues);
}
|
清单 A-2. 创建 Atom 提要的 JSP(InquiryMacroOutput.jsp)的代码
<%@ page contentType="text/html;charset=UTF-8"errorPage="../BasicIOErrorPage.jsp"%>
<%@ page import="com.ibm.hats.runtime.*,
javax.xml.parsers.DocumentBuilder,
javax.xml.parsers.DocumentBuilderFactory,
javax.xml.transform.OutputKeys,
javax.xml.transform.Transformer,
javax.xml.transform.TransformerFactory,
javax.xml.transform.dom.DOMSource,
javax.xml.transform.stream.StreamResult,
org.w3c.dom.Document,org.w3c.dom.Element,
org.w3c.dom.Text,
java.io.StringWriter,
java.util.ArrayList,
java.util.Vector,
java.util.Date"%>
<%@ taglib uri="hats.tld" prefix="HATS"%>
<% IOGV.process(request); %>
<jsp:useBean id="InquiryMacro" type="IntegrationObject.InquiryMacro"
class="IntegrationObject.InquiryMacro" scope="request">
<jsp:setProperty name="InquiryMacro" property="*" />
</jsp:useBean>
<%
//Use the Integration Object that is instantiated above
//to get data from the 3270 machine.
InquiryMacro.doHPTransaction(request, response);
try {
// Build the feed to return from the page here.
// A well-formed Atom Feed should contain the
// following: A root "feed" element with "title",
// "updated", "author" (containing "name" and "email"), and "id"
// Create new feed factory
DocumentBuilderFactory feedFactory = DocumentBuilderFactory.newInstance();
// Create a new feed builder from the feedFactory
DocumentBuilder feedBuilder = feedFactory.newDocumentBuilder();
// Create a new document from the feed builder
Document doc = feedBuilder.newDocument();
// Create the root "feed" Element for the Atom Feed
Element root = doc.createElementNS(
"http://www.w3.org/2005/Atom", "feed");
doc.appendChild(root);
// Create the "title" element for the Atom Feed
Element title = doc.createElement("title");
// Append the title to the root element
root.appendChild(title);
// Create a text node for the title element
Text titleText = doc.createTextNode("Sample Feed from HATS");
// Append the text to the title node
title.appendChild(titleText);
// Create the "updated" element for the root of the Atom Feed
Element updated = doc.createElement("updated");
root.appendChild(updated);
Text updateText = doc.createTextNode(new Date().toString());
updated.appendChild(updateText);
// Create the "author" element for the root of the Atom Feed
Element author = doc.createElement("author");
// Created the "name" element for under the author element
Element name = doc.createElement("name");
// Create the "email" element for under the author element
Element email = doc.createElement("email");
name.setTextContent("IBM Hats");
email.setTextContent("ibm@us.ibm.com");
// Append the name and email to the author
author.appendChild(name);
author.appendChild(email);
// Append the author element to the root
root.appendChild(author);
// Create the "id" element for the root of the Atom Feed
Element id = doc.createElement("id");
id.setTextContent("http://www.ibm.com/root");
root.appendChild(id);
// Add all of the inquiries to an array to loop through
// and construct the body of the Atom Feed
ArrayList inqueries = new ArrayList();
inqueries.add(InquiryMacro.getInquiry1AsVector());
inqueries.add(InquiryMacro.getInquiry2AsVector());
inqueries.add(InquiryMacro.getInquiry3AsVector());
inqueries.add(InquiryMacro.getInquiry4AsVector());
inqueries.add(InquiryMacro.getInquiry5AsVector());
// Create multiple "entry" elements from the inquiries
// and add them to the root "feed"
// A well-formed entry element should contain title,
// link, id, updated, and content
for (int i = 0; i < 5; i++) {
// Get the vector of strings from the array JSP can't
// have parameterized types so it must be generic
Vector inquiry = (Vector) inqueries.get(i);
// Create the top element for the new Entry
Element entry = doc.createElement("entry");
// Append the entry to the root "feed" element
root.appendChild(entry);
//Create and append the title element to the Entry
Element titleEntry = doc.createElement("title");
titleEntry.setTextContent("Entry #" + i);
entry.appendChild(titleEntry);
//Create and append the link element to the Entry
Element link = doc.createElement("link");
link.setAttribute("href", "http://www.ibm.com");
entry.appendChild(link);
//Create and append the id element to the Entry
id = doc.createElement("id");
id.setTextContent("http://www.ibm.com/id" + i);
entry.appendChild(id);
//Create and append the updated element to the Entry
Element updatedEntry = doc.createElement("updated");
entry.appendChild(updatedEntry);
Text updateEntryText = doc.createTextNode(new Date()
.toString());
updatedEntry.appendChild(updateEntryText);
Element summaryEntry = doc.createElement("content");
//******* If you plan on having html content here, you should set
//******* the type attribute to html so it will display correctly
//******* by uncommenting the following lines
//summaryEntry.setAttribute("type", "html");
//summaryEntry.setAttribute("mode", "escaped");
// Create and append any data nodes from your inquiry to
// the content node of the entry
Element record = doc.createElement("Number");
record.setTextContent(inquiry.get(0).toString().trim());
summaryEntry.appendChild(record);
Element uname = doc.createElement("Name");
uname.setTextContent(inquiry.get(1).toString().trim());
summaryEntry.appendChild(uname);
Element address = doc.createElement("Address");
address.setTextContent(inquiry.get(2).toString().trim());
summaryEntry.appendChild(address);
Element phone = doc.createElement("Phone");
phone.setTextContent(inquiry.get(3).toString().trim());
summaryEntry.appendChild(phone);
Element date = doc.createElement("Date");
date.setTextContent(inquiry.get(4).toString().trim());
summaryEntry.appendChild(date);
Element amount = doc.createElement("Amount");
amount.setTextContent(inquiry.get(5).toString().trim());
summaryEntry.appendChild(amount);
Element comment = doc.createElement("Comment");
comment.setTextContent(inquiry.get(6).toString().trim());
summaryEntry.appendChild(comment);
// Append the content element to the entry element
entry.appendChild(summaryEntry);
}
// The following block transforms the Feed into a consumable
// string for the out.print
TransformerFactory
feedTransformerFactory = TransformerFactory.newInstance();
Transformer feedTransformer = feedTransformerFactory.newTransformer();
feedTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
feedTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
feedTransformer.transform(source, result);
//Print out the constructed feed xml as the content of the page
out.print(sw.toString());
} catch (Exception e) {
System.out.println(e);
}
%>
|
参考资料 学习
获得产品和技术
讨论
作者简介  | |  | John Feller 是 IBM Emerging Technologies Toolkit Development 开发团队的经理。他管理一个充满活力和创造力的开发团队,他们为新兴的 Internet 软件技术构建、设计和开发新的解决方案,然后发布到 alphaWorks。目前,他致力于使用 Web 2.0 技术(比如 wiki、博客、标记和 Ajax 用户界面)构建在线社区。他分别从 University of Dayton 和 Ohio State University 获得计算机科学的学士和硕士学位。他从 University of North Carolina, Chapel Hill 获得 MBA 学位,并且通过 Project Management Institute 的 Project Manager Professional 认证。 |
 | |  | Chris Gladd 是 Pennsylvania State University 的学生,他的专业是计算机科学。目前,他参与 IBM jStart Emerging Technologies 团队的工作,并且拥有超过 3 年的软件开发经验。 |
对本文的评价
|  |