成都心情

  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理 ::
  98 随笔 :: 2 文章 :: 501 评论 :: 1 Trackbacks
译者语
(在下次的与db4o 结合时,再也不需要 XStream 了:),现在我们一起享受没有 xml 的 OpenLaszlo 吧!)

OpenLaszlo 是一个允许你在包括 Flash 和 DHTML 在内的多个运行时平台构建丰富因特网应用程序(rich internet applications,RIA)的开发平台。你可以利用基于 XML 的 LZX 语言来声明构建用户界面并利用 ECMAScript 实现应用程序的动态部分。这和传统的 HTML+JavaScript 的配合非常类似。


接收非 XML 数据

OpenLaszlo 通常希望你提供的数据是 XML 格式或符合 XML 特性的数据,比如 UI data-binding 组件就依赖这种格式。但是,有某些情况你可能更愿意采用其他数据格式。例如 JSON,作为一种数据交换格式它已经越来越在 Ajax 应用程序中流行了。也许你正在期待 OpenLaszlo 能使用已存在的或是你自己写的基于 JSON 的服务。

从 OpenLaszlo 3.1 发布开始,可以通过 XMLHttpRequest 类完成数据请求而不必一定是 XML 格式。在使用 XMLHttpRequest 类之前你应该把以下内容引入到 OpenLaszlo 应用程序的 canvas 中。

<include href="rpc/ajax.lzx"/>

该类的行为看上去很像经典的 DHTML Ajax 应用程序,比如:

function doXhrRequest() {
  
var url = "http:/yourservice"// the single slash is mandatory in OpenLaszlo
  var req = new XMLHttpRequest();
  req.onreadystatechange 
= processRequestChange;
  req.open(
"GET", url, true);
  req.send(
null);
}

先构建一个新的 XMLHttpRequest 实例,注册回调函数然后执行请求流程,通过实际的 URL 打开请求然后发送到服务器。

回调函数的实现有点像你曾经经历过的 Ajax 应用程序:

function processRequestChange(request) {
  
// check if the data transfer is complete
  if (4 == request.readyState) {
    
// process the reponse text if the request was successful
    if (200 == request.status) {
      
var text = request.responseText;

      
//  use the text 
    }
  }
}


它用这种方式帮助你处理接收到的文本数据来为应用程序服务。


采用 JSON

接下来的文章将利用 Java 构建一个非常简单的 JSON 服务,并在 OpenLaszlo 客户端使用并异步显示。

利用 Java 构建 JSON

我尽量避开服务器端 Java 技术的争论,并假设你选择的框架可以输出“text/plain” mime-type 文本数据。

数据是我们将要显示的“Person”bean:

public class Person {
  private String name;
  private 
int age;

  public 
void setName(String name) { this.name = name; }
  public String getName() { 
return name; }
  public 
void setAge(int age) { this.age = age; }
  public 
int getAge() { return age;}
}

我们将创建 person 实例并为它生成 JSON 数据。有很多 Java 库可以完成这个工作,但现在我选择的是 SOJO(Simplify Old Java Objects),这是因为它的设置和使用都非常简单。

下面是用 Java 写的服务器端 JSON 服务代码:

Person person = new Person();
person.setName(
"Geert Bevin");
person.setAge(
32);

Object json 
= new JsonSerializer().serialize(person);
// output the json data as a string response

在 OpenLaszlo 中解析 JSON

OpenLaszlo 没有解析 JSON 的能力,但是幸运的是 Oliver Steele 开发了一个库来实现。你可以从他的个人站点获取。下载并解压缩后,把 json.js 文件放在你的 web 目录并把下面的代码添加进 OpenLaszlo canvas 以激活对 JSON 的支持:

<script src="json.js"/>

现在你可以解析从 XMLHttpRequest 收到的文本数据了,再进行简单的函数调用就可以得到从服务器端来的 JSON 对象结构。添加下面这行代码到上面我们创建的 processRequestChange 函数:

var result = JSON.parse(text);

“result”变量是一个包含了你获取到的 person bean 属性值的数组:

var person_name = result.name;
var person_age = result.age;


与 GUI 结合

要包裹上面的数据,我要构建一个简单的含有按钮的 OpenLaszlo 界面来触发 JSON 服务请求。当按钮被点击,两个 text 文本字段将显示接收到的数据。

构建控制器和界面

添加如下 LZX 代码片段到你的 canvas 标签:

<hbox inset="10">
  
<vbox id="mainArea" inset="10" spacing="10">
    
<button onclick="doXhrRequest()">Get data</button>

    
<hbox name="personName">
      
