Qwicap is a web application development API written in Java and based on the XHTML, CSS2 and Java Servlet technologies. It dispenses with the usual hit-run-exit model of web applications, automatically provides a state-rich environment, and includes an XML "templating" engine that makes on-the-fly customization of web pages straightforward while promoting a loose coupling between page markup and code. It is intended to reduce the learning curve associated with writing web applications, and the amount of time even experienced developers spend dealing with the mechanics of such development. Furthermore, it seeks to offer an alternative to the intimate mixing of code and content promoted by Java Server Pages (JSP), the confusion and code fragmentation associated with JSP tag libraries, and, for that matter, the embedding of content into Servlet or CGI code, with the associated code-clutter and content maintenance problems.
"Qwicap" is an acronym for "Quick Web Interface for Conventional Applications." In this context, a "conventional application" is considered to be the sort of application people traditionally write when learning to program, or for use in interactive command-line environments: An application that writes output to the console, prompts its user for input whenever it wants to, blocks until the input is received, processes the input to produce some output, and continues that cycle until a desired result is achieved. While such applications often end-up with user interfaces that only their mothers could love, compared to GUI- and Web-based applications they are wonderfully quick and easy to write.
Qwicap therefore attempts, as much as possible, to make that conventional application design model work in the context of Java web applications, while doing everything it can to promote and support a high quality web interface. Where possible, it automates "best practice" (or at least "pretty good practice") behaviors.
The developer's learning curve is minimized by that approach, by Qwicap's modest, high-level API1, and by its refusal to employ crutches like metadata, config files, and custom markup. Beyond a familiarity with Qwicap's high-level API, the developer needs only a basic grasp of XHTML markup, cascading style sheets, and their application server of choice - inevitable requirements for web-oriented developers, whether they use Qwicap or not.
The conventional application model was adapted to the web and Qwicap as follows:
- Where output was text printed to a console, output becomes whole web pages customized on-the-fly using a templating system and transmitted to a browser.
- Where input was any text typed at a prompt, input becomes all the data entered into a form on a web page.
- Where an application typically blocked when it read input after prompting, a Qwicap application blocks after sending a web page to the client.2 Both applications enjoy the flexibility of prompting the user for input at any time. However, the Qwicap application also has the benefit of type-specific accessor methods to retrieve and validate its input (the name/value pairs supplied by the controls in XHTML "form" elements). When those methods determine that input is invalid, error messages are automatically generated and inserted into the document markup above the relevant form, applicable labels3 are marked for emphasis, and the document is sent back to the client for correction, all transparently to the application.
Brief Application Examples, Conventional vs. Qwicap
Below are conventional (interactive command-line) and Qwicap implementations of the same game in which the user attempts to guess a number between 0 and 100, inclusive. The implementations do the same things in the same order, and are approximately the same length, although certain operations require more lines of code in one version or the other. (Long lines have been wrapped and their continuations indented.)
Conventional Implementation of Number Guess
The following is a complete, self-contained implementation of the "number guess" game in
the form of an interactive, command-line application. Note that the only significant
overhead—code not strictly involved in implementing the central algorithm—is
the user input verification loop. The Qwicap version benefits from a single method call
(getInt
) which provides that verification, conversion and correction-request
functionality.
import java.io.InputStreamReader; import java.io.BufferedReader; public class CLI { public static void main(final String[] args) throws Exception { final BufferedReader In = new BufferedReader(new InputStreamReader(System.in)); final int No = new java.util.Random().nextInt(101); int GuessCount = 0; int Guess; System.out.println("A random number between 0 and 100 (inclusive) has been selected."); do { while (true) { try { System.out.print("Guess the number: "); Guess = Integer.parseInt(In.readLine()); if (Guess >= 0 && Guess <= 100) break; } catch (NumberFormatException e) { System.out.println("That's not a number. Try again."); } } if (Guess < No) System.out.println(Guess + " is too low."); else if (Guess > No) System.out.println(Guess + " is too high."); GuessCount++; } while (Guess != No); System.out.println("Correct! The number was " + No + ". You guessed it in " + GuessCount + " attempts."); } }
Qwicap Implementation of Number Guess
The following is an implementation of the "number guess" game in the form of a Qwicap-based web application. This is the entire implementation, but it is not complete in the sense that it depends on a web page, and a style sheet, which are not shown here.
The only significant overhead in this implementation is manipulation of the web page. There are two conceptually distinct manipulations being conducted. The first is the changing of the visibility of the web page's major divisions as the application progresses through its three phases: introduction (the initial page), interaction (playing the game), and conclusion (summarizing the outcome). This requires 2½ lines of code. The second type of manipulation inserts into the page feedback on the outcome of the user's guesses. This requires two lines of code, one in the interactive phase of play, and one to summarize the outcome. The author recognizes that this approach is not as simple as just using a few "println" statements on the command-line, but believes it's not bad. And, of course, it buys the application not only a web interface, but one that is flexible and of good quality.
Observe that this application effortlessly and transparently gains the benefit of
sessions and server-side state. Indeed, Qwicap's approach effectively extends
server-side state to encompass even the local variables in existence, and all the
control-flow that is in-progress, when the prompt
method is invoked.
This imposes a price in server memory consumption, but given the gains in simplicity and
development speed (and probably in execution speed), along with the modest cost of RAM,
the author believes this to be a beneficial trade-off. The worst side-effects of this
design can be mitigated by developer education: If your server might become
memory-constrained, avoid holding references to large, temporary allocations in call
chains leading to prompt
invocations.
For additional, expanded comparisons of "number guess" implementations, see the document "Comparison of Number Guess Implementations".
In situations where such limits cannot be avoided, major sections of the Qwicap code, notably the XHTML templating mechanism, can be used independently of the full-up, thread-oriented Qwicap system.
It is the author's opinion that there are no silver bullets, and no one-size-fits-all solutions to development problems, so the fact that Qwicap isn't equally suited to all web applications is something it has in common with every other method for creating web apps. In addition, he suspects that the majority of web apps serve relatively small numbers of users concurrently, and that throwing commodity server hardware at a scaling problem can be more cost effective than throwing programmer-hours/days/weeks at it.