Combining the power of WebSphere sMash and Adobe Flex
Today, a multitude of information tasks - from obtaining a regional weather forecast to sharing video files with five hundred of your closest friends - is solved using Web 2.0 applications. In response to the growing use of Web 2.0 technologies, IBM has released WebSphere sMash, a framework for developing and executing applications based on such basic concepts as dynamic development, simplicity, and RESTful interfaces. In most WebSphere sMash applications, user interfaces are implemented using Ajax, HTML, or the Dojo Toolkit.
In this post, using an example of a simple "training" application, we show how to implement Web 2.0 user interface support written in Adobe Flex. Server implementations are provided in two languages - Groovy and PHP. You can also download the “training” file and ask your questions to IBM representatives.
Introduction
The term Web 2.0 is often used in a too broad sense. This term is probably best defined as an architectural style based on the use of “fast” application programming interfaces, such as REST (REpresentational State Transfer) for creating consumer applications.
As an architectural style, Web 2.0 does not dictate the need to use certain technologies either on the client side (browser) or on the server side. In fact, the most attractive feature of Web 2.0 applications is the clear separation of client and server technologies. This separation allows the developer to choose client and server technologies based on their relevance to the task being solved, without the need for a single solution for all occasions.
On the server side, the WebSphere sMash framework is particularly well-suited for professionals with experience in Java development who are focused on quickly getting results (usually associated with dynamic scripting languages). The WebSphere sMash environment supports PHP and Groovy (a dynamic scripting language with Java syntax), making it available to a wide range of developers.
Although WebSphere sMash does not require certain client technologies, WebSphere sMash applications are most often equipped with HTML / Ajax-based user interfaces, sometimes extended using the Dojo Toolkit. Although these technologies meet the requirements of many user interfaces, some applications require a higher degree of interactivity and a more developed framework. This is exactly the kind of framework that Adobe Flex v. 3, which is widely used to create the so-called RIA applications (Rich Internet Application).
In this post, some approaches to combining the capabilities of WebSphere sMash and Adobe Flex are examined using a simple WebSphere sMash application for which a visually appealing user interface is created using the Adobe Flex product. The specified application is intentionally made very simple, which allows you to more clearly demonstrate the technology of combining the capabilities of WebSphere sMash to Adobe Flex. According to the philosophy of WebSphere sMash, all communications between the browser and the server are based on RESTful interfaces and use standard data encoding. To demonstrate the flexible capabilities of WebSphere sMash and Adobe Flex, the article shows several varieties of a training application:
- WebSphere sMash application using the Groovy language or PHP.
- Data transfer between WebSphere sMash code and Adobe Flex code using XML or JSON format.
Using WebSphere sMash
WebSphere sMash, created as part of the Project Zero open incubation project, is based on three basic principles: simplicity, dynamism and speed. Thanks to these attributes, this powerful framework makes it easy to create applications that support reuse and do not require significant effort to adapt to changes. The WebSphere sMash environment is focused on dynamic development, so many companies that urgently need to create new applications use this environment today to quickly and easily develop stable applications. WebSphere sMash dependency management tools remove many of the barriers to deploying an application. This greatly simplifies the deployment of applications in various environments, eliminating the need to resolve classpath dependencies. Unlike many other application development environments, WebSphere sMash only includes the truly necessary modules, which significantly reduces the overall size of applications and ensures their quick initialization. Thus, WebSphere sMash is a truly excellent environment for dynamic development.
Web 2.0 and REST-style programming
By the term REST, many mistakenly mean the corresponding architecture; in this case, REST is rather the application programming interface on which the Web 2.0 architecture is based. REST interfaces represent the traditional list / create / read / update / delete operations using the standard HTTP methods GET, POST, PUT, and DELETE. Examples of the application of some of these methods are described in the following sections.
Web 2.0 technologies provide real advantages - they allow companies to present their internal services and data sources on the Internet in new formats that are easier to use for browser-type applications (for example, using the ATOM, JSON, RSS, RESTful interfaces). Companies such as Google and Amazon occupy a leading position in the field of Web 2.0 APIs, which allow developers to use existing functionality and create applications based on them, i.e. with minimal effort.
Appbuilder
AppBuilder is a tool for developing applications in WebSphere sMash (the zip file accompanying this article was packaged using AppBuilder). AppBuilder allows you to quickly build applications thanks to the following functions: built-in editor with syntax highlighting tools, the ability to start / stop the server, access to the execution log, and the ability to trace using the console. The AppBuilder tool is available for download on the Project Zero Web site .
Figure 1. Features of AppBuilder for syntax highlighting in the application editor
Figure 2. Runtime log tab in the file editor
Groovy and PHP
We want to focus on expanding the consumer capabilities of an existing application by building its front end in an Adobe Flex environment, so this article covers only certain aspects of the WebSphere sMash infrastructure.
One of the attributes of the WebSphere sMash environment is the ability to create an application very quickly, based on the use of powerful Groovy and PHP scripting languages.
Having appropriate built-in conventions WebSphere sMash greatly simplifies and streamlines the creation of a resource in an application. Any Groovy or PHP script placed in the WebSphere sMash application directory with the name app / resources is automatically represented as a RESTful resource:
Table 1. Scripts presented as RESTful resources
Additional information:Project Zero: Programming Model and Resource Agreement (REST) .
Our first task will be to create a server component for the to-do list application.
Creating a to-do service with Groovy
Groovy is a scripting language targeted at programmers who cannot do without Java. With easy integration with existing Java code and scripting capabilities, Groovy guarantees speed and ease of development.
To store a custom to-do list, use the app zone in the global context. The following methods are used for this:
- onList: creates a list of to-do elements.
- onCreate: creates a new item in the to-do list by adding the specified item.
- onRetrieve: puts the item in a list based on the index ID.
- onDelete: removes an item from the to-do list
In the original version, the application in question was created with the expectation of returning XML data. The code shown in this article is almost identical to the typical REST resource from the above article on the Project Zero Web site. The full WebSphere sMash source code for the fragments shown below is: CombiningThePowerOfWSWithAdobeFlex / src / TodoService-1.0.0 / TodoService / app / resources / todos_xml_grovy.groovy (see the Download section below).
Listing 1. OnList () event handler
def onList () {
logger.INFO {"onList (): called"}
def todos = app.todosXML []
if (todos == null) {
todos = []
}
else {
todos = todos.values ()
}
outputXML ( todos)
logger.INFO {"onList (): returning $ {todos}"}
}
Listing 2. onCreate () event handler
def onCreate () {
logger.INFO {"onCreate (): called"}
def item = request.params.item []
request.status = HttpURLConnection.HTTP_BAD_REQUEST
if (item! = null && item.length ()> 0) {
def todos = app.todosXML []
def index = app.index []
if (todos == null) {
todos = [:]
index = 0
}
index ++
todos.put (index, [id: index, value: item])
app.todosXML = todos
app.index = index
request.status = HttpURLConnection.HTTP_CREATED
request.headers.out.Location = request.uri [] + '/' + index
logger.INFO {"onCreate (): created id $ {index } -> $ {item} "}
}
}
Listing 3. OnRetrieve () event handler
def onRetrieve () {
logger.INFO {"onRetrieve (): called"}
def id = request.params.todos_xml_groovyId []
if (id! = null) {
def todos = app.todosXML []
def value = todos.get ( id.toInteger ())
if (value! = null) {
outputXML (value)
logger.INFO {"onRetrieve (): returning $ {value}"}
return
}
}
send404 ()
}
Listing 4. OnDelete () event handler
def onDelete () {
logger.INFO {"onDelete (): called"}
def id = request.params.todos_xml_groovyId []
if (id! = null) {
def todos = app.todosXML []
if (todos.remove (id .toInteger ())) {
app.todosXML = todos
logger.INFO {"onDelete (): deleted $ {id}"}
return
}
}
send404 ()
}
Listing 5. Response rendering in the outputXML method
def outputXML (data) {
logger.INFO {"converting $ {data} to XML"}
request.headers.out.'Content-Type '=' application / xml '
request.view =' XML '
request.xml.output = data
render ()
}
Creating a to-do service using PHP
PHP is a universal scripting language. The PHP implementation shown in this section is functionally equivalent to the Groovy implementation shown above. There are only a few syntactic differences between these two implementations. Depending on the complexity of the serializable objects, indirect rendering is handled by WebSphere sMash.
The full WebSphere sMash source code for the fragments shown below: CombiningThePowerOfWSWithAdobeFlex / src / TodoService-1.0.0 / TodoService / app / resources / todos_xml_php.php (see Download section below).
Listing 6. onList () method)
function onList () {
$ todos = zget ("/ app / todos_xml_php");
if ($ todos == null) {
$ todos = array ();
}
zput ('/ request / view', 'XML');
zput ('/ request / xml / output', array_slice ($ todos, 0));
zput ('/ request / xml / rootelement', 'arraylist');
render_view ();
}
Listing 7. onCreate () method
function onCreate () {
$ item = zget ("/ request / params / item");
zput ("/ request / status", 400);
if ($ item! = null && strlen ($ item)> 0) {
$ todos = zget ("/ app / todos_xml_php");
$ index = zget ("/ app / index");
if ($ todos == null) {
$ todos = array ();
$ index = 0;
}
$ index ++;
$ todos [$ index] = array ('id' => $ index, 'value' => $ item);
zput ("/ app / todos_xml_php", $ todos);
zput ("/ app / index", $ index);
zput ("/ request / status", 201);
$ uri = zget ("/ request / uri");
zput ("/ request / headers / out / Location", "$ uri / $ index");
Listing 8. onRetrieve () method
function onRetrieve () {
$ id = zget ("/ request / params / todos_xml_phpId");
if ($ id! = null) {
$ todos = zget ("/ app / todos_xml_php");
$ value = $ todos [$ id];
if ($ value! = null) {
zput ('/ request / view', 'XML');
zput ('/ request / xml / output', $ value);
render_view ();
return
}
}
// Error handling
zput ("/ request / status", 404);
echo "An error occurred while processing your request";
}
Listing 9. onDelete () method
function onDelete () {
$ id = zget ("/ request / params / todos_xml_phpId");
if ($ id! = null) {
$ todos = zget ("/ app / todos_xml_php");
unset ($ todos [$ id]);
zput ("/ app / todos_xml_php", $ todos);
return
}
// Error handling
zput ("/ request / status", 404);
echo "An error occurred while processing your request";
}
JSON format
In keeping with the nature of Web 2.0, the WebSphere sMash environment, in addition to XML, supports JSON (JavaScript ™ Object Notation) (for more information on JSON, see Resources). One of the significant advantages of the Groovy language is the simplicity of parsing when using XML and JSON formats, which saves the developer from a significant investment of time in writing the appropriate code.
The WebSphere sMash environment is capable of rendering an HTTP response using direct rendering through the API or indirect rendering. To create output in XML and JSON formats, this post uses only indirect rendering. In general, the renderer is called as follows:
1. Set the value / request / view in the global context of the Global Context of the corresponding renderer.
2. Specify additional values for this renderer in the GlobalContext global context, where necessary.
3. Call the renderer zero.core.views.ViewEngine.render ().
The above example uses only XML data. The next section describes how to implement JSON format output using minimal modification of the Groovy and PHP code.
The full WebSphere sMash sources for JSON output are: CombiningThePowerOfWSWithAdobeFlex / src / TodoService-1.0.0 / TodoService / app / resources / todos_json_groovy.groovy and CombiningThePowerOfWSWithAdobeFlex / src / Todoerpero_serfodsero_service_ TodoSero_service_ TodoService_ TodoService_ TodoService_ TodoService (see Download section below).
Listing 10. JSON output using Groovy
def outputJson (data) {
logger.INFO {"converting $ {data} to JSON"}
request.headers.out.'Content-Type '=' application / json '
request.view =' JSON '
request.json.output = data
render ()
}
Listing 11. JSON output using PHP
zput ('/ request / view', 'JSON');
zput ('/ request / json / output', $ todos);
render_view ();
Using Adobe Flex
Until now, we have described the construction of the server side of the application. Now we will consider the construction of the browser part of the application, which should interact with the server part created earlier using WebSphere sMash.
The Adobe Flex environment enables the creation of platform-independent RIA applications (Rich Internet Application) that can be uniformly deployed in all major browsers, desktop environments, and operating systems (see Resources). These RIA applications can be executed in browsers using the Adobe Flash player or in desktop environments using the Adobe Integrated Runtime (AIR) tool.
Full Adobe Flex source code for code snippets: CombiningThePowerOfWSWithAdobeFlex / src / todoJSON.mxml and CombiningThePowerOfWSWithAdobeFlex / src / todoXML.mxml (see Download).
Building an application in an Adobe Flex environment is as follows:
1. Retrieving data from a WebSphere sMash environment
Adobe Flex makes it easy to load external data using the HTTPService component (see Resources). This article shows two ways to make HTTP requests - for XML and for JSON, respectively. Adobe Flex has built-in XML support (that is, it uses ECMAScript for XML (e4x) technology for parsing data), so in this case, the developer has to write less code. To support serialization of JSON data in Adobe Flex, you must download the corelib library (see Resources). In the code example shown in Listing 12, an HTTPService component is created and made available to the application. This allows you to delete, retrieve, and create items in the to-do list using the XML data provided by WebSphere sMash.
Shown in Listing 12, the Adobe Flex MXML code makes extensive use of Adobe Flex binding mechanisms (variable names in braces) to dynamically replace resource names and identifiers when sending requests in real time. WebSphere sMash displays URLs specified in elements
Attributes of the result and errors provide the code to be executed if the conditions of “successful completion” or “error” occur, respectively. Automatic processing of data returned by calls to list and retrieve is provided by linking data anywhere in the MXML code. Updating the displayed data after the create and delete calls are completed is provided by initiating the next list call.
Listing 12. Creating an HTTPService component using XML
url = "/ resources / {resource}" method = "GET"
resultFormat = "e4x" />
url = "/ resources / {resource} / {idToRetrieve}" method = "GET"
resultFormat = "e4x"
result = "detailsBox.visible = true" />
url = "/ resources / {resource}" method = "POST"
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()">
{itemToAdd.text}
url = "/ resources / {resource} / {idToDelete}" method = "POST"
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()" />
resultFormat = "e4x" />
resultFormat = "e4x"
result = "detailsBox.visible = true" />
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()">
{itemToAdd.text}
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()" />
The JSON library provides similar functionality for parsing the JSON data provided by WebSphere sMash (Listing 13). The main difference between the JSON code and the XML code in Listing 12 is that the list and retrieve result handlers have explicit calls to decode the JSON data.
Listing 13. Creating an HTTPService component using JSON
url = "/ resources / {resource}" method = "GET"
resultFormat = "text"
result = "todoItems = JSON.decode (listTodosHS.lastResult as String);" />
url = "/ resources / {resource} / {idToRetrieve}" method = "GET"
resultFormat = "text"
result = "detailItem = JSON.decode (retrieveTodoHS.lastResult as String);
detailsBox.visible = true; "/>
url = "/ resources / {resource}" method = "POST"
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()">
{itemToAdd.text}
0 url = "/ resources / {resource} / {idToDelete}" method = "POST"
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()" />
resultFormat = "text"
result = "todoItems = JSON.decode (listTodosHS.lastResult as String);" />
resultFormat = "text"
result = "detailItem = JSON.decode (retrieveTodoHS.lastResult as String);
detailsBox.visible = true; "/>
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()">
{itemToAdd.text}
result = "listTodosHS.send ()"
fault = "listTodosHS.send ()" />
2. Parsing and displaying data
As shown in Listing 14, Adobe Flex components simplify processing the results of an HTTPService request.
Listing 14. Processing the results of an HTTPService request
paddingBottom = "5" paddingLeft = "5"
paddingRight = "5" paddingTop = "5"
cornerRadius = "5" borderThickness = "1"
borderStyle = "solid" borderColor = "black"
dropShadowEnabled = "true" shadowDistance = "3"
shadowDirection = "right">
dataProvider = "{listTodosHS.lastResult.item}">
paddingBottom = "3" paddingLeft = "3"
paddingRight = "3" paddingTop = "3"
rollOver = "event.currentTarget.setStyle
('backgroundColor', 0xffff88)"
rollOut = "event.currentTarget.clearStyle
('backgroundColor')" >
toolTip = "Click to delete item" />
fontSize = "8" textDecoration = "underline"
click = "getItemDetails (event)" />
toolTip = "Press Enter to add the new item."
enter = "createTodoHS.send (); event.currentTarget.text = '' »/>
backgroundColor = "white"
paddingBottom = "5" paddingLeft = "5" paddingRight = "5" paddingTop = "5"
cornerRadius = "5" borderThickness = "1"
borderStyle = "solid" borderColor = "black"
dropShadowEnabled = "true" shadowDistance = "3"
shadowDirection = "right">
paddingRight = "5" paddingTop = "5"
cornerRadius = "5" borderThickness = "1"
borderStyle = "solid" borderColor = "black"
dropShadowEnabled = "true" shadowDistance = "3"
shadowDirection = "right">
paddingRight = "3" paddingTop = "3"
rollOver = "event.currentTarget.setStyle
('backgroundColor', 0xffff88)"
rollOut = "event.currentTarget.clearStyle
('backgroundColor')" >
click = "getItemDetails (event)" />
enter = "createTodoHS.send (); event.currentTarget.text = '' »/>
paddingBottom = "5" paddingLeft = "5" paddingRight = "5" paddingTop = "5"
cornerRadius = "5" borderThickness = "1"
borderStyle = "solid" borderColor = "black"
dropShadowEnabled = "true" shadowDistance = "3"
shadowDirection = "right">
Event handling in Adobe Flex
Adobe Flex uses ActionScript, an object-oriented scripting language based on ECMAScript technology (see Resources), which allows you to create dynamic user interfaces for interactivity, such as event management (see Listing 15). Please note that the creationComplete () function requires additional steps to coordinate the method for generating HTTP REST calls in the Adobe Flex environment with the results that WebSphere sMash expects to get.
Listing 15. Sample Adobe Flex code
/**
* Logic to run after the mx:Application has been created.
*/
internal function creationComplete():void {
// initial population of the list
listTodosHS.send();
// Flex doesn't know how to generate an HTTP DELETE.
// Fortunately, sMash/Zero will interpret an HTTP POST with
// an X-Method-Override: DELETE header as a DELETE.
deleteTodoHS.headers['X-Method-Override'] = 'DELETE';
// set a dummy body for the POST so Flex won't change it to
// a GET
deleteTodoHS.request['foo'] = 'I really do want a POST';
}
/**
* Called when the user requests details for an item.
*/
internal function getItemDetails(event:MouseEvent):void {
// find id of item to be deleted
var lb:LinkButton = event.currentTarget as LinkButton;
var i:int = lb.parent.parent.getChildIndex(lb.parent);
idToRetrieve = listTodosHS.lastResult.item[i-1].id;
// hide details box while we're getting details
detailsBox.visible = false;
// ask server for details
retrieveTodoHS.send();
}
/**
* Called when the user checks on a box to delete an item
*/
internal function deleteItem(event:MouseEvent):void {
// find id of item to be deleted
var cb:CheckBox = event.currentTarget as CheckBox;
var i: int = cb.parent.parent.getChildIndex (cb.parent);
idToDelete = listTodosHS.lastResult.item [i-1] .id;
// hide details if deleting the same item
if (retrieveTodoHS.lastResult! = null &&
idToDelete == retrieveTodoHS.lastResult.id)
detailsBox.visible = false;
// tell server to delete item, list will be updated when
// delete finishes
deleteTodoHS.send ();
}
The download file (see Download section) contains the complete source code for this training program.
Generalization of previous reasoning
Adobe Flex does not have ready-made support for serializing JSON data. To implement this support, you must download the corelib library from the Adobe website and place it in the libs directory of the WebSphere sMash application (see Resources). To deploy the Adobe Flex application, the application (.swf) must be present in the public directory of the WebSphere sMash application. The source code included in this article contains two versions of the Adobe Flex application, the first of which uses the XML format, and the second uses the JSON format. If the WebSphere sMash server is running, then these applications can be accessed using the following links: localhost : 8080 / todoXML.html or localhost : 8080 / todoJSON.html, respectively.
Explanations for the following figures.
- View of the loaded application after calling the onList () method (Fig. 3).
- The Adobe Flex browser part sends an HTTP POST request to add a new item to the to-do list (Fig. 4).
- The Adobe Flex interface controls the onclick event (which occurs when a check box is selected in the control window) to remove an item from the to-do list (Fig. 5).
- When the user clicks on the to-do list element, the onRetrieve () method is called (Fig. 6 and Fig. 7).
- This application supports switching between implementations in Groovy and PHP (Fig. 8).
Figure 3. Application view after calling the onList () method
Figure 4. Adding an item to the to-do list
Figure 5. Removing an item from the to-do list
Рисунок 6. Пользователь выбрал пункт в списке to-do list
Рисунок 7. Вид приложения после вызова метода onRetrieve()
Рисунок 8. Приложение может переключаться между Groovy и PHP
Заключение
WebSphere sMash is a simple but powerful framework for quickly building Web applications. With support for two dynamic scripting languages (Groovy and PHP), WebSphere sMash allows you to quickly start developing Web 2.0 applications. This article demonstrates the standardized RESTful techniques that you can use to combine WebSphere sMash server logic with functionally rich, highly interactive user interfaces written in Adobe Flex. For more information about the topics covered in this article, see the Resources section.
Loading
Download file available for download: smash-flex-sample.zip
Resources
An article on the IBM
IBM WebSphere sMash website . Product Information (EN)
Project Zero Developer Community
Project Zero: REST (Programming Model and Resource Agreement) (EN)
Project Zero: JSON Support (EN)
Project Zero: Response Rendering (EN)