|
![]() |
|
Our sample Java Server Pages application displays regularly updated appointment data for someone on the move, such as an appliance engineer making house calls. This application was created on Windows NT using the Java Server Web Development Kit (JSWDK) 1.01. I used the servletrunner utility that comes with the JSWDK to serve the JSP pages from my own desktop machine. In order to test and view the application I used the Nokia WAP Toolkit 1.2. This is a nice Java SWING application that requires the Java Runtime Environment (JRE) 1.2.2 to be installed on your computer before it will run. It consists of a browser that displays the WAP content on a simulation of a mobile phone. The normal way to serve WAP content is to have a WAP gateway server sitting between the mobile phone network and a standard web server. One reason for this is that WML is compiled or "tokenized" to conserve bandwidth. But the Nokia WAP Toolkit contains its own WML compiler and so it can talk directly to an HTTP server (in our case the servletrunner utility). The WAP toolkit is available from the Nokia WAP Developer Forum at http://forum.nokia.com. Although it is free, you will have to register before you can download it. A Brief Introdution to WMLThe most important thing to remember about WML is that, since it is an XML-defined language, it is "well-formed". This means that, unlike HTML, all tags must be closed and cannot be incorrectly nested, and all attribute values must be enclosed in quotation marks. WML is also DTD-validated, which means that any WML content is checked against the WML Document Type Definition before it is displayed. So tags must have exactly the attributes specified in the DTD and cannot be nested inside a another tag unless permitted by the DTD. Unlike normal web browsers, you'll find that the Nokia simulator is extremely fussy and will refuse to display any page that contains the slightest violation. Although WML bears a superficial resemblance to HTML, don't be fooled, because there are significant differences. The key metaphor in WML is that of a deck of cards. The deck is the smallest unit that is downloaded to the device and consists of one or more cards which normally equate to one display "screen". The deck is contained within the <wml> and </wml> tags. When a deck is first loaded, the first card in the code is shown (unless you are navigating to a specific card within the deck). Each <card> has an "id" attribute that is used for referencing it in hyperlinks and a "title" attribute that is typically displayed at the top of the screen. All visible content in a card must be enclosed in a <p> element. The text formatting tags are the same as their HTML counterparts: <b>, <big>, <em>, <i>, <small>, <strong> and <u>. You can also build tables in WML with the familiar <table>, <tr>, and <td> tags, but the <table> tag requires a "columns" attribute. It is important to remember that current WAP devices may not support all of the formatting elements, and there may be considerable variations in the way that they are displayed. With WML it is possible to declare variables that can be substituted into display text, and which can be used to preserve state between decks. Variables are set with the <setvar> element which has the name and value attributes. To substitute the current value of the variable into text, prefix the variable name with $, as in Perl. As a consequnce of this, the dollar sign must itself be escaped as $$ if you wish to display it in normal text. WML uses the # sign to indicate a hyperlink to a card within a deck, in the same way that anchors within an HTML page are referenced. For example, the URL "/my_deck.jsp#card_two" will display the card with the id attribute value of "card_two" in the deck served up by "my_deck.jsp", whereas the URL "#card_two" references the card with that id in the current deck. The Constraints of WAP DevelopmentWhen building WAP applications you must bear a number of points in mind. WAP devices have a small display area - typically four lines of twelve characters, and having to scroll too much can be annoying. The data entry capabilities may be limited and awkward. The device will probably have limited RAM and CPU power. And the current wireless networks have low bandwidth and are slow and unreliable with high latency. Coupled with the lack of control the programmer has over the way that widgets are displayed, it becomes clear that WAP applications should be lightweight and simple. The ApplicationOur sample application consists of two decks. The first is served up by pick_appointment.jsp and has one card which displays a <select> widget of appointment times. When an <option> is selected the user is forwarded to the second deck, show_appointment_data.jsp, which is passed the appointment ID as a parameter. This second deck has two cards. The first displays the appointment data and the second contains a data entry widget that allows the engineer to check off the appointment by entering a completion code. The dynamic appointment data is fetched from a Java Bean instance, the source code of which is not shown, but which might use JDBC to connect to a database of appointments. The check-off code is processed by a servlet, the source code of which is also not shown. Since the appointments may change throughout the day as customers phone in to cancel we will refresh the pick_appointment.jsp page every minute in case the engineer leaves his phone pointing at that page. pick_appointment.jsp Please note that there are artificial line breaks in the code that follows - created by the layout of this Web page. You can check the correct line breaks by looking at the page source code.
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" <%! <%! String strXMLPrologue = "<?xml version=\"1.0\"?>"; %> <%-- WML CONTENT BEGINS --%> <timer value="100%"/> <!-- Display the "select" widget of appointments to pick --> <%-- WML CONTENT ENDS --%>
<jsp:useBean id="appointmentBean" class="mwebber.samples.AppointmentBean" <% <%! String strXMLPrologue = "<?xml version=\"1.0\"?>"; %> <%-- WML CONTENT BEGINS --%> <p> </wml>
Since a WML deck is really an XML document it contains the standard XML prologue and a pointer to the DTD. However, the <? and ?> markers of the prologue appear to confuse the JSP parser and so we hide this prologue in a String variable (don't forget that a JSP page is parsed into a Java source file which is then compiled into a servlet). You should also be aware of this problem if you use other "server page" languages such as PHP and ASP. Note that the <br/> tag is closed - this is standard XML. And as you can see, comment markers are the same as in HTML. WML has support for basic event generation and handling. To understand the mechanism, you'll need to think in terms of "tasks" which are bound to "events". A task, unsuprisingly, is something that is done. There are four types of task, <noop>, <refresh>, <prev> and <go>. Our sample application uses the latter two. The <prev> task navigates to the previous card in the device's history stack, which each WAP device is required to maintain. The <go> task navigates to a URL. It may be used as a simple hyperlink, as in our first deck which uses it in conjunction with a timer event, or to send form data to the server, as in our second deck which uses it in conjunction with an accept event. For the second use there is the <postfield> element which defines the name-value pairs to be passed to the processing script. Note that the "value" attribute is set to the "check_off_code" variable, which the device automatically sets to the value that the user entered in the input field. An event, when fired, processes the task that is bound to it. Tasks may be bound with one of three event tags: <anchor>, <onevent>, and <do>. Our application uses the latter two. The <onevent> tag handles what are known as Intrinsic Events. These are events that are triggered internally by the device. There are four types of Intrinsic Event, specified with the type attribute: oneventforward, oneventbackward, ontimer, and onpick. The first two are fired when the user navigates to a card, and the onpick event occurres when the user selects or deselects an <option> item of a <select> widget. Our application uses a timer to reload the deck every minute. The value attribute of the <timer> tag is the interval in tenths of a second. You can see that we have associated a <go> task with the timer event in order to reload the deck. Besides Intrinsic Events there are seven User-Triggered Events. These are specified with the <do> element which assigns a task to a hardware key or on-screen widget (this is device-dependent). These Intrinsic Events are accept, prev, help, reset, options, delete, and unknown. On the Nokia simulator our "prev" event is fired by a selecting a special "Back" option that appears below the main screen, accessed by the right control button on the handset. Setting the label attribute of the <do> element has no effect with this device. The display widgets for the "accept" event in our second deck are rather convoluted, and involve taking us through an Options menu to a dedicated data entry screen. The <input> element specifies a text entry object. Among the attributes of the <input> element are the following. emptyok - this specifies whether or not the user must enter a value in the field. There is considerably more to the WML language than we have had space to cover here, but I hope that this article has covered enough of the basics to allow you to begin developing WAP applications of your own.
An excellent WML and WMLScript tutorial is Programming Applications with the Wireless Application Protocol by Steve Mann (John Wiley & Sons, 2000). Mark Webber is a Web Developer with Demon Internet, a brand of Thus plc. He is a Sun Certified Java Programmer. |
| Suits | Ponytails | Propheads | Contact WDJ | Discuss | Web Audio | Search |
