Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29318596
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Java

2010-06-06 22:39:27

XML (eXtensible Markup Language) 是 W3C 定义的一种用以描述结构化数据的元语言 (Meta Language)。由于 XML 的目标就是为了促进 Internet 中结构化文档的交换,因此其被设计为与具体编程语言、操作系统或传输协议无关的纯数据描述。正是由于 XML 的数据独立性,它的出现给分布式计算领域 (distributed computing) 带来了重大影响,并在 SOA(Service Oriented Architecture)和 Web 应用中得到了非常广泛的应用。

然而,在实际 SOA 应用的设计和开发中,考虑到组成系统的各个功能模块的异构性 (heterogeneity),例如:模块开发时间(新近开发 v.s 遗留系统),核心功能(Web Portal v.s 数据库),设计目标(性能 v.s 复用性)等等因素,不同的模块可能会使用除 XML 以外的不同数据描述和存储格式,这就需要开发人员在 XML 和 non-XML 格式之间进行数据转换。例如,许多商业系统采用 EDI(Electronic Data Interchange)标准进行数据交换,如果希望在 SOA 应用中整合此类现有系统,就需要完成 XML 和 EDI 格式之间的数据转换。与此类似,在网上购物系统的开发中,与用户交互的前端往往会使用 XML 存储用户或者商品的数据,而后端则需要对这些数据对象 (Object) 进行处理,诸如存储至数据库或者插入处理队列(如购物车)等操作,便捷和高效的 XML 到 Java 对象转换在这样的场合就能发挥巨大作用。

实际上,针对 XML 到 non-XML 格式的数据转换,当前已有一些工具,然而却或多或少在易用性或是功能全面性上不尽如人意。例如,XSLT(XSL Transformation) 可以帮助我们转换 XML 数据到 HTML 网页。但是,XSLT 并没有解决上面所提到的传统数据 ( 如 EDI,CSV) 与 XML 数据的互相转换;同时,编写 XSL 的转换模板,如果不是十分精通 XSLT 语法,往往需要耗费大量时间查阅手册。因此,一个设计良好、易于使用的 XML 到 non-XML 数据转换框架和引擎,就成为 SOA 应用开发中的重要工具。本文要介绍的 Smooks 就是这样一款拥有强大功能的 XML 和 non-XML 数据转换引擎。


Smooks 是一款基于 LGPL 协议的开源 Java 框架,主要用于处理 XML 与 non-XML 格式 ( 包括 CSV,EDI,Java) 之间的转换。Smooks 于 2008 年 5 月发布 v1.0,目前最新的版本已是 v1.3.1。正如 Smooks 开发人员所言,“Smooks …让操作 XML, EDI,XML,CSV 变得更简单”。

实际上,我们通常将 Smooks 看做是一个 XML 到 non-XML 格式的“数据转换引擎”,然而在 Smooks 的核心实现中,本质上是为 XML, CSV, EDI 和 Java 等数据源提供了一个事件流(Event Stream),对数据源的处理其实可以看做是针对此输入数据流的一个个逻辑事件处理。因此,Smooks 的核心其实是一个“结构化数据事件流处理器”。在这样的设计中,开发人员可以用以下两种模式使用 Smooks:

  • 开发人员可以编写自己的逻辑事件处理器,用于定制化处理一个数据源事件流中的特定事件;
  • 开发人员也可以直接使用 Smooks 发行版中提供的解决方案(out-of-box solutions )。在这种模式下,开发人员只需重用别人创建的组件并重新配置它们来对数据源进行处理。例如,通过使用 Smooks 提供的组件便可完成从 XML 到 Java 对象的转换(正如本文下面将会展示的一样)

因此,在开始使用 Smooks 之前,让我们先了解一下 Smooks 发行版中已经提供了哪些数据转换功能。在 Smooks 的发行版中,主要包含了 4 大类也已实现的 XML 和 non-XML 数据转换组件 ,分别为:

Java 绑定 (Java binding)

Smooks 支持从多种数据源生成 Java 对象,包括从 CSV, EDI, XML 或 Java 等(如图 1 所示)。生成的 Java 对象既可以作为数据转换的结果进行使用,也可以成为另一个数据转的输入。



图 1. Smooks Java 绑定

数据格式转换(Transformation )

Smooks 支持多种数据格式之间的转换,包括:XML > XML, CSV > XML, EDI > XML, XML > EDI, XML > CSV, Java > XML, Java > EDI, Java > CSV, Java > Java, XML > Java, EDI > Java 等(图 2 )。



图 2. Smooks 数据转换

海量数据处理(Huge Message Processing )

Smooks 能够支持对海量数据(GB 量级)的处理,例如拆分 (Split),转换 (Transform) 海量数据至数据分片 (message fragment) 以及路由 (Route) 这些数据分片至文件,数据库或者 JMS(Java Message Service)。



图 3. Smooks 海量数据处理

数据信息补充(Message Enrichment )

Smooks 可以利用数据库或者其他数据源,添加额外的信息至输入的数据中。例如在网络购物应用中可以将用户的偏好(preference)从数据库中添加到用户订单中,以便为后续业务流程提供更多信息。



图 4. Smooks 数据信息补充

在 提供了如此丰富的 XML 和 non-XML 数据转换功能的同时,Smooks 同时还提供了 Eclipse Smooks 插件以方便开发人员在 Eclipse 集成开发环境中开发和测试基于 Smooks 的数据转换应用 [7]。接下来,本文将以 Java 绑定 为例,结合 Smooks Eclipse 插件,较为详细的介绍如何在 Eclipse 中轻松完成设计、配置和测试基于 Smooks 的 XML 到 Java 对象的数据转换。


正 如上文所提到的,Smooks 能够支持从多种源数据格式生成 Java 对象。然而,考虑到 JiBX 也能够完成从 XML 生成 Java 对象 [8],那么开发人员为什么要选择 Smooks 来完成类似任务呢?让我们选择 Smooks 的理由包括(或者说在下述这些场合 Smooks 更加适用):

  • Smooks 支持从 XML 和 non-XML 格式(如 EDI ,CSV 或 JSON )生成 Java 对象(甚至混合 XML 和 non-XML 源);而 JiBX 只支持从 XML 产生 Java 对象;
  • 当源数据仅有 XML 格式的数据,而缺少 XML Schema 的时候,Smooks 仍然能够完成从 XML 数据生成 Java 对象;而 JiBX 并不支持这个场景;
  • 由于 Smooks 不依赖于 Schema 文件,因此在数据源 XML 格式变化的情况下,Smooks 只需相应的修改从 XML 到 Java 对象的映射配置即可;而其他类似依赖于 Schema 的工具需要重新从 Schema 生成 Java 对象,重新编译并部署;
  • 如上文提到,Smooks 支持用户自定义逻辑事件处理器以达到在从 XML 生成 Java 对象的过程中加入定制处理的目的,从而具有良好的课扩展性(Extensibility );JiBX 并不支持类似的功能

如果所开发的项目符合上面的描述,那么选择 Smooks 来完成 Java 绑定,正如本文下面即将介绍的一样,将会是一次轻松和高效的开发体验。

本 文接下来将利用一个简单的例子说明如何使用 Eclipse Smooks 插件的图形化界面轻松完成 XML to Java 绑定。读者在了解了 Smooks Eclipse 插件的使用方法之后,可以利用类似的方法完成 Smooks 所支持的其他数据转换功能。


在 本文中,我们使用一个简单的网上购物系统的场景来说明如何使用 Smooks Eclipse 插件进行 Java 绑定 的开发。假设此网上购物系统的前端将用户的订单都按照清单 1 中的 XML 格式进行存储,然后传给后台处理模块。我们希望使用 Smooks 来完成从此 XML 文件生成相应的 Java 对象以便进行后续的处理。



				
"1.0"encoding="ISO-8859-1"?>



Wed Nov 15 13:45:28 EST 2006
"123123">Joe



111
2
8.90


222
7
5.20




Smooks 发布版本可以从 下载。笔者使用的是最新版本 v1.3.1,选择页面中“All”进入下载页面。下载完成之后将 Smooks 发布版 lib 目录中的所有 jar 包拷贝至所使用的 Eclipse 的 plugin 目录。

在 下载了 Smooks 发布版之后,接下来需要在 Eclipse 中安装 Smooks 开发插件。点击 Eclipse 中的 Help > Install New Software …,在出现的页面中点击“Add”,添加一个新的 update site,地址为 。在接下来显示的此 update site 可供选择安装的插件中,选中 Data Services > Smooks Tools,单击 Next 开始安装插件。



图 5. 安装 Smooks Eclipse 插件

安装完成之后重启 Eclipse,单击 File > New,如果出现如下图中所示的 Smooks 配置文件 Wizard,则说明 Smooks Eclipse 插件安装成功。



图 6. 新建 Smooks 配置文件 Wizard

由于到目前为止,我们仅有作为源数据的 XML 文件,因此在开始配置 Smooks 完成 XML 到 Java 的绑定之前,还需要开发目标 Java 类用以承载数据。

