Recent Blogs

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

Restlet Cookbook - Form Submission and Processing (Recipe 3) This recipe describes a typical form submission using Restlet framework 10/15/2007

Restlet Cookbook - Site Application (Recipe 2) This recipe describes a possible way to code a Restlet Web site application 10/04/2007

more...

Restlet Cookbook - Form Submission and Processing (Recipe 3)

Posted: 10/15/2007 by Serge Ilyn

After describing some basic approaches and coding while designing and implementing a Web site using Restlet framework, let's consider next step - showing and submitting a Web form. Using Restlets, it's as easy as just showing simple Web pages.

Showing Web Form

As always, there are many ways to to this - the code below is based on the design and samples in the first two recipes. If you followed them, you know that to show a form, since it's just another resource, we need to route to this resource based on URL. With the form, we do this exactly the same way it is done for all other resources in Recipe 2 - see the createRoot() method. Now, we will "attach" to the router the ContactUsResource class which I will discuss shortly.

Example 1
  /** createRoot */
  public Restlet createRoot() {
    ...
    router.attach("/contact", ContactUsResource.class);
    ...

    return router;
  }

Conceptually, the ContactUsResource class is not much different from the PageResource class discussed in Recipe 1 (see Recipe 1, Example 3). The example below shows how the new resource can be coded. Note that the same way as the PageResource class before, it extends the BaseHTMLResource, and in its getPagable() method returns an instance of the ContactUs class (we'll take care of ContactUs in a moment)

Example 2
public class ContactUsResource extends BaseHTMLResource {
  ContactUs contactUs;

  public ContactUsResource(Context context, Request request, Response response) 
{
    super(context, request, response);
    contactUs = new ContactUs();
  }

  public Representation getRepresentation(Variant variant) {
    Representation result = null;
    if (variant.getMediaType().equals(MediaType.TEXT_HTML)) {
      try {
        result = new 
TemplateRepresentation(Constants.findLayoutTemplateName(contactUs.getLayout()), 
Naviquan.freeMarkerConfig, getPagable(), MediaType.TEXT_HTML);
      }
      catch (Exception ex) {... }
    }

    return result;
  }

  public boolean allowPost() {
    return true; }

  public void handlePost() {
    contactUs.buildFromForm(getRequest().getEntityAsForm());
    try {
      saveToBackend(getRequest(), contactUs); }
    catch (Exception ex) {
      ex.printStackTrace(); }
    getResponse().redirectPermanent("./");  // redirect to the home page
  }

  private void saveToBackend(Request request, ContactUs contactUs) throws 
Exception {
    try {
       ...
    }
    catch (Exception ex) { ... }
    finally {
       ... // you can check-in your connection here to the pool or do something 
else useful 
    }

  }

  public Pagable getPagable() {
    return contactUs; }

}

Processing Web Form

Looking at the code, you may guess that the ContactUsResource is used for both, showing the form and processing form submission. The reason it's working is that when you request a page with the form with the URL pattern of /contact which is a GET request by default taken care by the public Representation getRepresentation(Variant variant) method (see Recipe 1). When form is submitted, the form action attribute has the same URL pattern of /contact (you will see this below); however, the form method is POST.

To "enable" processing of POST requests in your resources you should override public boolean allowPost() to return true (as we did above). We also need to implement public void handlePost() method that should do processing you want. In my handlePost() method I do essentially three things:

  • Getting values from the form (the way it's done will become clear when you examine ContactUs class below).
  • Saving form data to the back-end (this part is not considered since it has nothing to do with Restlet framework - it's up to you to decide and code your back-end).
  • Doing some post-submission things - I just redirect for simplicity to the home page

To complete the picture, we need to discuss the ContactUs class. Its coding relevant to the Restlet framework is below in the Example 3.

Example 3
public class ContactUs extends AbstractPage {
  private String email;
  private String comments;
  
  .... // getters and settters

  public String getLayout() {...}

  ... // all other methods as required to implement AbstractPage 

  public String getCenterPane() {
    StringBuffer html = new StringBuffer("You may also use the form below to 
submit a comment or ask a question.");
    html.append("<form name=\"contactUs\" method=\"post\" 
action=\"/contact\">");
    html.append("Comments:<br><textarea name=\"comments\" cols=\"55\" 
rows=\"10\"></textarea>");
    html.append("E-mail:<br><input type=\"text\" name=\"email\" 
size=\"55\" value=\"\">");
    html.append("<input type=\"button\" name=\"submitButton\" 
value=\"Submit\" onclick=\"document.forms['contactUs'].submit()\">");
    html.append("</form>");

    return html.toString();
  }


  public void buildFromForm(Form contactUsForm) {
    setEmail(contactUsForm.getFirstValue("email"));
    setComments(contactUsForm.getFirstValue("comments"));
  }

}

The implementation of the public String getCenterPane() is shown simply because I want to render the form in the center pane of the page (this example is built upon previous recipes), and I need to prove you some facts about the form I was talking above. The code builds HTML for the Freemarker template - this HTML will not make the form pretty, but you will get the point.

The core processing takes place in the buildFromForm(Form contactUsForm) called from the handlePost() in the Example 2. The values from the form are received by using getFirstValue() Restlet API in the Restlet Form class. The From instance is obtained by using getEntityAsForm() API of the Restlet Request class.