Restlet Cookbook - Delving into handleGet() and handlePost() (Recipe 8)

Posted: 07/30/2008 by Serge Ilyn

If you look at the Restlet API related to the org.restlet.resource.Resource, you will notice several handleX() methods where X may stand for various types of calls. When you develop a Web site application with more or less complex functionality, these methods, in particular, handleGet() and handlePost() may be your best friends in finding solution for some trickery you plan for the site. This posting provides related examples that illustrate at least some simple things you may do with these methods.

Now, let's look at the documentation for handleGet() and handlePost():

  • public void handleGet() Handles a GET call by automatically returning the best entity available from the target resource (as provided by the 'findTarget' method).
  • public void handlePost() Handles a POST call invoking the 'post' method of the target resource (as provided by the 'findTarget' method).

Although there are some differences in the description of both methods, it's obvious that both play an important role in processing requests. For example, let's play with handleGet() by trying to override it with different implementations - look at Listing 2. which also tells you what will happen in different cases.

Listing 1. Playing with handleGet()
// A. Nothing happens here - you will see blank page
   public void handleGet() {}

// B. Everyting is fine now
   public void handleGet() {
       super.handleGet();
   }

// C. Redirected to IBM web site
  public void handleGet() {
     getResponse().redirectPermanent("http://www.ibm.com");
  }

For practical purposes, the most interesting case is C. since it shows us a way to take advantage of overriding handleGet() to achieve the functionality we may need. As an example, look at Listing 3 with handleGet() in a hypothetical Resource that processes GET for showing shipment and billing address form of an e-commerce Web site. One of the two unpleasant cases you want to process is when someone is requesting the address form with a shopping cart that is empty (by guessing the URL for the address form). No matter how stupid this case may seem to you, a well appointed application should be able to have all sorts of safeguard mechanisms.

The second condition in handleGet() in Listing 5 is more realistic - you check the protocol used to get the form. If it happens to be an HTTP call, you should switch it to HTTPS to protect users' personal data. And that's exactly what is done.

Listing 2. Scenario of using handleGet() in a Resource than processes shipment and billing address form (GET)

  public void handleGet() {
    if (getShoppingCart().isEmpty()) {
       getResponse().redirectTemporary("/continue_shop"); }

    Protocol protocol = getRequest().getProtocol();
    if(protocol.equals(Protocol.HTTP)){
        Reference ref = getRequest().getResourceRef();
        getResponse().redirectPermanent("https:" + ref.getHierarchicalPart());
    }

    super.handleGet();
  }

Before I start talking about handlePost(), I would like to draw your attention to a very important note in the Javadoc for the Resource class: "...You need to declare which REST methods are allowed by your Resource by overiding the matching allow*() method. By default, allowGet() returns true, but all other allow*() methods will return false..." This is to say that to use POST, you will have to override allowPost() (see Listing 3.)

Listing 3. Overriding allowPost()
  public boolean allowPost() {
    return true; }

If you start playing with handlePost() same way we played with handleGet(), you will notice that it's conveniently called for us as well every time we hit the "Submit" button of the form. Again, it means that by overriding it, we may code many things that are frequently associated with POSTing. Let's look at Listing 4. which shows handlePost() for a hypothetical Contact Us form. Three interesting things to look at are:

  • An approach to validate data submitted with the form
  • Re-display of the contact us form if validation fails and
  • Redirection to the "Thank you page" if everything is fine; you may also notice that among other things I save data in a database (see below for some insights about processing errors)

Sometimes I get emails where folks ask me question like "what is buildFromForm()? I do not know such method; can you explain?" Well, I would like to stress that I am trying to provide concepts and not a ready-made applications. However, very often to illustrate concepts especially in an interesting context, some other stuff is needed. I am trying to provide meaningful names so that the context makes sense. But I do not provide usually any complete implementation of such context since this is a Restlet cookbook and not a Java one.

