In the J2EE (Java 2 Platform, Enterprise Edition) architecture's presentation tier, servlets and JSPs (JavaServer Pages) generally render data derived from the business logic tier as HTML for browser presentation. Implementing your application in HTML offers many advantages: HTML is easy to write, very lightweight, and looks aesthetic.
However, sometimes HTML can be limiting when you require a more complex GUI (graphical user interface). For example, the
<table> tag is simple (yet powerful), but it doesn't have scrolling, selection, and editing capabilities. What happens if you need a table that behaves more like a spreadsheet, where the user scrolls through the results and carries out complex cell selections? In addition, what if you need a hierarchical tree display. No HTML tag displays a tree structure that lets users expand and contract, drag and drop, or rename and delete nodes; something you might expect in a mailbox display that mimics a desktop mailbox.
You can implement some table and tree behaviors using HTML and DHTML. For example, you can implement simple selection in tables using checkboxes and cell background color. However, DHTML is difficult to write and maintain and has notorious browser deployment problems. Conversely, due to its rich object-oriented API, Java is well suited to this complex GUI behavior in the form of browser-embedded applet components. But what exactly is the relationship between applets and J2EE, and how can you integrate applets into a J2EE architecture?
In The J2EE Tutorial, Sun Microsystems briefly mentions that one client option is to embed applets in Webpages. However, the tutorial is unclear on how to integrate an applet into a J2EE system; instead, it concentrates on Web components (servlets and JSPs). This is due to the simplicity of those technologies; no plug-ins are required. Sun also mentions that you can use JSPs for outputting XML documents, which is generally useful for producing data in a standardized computer-readable format for Web service consumption.
However, in this article, I present a valuable J2EE pattern to embed presentation applets in your standard JSP-generated HTML, which consumes XML as a source of display data that your Web components also generate. This avoids your applet components having to make RMI/IIOP (Remote Method Invocation over Internet Inter-ORB Protocol) calls to retrieve data from EJBs (Enterprise JavaBeans) or other J2EE components that introduce complicated firewall issues. It gives you the best of both worlds from Web clients and Java applications: Flashy HTML that contains components with potentially complex behavior configured by simply formatted data.
So how do you do it? First, let's consider the concept of presentation data. Presentation data is data derived from your business logic tier (and ultimately your data tier) that has been processed and simplified to essentially configure a viewer. Presentation data comprises data that will appear in the GUI component and any extra data that describes the structure and state of that GUI component. For example, think of a hierarchical tree viewer; here is the data required to represent an instance of such a tree:
- The names of the nodes that comprise the tree
- Whether each node is a leaf or a folder
- A representation of the node hierarchy
This data more or less equals the data that a
JTree requires in its
TreeModel. You can represent presentation data in XML format. Here is a simple example of an XML document representing a hierarchical tree:
<?xml version="1.0" encoding="UTF-8"?> <tree title="My Tree Root"> <folder title="My Folder One"> <leaf title="My Leaf One"/> </folder> <leaf title="My Leaf Two"/> </tree>
You can easily imagine enriching each tree node description with further attributes, such as the URL of a node's icon, a hyperlink to the object the node represents, and the object class a node represents (such as a currency or a date class).
This XML document might seem simple, but when you consider that JSPs can easily generate much more complicated versions of this document, a whole new world opens up. For example, a user could obtain an XML document representing a user's mailbox by simply looking up a URL. Behind the scenes, the servlet mapped to that URL looks up one or more EJBs and calls remote methods on them. The remote methods fetch the required data using JDBC (Java Database Connectivity) and carry out any necessary business logic before returning the data to the calling servlet. The servlet then passes the data to a JSP to render as an XML presentation data document.
However, an XML document full of presentation data isn't useful on its own. This is where applets come in. You can program applets to read these XML documents and parse the data into object graphs that can be displayed using Swing and other component libraries. For example, you can parse the tree XML document into
DefaultMutableTreeNode objects, which a
JTree can display. Figure 1 shows a sequence diagram for the whole process of displaying a J2EE-derived Webpage with an applet.
A JSP can embed an applet in an HTML page by either using the standard HTML
<applet> tag or using the
<jsp:plugin> tag. The latter tag encapsulates the HTML code required for running an applet with the Java Plug-in. The Java Plug-in is a browser plug-in that overrides the browser's default JVM and lets you run applets with a specified JVM. This lets the browser utilize the latest Java APIs without you having to wait for the browser itself to implement them.
But the Java Plug-in has one major disadvantage: The user has to download more than 9 MB of code just to view your applet! This eliminates the possibility that Web applications that need to attract casual Web surfers will use the Plug-in. However, Web applications that have frequent users can definitely warrant the overhead of downloading the Plug-in; for example, applications on a corporate LAN that an employee requires to perform his/her job. In addition, you can configure the
<jsp:plugin> tag so that the Plug-in is downloaded from a particular place. This means that you can place the Plug-in on the LAN for speedy installs.
One powerful aspect of this pattern is that applets can fire off the business processes that implement any state change the user makes to the applet-displayed data. You can implement this by getting applets to call on URLs that include parameters to encode the state change. For example, if you want to implement drag and drop in a
JTree, you could give each node a unique ID. You might specify a folder node in your XML document like the following:
<folder title="My Nice Folder " id="5">
and a leaf:
<leaf title="My Nice Leaf" id="7">
Upon notification of a drop gesture within a folder, the system constructs a URL object:
You then request this URL by using class
openStream() method. The URL maps to a servlet that calls a stateless session bean, which performs the move. If the move is successful in the session bean, the following document returns to the applet:
<?xml version="1.0" encoding="UTF-8"?> <tree-move> <success/> </tree-move>
Upon receipt of this document, the client-side logic that moves the node within the
TreeModel could then execute. For example, if a tree node is deleted, the node could be removed from the
TreeModel. If something goes wrong during the server-side call, an XML document indicating the failure could return:
<?xml version="1.0" encoding="UTF-8"?> <tree-move> <failure/> </tree-move>
You then report the server-side failure to the user through, for example, a status bar message or a dialog box. Figure 2 shows how the applet fires these state changes.
Following are several useful hints and tips for implementing this pattern.
Make the XML format as simple as possible
XML is a bulky data format and takes time and effort to transport and parse. Therefore, you should keep the format as simple as possible. Only include necessary data and try to keep XML tags short. You will need to encode some characters—like "<", ">", and "&"—using their
&#xxx character reference; otherwise, you will get parsing errors.
Use a lightweight SAX parser
To minimize application startup time, use a lightweight parser. One parser I found appropriate for this pattern is Aelfred, which has a low download time. In addition, it is free for commercial and noncommercial use. If you deal with simple XML documents, you can implement your own primitive parser. The SAX API is preferable to DOM, as it saves on memory due to its event-driven model.
Don't validate the XML
Validating the XML documents in the applet takes time, so you should avoid it if possible. It is, however, important to catch any exceptions that result from unexpected XML structure and let the user know via some GUI feedback element, such as a status bar or dialog box message.
Only retrieve the data you need
You can save on download overhead by only retrieving the data you actually need at that time. For example, in the Swing JTree previously described, you don't need the whole data structure if that involves downloading a lot of data. You can introduce a node like the following:
<dynamic-folder title="My Dynamic Folder" data-link="http://localhost:8080/tree/url-to-get-more-data?node-id=123"/>
Although this folder contains no data, you could render it normally and when the user expands it, the applet could read the data-link URL and then fetch an XML document containing the data for its children. This could be parsed, placed in
TreeNode objects, and rendered as usual. This saves on a large data download that you might not use when the applet first loads.
If displaying a
JTable, you don't need to have all the data on the client side. A
JTable fetches its data from its
TableModel as it needs them. This lets you get data as required. For example, you could start by loading the first 50 rows. If the user scrolls down below row 50, the
TableModel can ask a servlet to fetch the next 50 rows; that is, on-demand data fetching.
Only use applets where you need them
Avoid confusing UIs
You should avoid confusing the user by mixing browser and applet UI components. In our tree example, deleting a node by selecting from a pop-up menu would confuse the user. When the user right-clicks on the tree, she would get a completely different set of menu items to those used by clicking on the standard HTML (e.g., View Source and Refresh).
Pros, cons, and a demonstration
To summarize, this presentation-tier pattern has some distinct advantages:
Lets you complement standard dynamically generated HTML in a J2EE-based application with sophisticated Java components
Achieves a strong decoupling between the business logic tier and the presentation tier, as no RPC calls exist directly from the applets to the EJBs
Your J2EE application works over a firewall, like a regular Web application
- Because the presentation data is simple, you can easily render the data by other means, such as a .Net application, a B2B application, and so on
The only real disadvantage of this pattern is that users probably have to download the Java Plug-in to view your site. However, the power in terms of functionality to your Web application is a compelling reason for users to overcome this activation energy in many situations.
A simple proof-of-concept demonstration is included in the source code accompanying this article. It consists of a servlet that outputs a dynamically generated HTML page that contains an applet displaying a
JTree. The applet derives its data from another servlet that outputs XML. The applet lets you persistently delete tree nodes; therefore, it demonstrates the ability to change your data's state from an applet. This will give you a head start in writing your own implementations of this powerful pattern.
Learn more about this topic
- Download the source code for the proof-of-concept implementation of this presentation pattern
- Also in this week's Spotlight on J2EE"US Department of Energy Signs on to J2EE," Jian Zhong and Mike Lehr (JavaWorld, May 2002)
- The J2EE Tutorial, Stephanie Bodoff et al. (Addison-Wesley, March 2002; ISBN0201791684) details J2EE's three-tiered model and explains the presentation tier
- Buy the print version of The J2EE Tutorial
- The Java Plug-in
- The <jsp:plugin> tag
- OpenText's Aelfred is a free, lightweight XML parser suitable for use by applets due to its relatively small size
- "Java Tip 97Add Drag and Drop to Your JTrees," Rob Kenworthy (JavaWorld) is a useful Java tip for implementing drag and drop in JTrees
- Browse the Java 2 Platform, Enterprise Edition (J2EE) section of JavaWorld's Topical Index
- Browse the Java and XML section of JavaWorld's Topical Index
- Browse our complete list of David Geary's Java Design Patterns columns
- For more design pattern stories, visit the Design Patterns section of JavaWorld's Topical Index
- Speak out in JavaWorld's Enterprise Java discussion
- Sign up for JavaWorld's free weekly email newsletters
- You'll find a wealth of IT-related articles from our sister publications at IDG.net