In our first example, we're going to implement a Handler which simply converts the URL into a file path for a HTML template, then loads that document, inserts the Steam variables into that document, and, finally, writes the results back to the web server. Does this sound complicated? Well, don't worry, it's not. We'll look at the code for the entire Handler class, as well as the DisplayPageHandler helper class for it. (This code can be found in src/java/org/locomotive/module/display/DisplayPageHandler.java) If you want to use this code, remember to add an entry for the DisplayPageHandler class in hrt.conf:
All Handler classes which you write must implement three methods, init(Log server_log), shutdown(Log server_log), and handleRequest(HandlerData hd). init() is called only once, when a Handler class is loaded into memory. It's intended for you to do any initialization routines required before your Handler can be run. shutdown() is called by the Locomotive when the Locomotive is about to finish executing; so, you should implement your global clean-up tasks for your Handler in shutdown(); for instance, you may need to clean up a cache in the database. handleRequest(HandlerData hd) is the method which the Locomotive calls to tell the Handler to handle a Web request.// Add your own handlers here: disp org.locomotive.module.DisplayPageHandler
public class DisplayPageHandler extends GenericHandler { /** * DisplayPageHandler doesn't do anything in the init() method. */ public boolean init (Log server_log) { return true; } /** * DisplayPageHandler doesn't do anything in the shutdown() method, either. */ public boolean shutdown (Log server_log) { return true; } /** * main entry point called by RequestManager for each new request. */ public void handleRequest (HandlerData hd) { // call GenericHandler's handleRequest(hd) method, // to set up local variables super.handleRequest(hd); // insert some standard Steam variables, such as date and time. StandardInsertions.insertAll (hd); // if the URI is not null or empty, and it has only alphanumeric // characters or '?' or '+', then try to convert it into a file // path. if (handler_uri != null && !handler_uri.equals("")) { // NOTE: handler_uri, like a standard URI, always begins with // a leading '/', so we strip it off with substring(1) first. String convert_url_to_alphanum = handler_uri.substring(1).replace ('?', 'a').replace ('+', 'a'); if (StringUtil.isAlphanum (convert_url_to_alphanum)) { // convert "base?login+form" to "base/login/form.tmpl", // then display that file as a HTML template. String result = displayPage ( handler_uri.substring(1).replace('?', '/').replace( '+', '/') + ".tmpl", steam_vars); // if there is no file in that file path, then // displayPage() will return an empty string "", // in which case we should // tell the user that the URL was faulty. if (result.equals("")) sayBadURL(); } else { sayBadURL(); } } else { // send the user an error message saying that it was a bad URL sayBadURL(); } } }
Then, it checks that the URL is not null or empty, and does not contain any non-alphanumeric characters other than '?' and '+':// call GenericHandler's handleRequest(hd) method, // to set up the local variables super.handleRequest(hd);
Then, if everything is okay, it replaces both '?' and '+' within the URL with '/' and appends ".tmpl", converting "base?login+form" to "base/login/form.tmpl", for example. It passes this newly created file path into the method displayPage(), which is a method of GenericHandler which attempts to display that page as a HTML template. This means that displayPage() will insert the values of all Steam variables into that document, as well as write the result back to the web server:if (handler_uri != null && !handler_uri.equals("")) { // NOTE: handler_uri, like a standard URI, always begins with // a leading '/', so we strip it off with substring(1) first. String convert_url_to_alphanum = handler_uri.substring(1).replace ('?', 'a').replace ('+', 'a'); if (StringUtil.isAlphanum (convert_url_to_alphanum)) {
However, what about the case where the URL does not point to a real file? In that case, we would want to tell the user that their URL was bad. How can we tell whether the URL pointed to a real file? Well, displayPage() returns a String which contains the complete HTML template after all the Steam variables have been inserted. If the file path was invalid, then displayPage() will simply return an empty string, "". We can use that information to tell the user that their URL was bad:String result = displayPage ( handler_uri.substring(1).replace ('?', '/').replace ('+', '/') + ".tmpl", steam_vars);
Finally, if the URL is null or empty, or contains any non-alphanumeric characters other than '?' and '+', then, again, we tell the user that their URL was bad:if (result.equals("")) sayBadURL();
By the way, sayBadURL() is a GenericHandler method which sends back to the web server an HTML Page containing a simple message: "I'm sorry, I don't understand that URL." If you wish to override this message, you can use the GenericHandler method called displayString() to send a different message back to the web server, for example:else { // send the user an error message saying that it was a bad URL sayBadURL(); }
displayString("What was that? Try again.").
SUMMARY
In the last example, we used the String methods equals() and replace(); the StringUtil method isAlphanum(); and the GenericHandler methods displayPage() and sayBadURL(). We learned how to display a HTML template, and how to use the "handler_uri" variable. In the next example, we'll use the "user" and "session" variables and their methods, as well as use the "form" variable to access the data from an HTML form. In the next chapter, we will run through the basic steps you'll have to perform to write a module, and we'll talk a little about the differences between writing a Servlet module and a Handler module.