Anyway, to clarify Listing 4.:

  • contactUs is an instance of what you may call a "data" bean I use to make the Resource design cleaner. Please look at previous recipes where this approach is fully illustrated.
  • buildFromForm() is a a very simple method that populates the "data" bean with values from the form submitted.
  • validator is an instance of a Validator class which is responsible for making sure that data submitted are good. It has nothing to do with Restlet API - you may call its most important method any way you want, but ultimately it should return true if data are OK and false otherwise.
  • Same way, saveToDatabase() is method can be anything you need (and it may depend on the persistent storage you are using).
  • getPagable() is any method that returns an object suitable for constructing TemplateRepresentation (it can be contactUs especially if it implements some kind of Page interface as a standard way of supplying data to the template)

On a substantive side though, I would like to point to the getResponse().setEntity(result) line of code that allows to set a Representation instance as a Response entity (very natural if you think about it but nevertheless elegant). And that's what is done if validation fails (also make sure that whatever templating system you are using, it re-displays data that should be re-displayed upon failed validation). After saving data to the database (which implies that data are OK), you see in Listing 4 already familiar trick of redirecting to another page: in this case to some kind of "thank you" page (or anything you want).

Listing 4. Example of handlePost() while POSTing a Contact Us form
  public void handlePost() {
     contactUs.buildFromForm(getRequest().getEntityAsForm());
     Validator validator = contactUs.getValidator();
     if (validator.isFailed()) {
         Representation result = new TemplateRepresentation("contact_us.ftl", 
Arredocenter.freeMarkerConfig, getPagable(), MediaType.TEXT_HTML);
         getResponse().setEntity(result);
         return;
    }

    try {
       saveToDatabase(getRequest(), contactUs); }
    catch (Exception ex) {
       ex.printStackTrace(); }
    
   getResponse().redirectTemporary("/page/thank-you");
  }

I would like to finish with pointing to another potentially very important use of handleX() methods - exception handling. Let me quote Restlet FAQ that illustrates nicely this point: "Typically, unexpected exceptions are handled at the Application level, by setting the status to 500 (internal server error). If you want a different status when an exception is thrown, you have to catch it manually at a lower level (inside the handle(Call) or handleGet|Post|etc. method of your intermediary Restlet) and set the desired status on your response."


Recent Blogs

Convergence of Technologies II: Restlets, Highslide Viewer & SlideShowPro for Flash How to use Restlets, Highslide Viewer & Slide Show Pro Flash component to generate slide shows and show them in pop-up iframes 08/14/2009

Convergence of Technologies: Restlets, Highslide Viewer & Google Maps API How to use Restlets, Highslide Viewer & Google Maps API to generate Google maps using links on Web pages and show them in pop-up iframes. 08/13/2009

Ambimorphic, Mobile Configurations for Lamport Clocks After years of technical research into Smalltalk, with close cooperation with MIT Computer Science and Artificial Intelligence Laboratory (CSAIL) and its SCIgen, we have been able to show the construction of link-level acknowledgements. As a result, we propose an analysis of A* search, which we call Volt. 10/02/2008

Restlets and HTTP Sessions (Recipe 9) This recipe discusses some options in available to Web site developers using Restlet API to emulate traditional HttpSession's 07/31/2008

Restlet Cookbook - Delving into handleGet() and handlePost() (Recipe 8) This posting provides related examples that illustrate at least some simple things you may do with several handleX() methods where X may stand for various types of calls. 07/30/2008

Restlet Cookbook - How to enable SSL (Recipe 7) How to enable SSL on Restlet Web sites wihtout knowing too much keys, encryption, SSL and such. 07/29/2008

Restlet Cookbook - Using Filters in Restlet Applications (Recipe 6) This recipe contains code snippets illustrating the use of Filters in Restlet applications 03/09/2008

Restlet Cookbook - How to Create Virtual Hosts in Restlet Applications (Recipe 5) This recipe contains a code snippet for creating virtual hosts 02/24/2008

Popular HTML Escape Codes Here is a table of HTML escape codes for most frequently used symbols. If you use HTML, sooner or later you will find this table useful. 12/29/2007

Restlet Cookbook - Access Log (Recipe 4) This recipe describes access Logging using Restlet framework 11/09/2007

more...