Breaking OpenLaszlo loose from XML data
OpenLaszlo is a development platform that allows you to create rich internet applications which execute on several runtimes, including Flash and DHTML. You use an XML-based language, called LZX, to declaratively create the user interface and rely on EcmaScript to implement dynamic portions of the application.
OpenLaszlo is a development platform that allows you to create rich internet applications which execute on several runtimes, including Flash and DHTML. You use an XML-based language, called LZX, to declaratively create the user interface and rely on EcmaScript to implement dynamic portions of the application. This is very similar to the traditional HTML and JavaScript duo.



Download now: Java EE moves to the Eclipse Foundation
What are application developers and market analysts saying about Oracles decision to move Java EE to the Eclipse Foundation? What will this change? Find out here.
By submitting your personal information, you agree that TechTarget and its partners may contact you regarding relevant content, products and special offers.
You also agree that your personal information may be transferred and processed in the United States, and that you have read and agree to the Terms of Use and the Privacy Policy.
Receiving non-XML data
OpenLaszlo usually expects your data to be provided in XML and many of its features, like UI data-binding, rely on this. However, there are situations where you would like to work with other data formats. JSON, for example, is increasingly being used as the data-interchange format for Ajax applications. You might want to consume an existing JSON-based service in OpenLaszlo or write your own.
Since the 3.1 release of OpenLaszlo, it's possible to perform data requests whose results aren't parsed as XML by using their XMLHttpRequest
class. Before being able to use the XMLHttpRequest
class you have to add the following include to the canvas of your OpenLaszlo application:
<include href="rpc/ajax.lzx"/>
The class behaves exactly as in classic DHTML Ajax applications, for example:
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); }
This creates a new instance of XMLHttpRequest
, registers the call-back function that will be executed as the request progresses, opens the request for a particular URL and sends it to the server.
The implementation of the call-back function is analogue to what you do in any other Ajax application:
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 ... } } }
It's up to you to handle the received text in the manner that is best suited for your application.
Working with JSON
The rest of this article will create a very simple JSON service in Java and an OpenLaszlo client that consumes and displays it asynchronously.
Producing JSON with Java
I'm staying away from the server-side Java technology debate and assume that your framework of choice is able to output text with the text/plain
mime-type.
The data that we'll be displaying is held by simple 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;} }
We will create a person instance and generate the JSON data for it. There are several Java libraries that are able to perform this task, but currently my choice goes to SOJO (Simplify Old Java Objects) because it's extremely simple to setup and use.
This is the code for the server-side JSON service in Java:
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
Parsing JSON in OpenLaszlo
OpenLaszlo doesn't ship with JSON capabilities, but luckily Oliver Steele wrote a library that does just this. You can obtain it from his personal website. Once downloaded and unzipped, you have to put the json.js
file in your web directory and activate JSON capabilities by adding this tag to your OpenLaszlo canvas:
<script src="json.js"/>
Now you can parse the text that you received from the XMLHttpRequest
with a simple function call and obtain an object structure that corresponds to the JSON that was sent by the server. This is done by adding the following line inside the processRequestChange
function that we created above:
var result = JSON.parse(text);
The result
variable is an associative array and you can obtain the values of the person bean properties like this:
var person_name = result.name; var person_age = result.age;
Hooking this up to a GUI
To wrap this article up, we'll create a simple OpenLaszlo interface with a button that triggers the JSON service request when clicked and a couple of text fields that will display the received data.
Creating the controller and view
This can be declared by using the following snippet of LZX code inside your canvas
tag:
<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>
You'll notice that when the button is clicked, the doXhrRequest
function, which we created at the beginning of this article, is executed.
To display the received data in the text fields, we simple have to change the text attributes of the correct view elements after we parsed the JSON in the processRequestChange
function:
mainArea.personName.value.setAttribute("text", person_name); mainArea.personAge.value.setAttribute("text", person_age);
Handling network latency graciously
Since the request will be executed asynchronously, it can take a while for the data to arrive after clicking the button, due to network latency. This can be frustrating for the user and give the impression that the application is slow or unresponsive. A good approach is to display a busy status indicator when the request doesn't finish instantly. In this example I'm going to overlay a slightly transparent glass pane that contains the message "Loading..."
when the data takes longer that 200 milliseconds to arrive. The following LZX snippet creates the glass-pane:
<view name="loadingMessage" visible="false" bgcolor="#000000" opacity="0.7" width="100%" height="100%"> <text align="center" valign="middle" fgcolor="#ffffff">Loading...</text> </view>
By placing this code before the canvas closing tag, it will float above any other GUI element. Note that the 'visible
' attribute has been set to false
by default. We'll change that value when we want the glass pane to display.
So, as soon as the request starts, we initiate a timer that displays the glass-pane after 200 milliseconds. This can be done by relying on another value of the readyState
attribute of the XMLHttpRequest
class. You can refer to the class documentation for a complete overview of the possible values. For our use-case, we need to check if the attribute value is equal to 1
, which means that the request has started. This additional condition is added to the beginning of the processRequestChange
function:
// 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); }
This code uses a delegate, which basically ties an event to a method. The event in question is the expiration of the timer. Here, the showLoadingMessage
method will be called on the canvas instance after 200 milliseconds. The implementation of this method is easy, as you can see in the following snippet that should be added inside your canvas
tag:
<method name="showLoadingMessage"> this.loadingMessage.setAttribute("visible", true); </method>
It simply makes the loading message visible.
Finally, we need to hide this message again when the data arrives or interrupt the timer if the request took less than 200 milliseconds. This is done by adding two lines to the initial condition inside the processRequestChange
function:
... 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) { ...
Conclusion
It's easy to process arbitrary text with the OpenLaszlo XMLHttpRequest
class and even consume JSON services. Currently this is still primitive since it doesn't tie into the data-binding infrastructure. After the release of OpenLaszlo 4.0 (which should happen in Q1 2007), the dataset infrastructure should be better abstracted, creating a uniform approach to interacting with structured data. Until then you're still able to explicitly update the view elements that you need.
Resources
- The OpenLaszlo project website : http://www.openlaszlo.org
- The OpenLaszlo 4.0 architecture : http://www.openlaszlo.org/legals
- OpenLaszlo Software Engineer's Guide : http://www.openlaszlo.org/lps/docs/guide/
- JSON format : http://www.json.org
- SOJO Java library : http://sojo.sourceforge.net
- JSON for OpenLaszlo : http://osteele.com/sources/openlaszlo/json
- Source Files : Download Here
Start the conversation
0 comments