从本示例的 XML 文件中可以很容易的看出,我们需要创建 3 个类以对应 XML:



				
public class Header {
// member variables
private String date;
private String customerNumber;
private String customerName;

// constructors
public Header() {
date = null;
customerNumber = null;
customerName = null;
}

public Header(String dateInput, String customerNumberInput,
String customerNameInput) {
date = dateInput;
customerNumber = customerNumberInput;
customerName = customerNameInput;
}

// get/set functions
public String getDate() {

}





				
public class OrderItem {
// member variables
private String productId;
private String quantity;
private String price;

// constructors
public OrderItem() {
productId = null;
quantity = null;
price = null;
}

public OrderItem(String productIdInput, String quantityInput, String priceInput) {
productId = productIdInput;
quantity = quantityInput;
price = priceInput;
}

// get/set functions
public String getProductId() {

}




				
public class Order {
public Header header;

public Vector orderItems;

public Order() {
header = new Header();

orderItems = new Vector ();
}

public void setHeader(Header headerInput){
header = headerInput;
}

public void setOrderItems(OrderItem item){
orderItems.add(item);
}
}

在有了 XML 文件作为源数据,并开发了相应 Java 类承载数据之后,我们就可以开始配置 Smooks 来完成 XML 到 Java 对象的映射。

首 先,在 Eclipse 中新建一个 Java 项目:File > New > Java > Java Project,然后将上文中开发的 Java 类源文件拷贝到此新建 Java 项目的 src 文件夹中;同时,新建一个文件夹 xml 并将作为源数据的 XML 文件拷贝至其中。然后新建一个 Smooks 配置文件:File > New > Smooks > Smooks Configuration File,选择刚才创建的 Java Project 的 src 文件夹作为 Smooks 配置文件的父目录,保留缺省的文件名 smooks-config.xml,单击 Finish 生成初始的配置文件。此时在 Smooks Processing 编辑器中只有一个 Input Task 图标。

单击 Input Task 图标,则可以看到 Smooks input reader 的属性配置界面。由于我们希望完成从 XML 到 Java 的绑定,因此在 Input Type 的下拉菜单中选择“Input Type”为 XML。接下来,在配置界面右侧的 Input Data 中单击 Add 将源 XML 文件添加到项目中(图 7)。Smooks 会自动解析此 XML 文件并在 Input Model View 中列出其数据模型。完成上述这些数据源导入的设置之后,Smooks 配置文件应该如下面图 7 所示。



图 7. 设置 Smooks 配置文件

在完成了源数据导入之后,我们要开始配置 Java 绑定。将鼠标移至 Input Task 的蓝色箭头右侧,将会有一个绿色加号(+)出现,单击此加号并选择出现的提示“Java 映射”(图 8)。



图 8. 选择 Java 映射

此时配置界面下方的 Selected Task Details 中将会出现作为源数据的 XML 文件的数据模型,我们接下来需要做的是将目标 Java 类导入并设置二者之间的映射关系。

为 了将开发的 Java 类导入 Smooks 配置,在 Selected Task Details 配置框中空白处单击鼠标右键,选择 Add > Java Class,将上文中开发的 Header,OrderItem 以及 Order 类导入。然后就可以非常方便的使用拖曳的方式在左边的 XML 数据模型和右边的 Java 类和成员变量之间建立映射关系,最后的结果如下图所示:



图 9. 建立 XML 和 Java 类之间的映射关系

在 完成了 Smooks 配置如何将 XML 文件转换为 Java 对象之后,我们可以十分方便的在 Java 代码中调用 Smooks 来测试上述转换。下面的清单 5 列出了示例代码。注意,为了运行 Smooks,还需要将 Smooks 发行版中的 jar 包添加到当前 Project 的 Build path 当中(右键单击 Project > Build Path > Configure Build Path … > Library > Add External JAR,选择下载的 Smooks 文件中 lib 目录下所有 jar 文件)。



				
public class TestSmooks {


public static void main(String[] args) throws IOException, SAXException {

// Instantiate Smooks with the config...
Smooks smooks = new Smooks("smooks-config.xml");
JavaResult javaResult = new JavaResult();

// Filter the input message to the JavaResult...
smooks.filter(new StreamSource(new FileInputStream("C:\\Order.xml")),
javaResult);

// Extract the Order bean from the JavaResult using the beanId...
OrderItem orderItem = (OrderItem) javaResult.getBean("OrderItem");

System.out.println("OrderItem.productId = " + orderItem.getProductId());
}

}


程序的运行输出为:

 OrderItem.productId = 111 

至此,我们就完成了使用 Smooks Eclipse 插件进行 XML 到 Java 对象的数据转换的配置和测试。


Smooks 是一个基于 LGPL 协议的开源 Java 数据转换框架,它在数据转换方便拥有强大的功能,能够完成包括 Java 绑定,数据格式转换,海量数据处理,数据信息补充等多种 XML 和 non-XML 数据之间的转换。

配 合 Eclipse Smooks 插件,开发人员可以非常方便的利用图形化界面完成 Smooks 数据转换的配置。本文利用示例展示了如何利用 Smooks Eclipse 插件完成 XML 到 Java 对象的数据转换并在 Java 代码调用此 Smooks 数据转换。开发人员可以利用类似的方法完成 Smooks 所支持的其他类型的数据转换。

阅读(1497) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~