<text><b>Name:</b></text> <text name="value"/>
    
</hbox>

    
<hbox name="personAge">
      
<text><b>Age:</b></text> <text name="value"/>
    
</hbox>
  
</vbox>
</hbox>

         
你会发现当按钮点击后,我们在本文开头创建的 doXhrRequest 函数就被执行了。

要在 text 文本字段显示 processRequestChange 函数解析 JSON 后返回的数据,我们只要简单的改变对应的界面元素 text 属性即可:

mainArea.personName.value.setAttribute("text", person_name);
mainArea.personAge.value.setAttribute(
"text", person_age);

优雅的处理网络延迟

既然是以异步方式处理请求,那么在点击按钮后数据到达还需要些时间,这是网络延迟导致的。这让用户感到沮丧,并给应用程序留下缓慢和迟钝的印象。一个良好的方式是当请求不能立即完成时显示繁忙状态指示标识。在本例中,如果数据返回超过 200 毫秒,那么就漂浮一个较透明的玻璃窗口(glass pane)在界面上,写上“Loading...”提示。下面的 LZX 片段创建了该玻璃窗口:

<view name="loadingMessage" visible="false" bgcolor="#000000"
          opacity
="0.7" width="100%" height="100%">
  
<text align="center" valign="middle" fgcolor="#ffffff">Loading</text>
</view>

          
在 canvas 标签关闭之前插入这段代码,这样就可以悬浮在任何 GUI 元素之上了。注意在默认时 'visible' 属性被设置为 false。当要显示玻璃窗口时可以改变该属性值实现。

那么,一旦请求发起,我们要初始化一个记时器来实现在 200 毫秒后玻璃窗口的显示。这个工作可以借由 XMLHttpRequest 类的 readyState 属性值实现,请参考类文档详细了解。根据我们的用例,需要检查该属性值是否为 1,以确认请求是否发起。这些条件判断加在 processRequestChange 函数的开头:

// the request has been started
if (1 == request.readyState) {
  
// create the delegate if is doesn't exist yet
  if ("undefined" == typeof(canvas.loadingMsgDel) ||
    
!canvas.loadingMsgDel) {
    canvas.loadingMsgDel 
= new LzDelegate(canvas, "showLoadingMessage");
  }
  
// intiate or reuse a timer
  LzTimer.resetTimer(canvas.loadingMsgDel, 200);
}

代码使用了委派类(LzDelegate),主要是为了把事件绑定到方法。该事件用来判定是否启动定时器,接着 showLoadingMessage 方法将在 200 毫秒后被 canvas 实例调用。实现该方法很简单,下面看到的代码片段要在 canvas 标签中添加:

<method name="showLoadingMessage">
  this.loadingMessage.setAttribute("visible", true);
</method>

上面的代码把加载消息(玻璃窗口)设置为可视。

最后,当数据返回或请求时间小于 200 毫秒时中断定时器并隐藏该消息。要实现这样的操作只需要添加两行代码到 processRequestChange 函数的初始化条件中:

  
  
if (4 == request.readyState) {

    
// disable a pending loading message or hide it if it's showing already
    LzTimer.removeTimer(canvas.loadingMsgDel);
    canvas.loadingMessage.setAttribute(
"visible"false);

    
// process the reponse text if the request was successful
    if (200 == request.status) {
      

         

结论

利用 OpenLaszlo 的 XMLHttpRequest 类和使用 JSON 服务处理任意文本数据是很简单的。当然,我的还很简陋并且没有用到数据绑定组件。在 OpenLaszlo 4.0(2007 第一季度发布)发布之后,数据集组件抽象程度更高了,统一了与结构化数据的交互方式。即便那样,你只需直接更新需要的可视化元素即可。


资源

OpenLaszlo 项目网站:http://www.openlaszlo.org
OpenLaszlo 4.0 结构:http://www.openlaszlo.org/legals
OpenLaszlo 软件工程师指南:http://www.openlaszlo.org/lps/docs/guide
JSON 格式:http://www.json.org
SOJO Java 库:http://sojo.sourceforge.net
JSON for OpenLaszlo:http://osteele.com/sources/openlaszlo/json
源文件:在这里下载

请注意!引用、转贴本文应注明原译者:Rosen Jiang 以及出处:http://www.blogjava.net/rosen

posted on 2007-04-07 20:54 Rosen 阅读(2606) 评论(1)  编辑  收藏 所属分类: Java EE 表现层及容器

评论

# re: 切断 OpenLaszlo 与 XML 数据间的耦合(翻译) 2007-09-08 12:06 top
JSON还行,正在试用。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: