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 IlynAfter 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
ContactUsclass 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.