Processing forms using scheme

Required Reading


A servlet is a program that runs on a web server and which dynamically generates webpages. It often will use data submitted by the user on HTML forms to generate the new webpage, and it may also access a database and/or send email while storing the data. All of the servlets we will examine in this class have a URL of the following form: where the extension "sxml" tells the server that this is a servlet.

Forms and parameters

Here are some examples of simple servlets, together with the html code for invoking them:

SXML: a language for writing servlets

In this class, we will use the SXML dialect of Scheme to create servlets. The simplest form of such a program will be the following
(let ((v1 (param request "name1")) (v2 (param request "name2")) ... (vn (param request "namen")) ) <xml> <html <head> <title> ...</title></head> <body> ...regular html code <scheme>v3</scheme> .... <scheme>v2</scheme> ... </body> </html> </xml> )
In this program the form data is first read and stored in the variables v1, v2, ..., vn. Then then HTML below is generated and the form data is inserted into the HTML by the vi expressions.

In general, you can have any scheme expression inside the scheme tags. A common idiom is to have some scheme code use a test to decide which bit of xml to insert. For example the following program generates two different pages depending on whether the correct password was entered.

(let ((pw (param request "passwd")) ) <xml> <html <head> <title>Password test</title></head> <body> <h1>Password test</h1> <scheme> (if (equal? pw 'john34mary) <xml>You know the password, please go <a href="">here</a> for more info</xml> <xml>Sorry, go ask the teacher for the password!</xml> ) </scheme> </body> </html> </xml> )
It could be called from a page of the form:
<html <head> <title>Password test</title></head> <body> <h1>Password test</h1> <form method=post action=pw.sxml> Enter the password <input type=password name=passwd size=20> <p> <input type=submit> </form> </body> </html>

By default if the form data consists of several words, (param expr "zzz"), will return only the first "word". If you want the entire text as a quoted string, you can use

  (.getParameter request "zzz")
Similarly, some form elements allow you to select multiple data items. By default (param request "zzz") only returns the first. If you want all of them you can use:
  (.getParametervalues request "zzz")

Example from class

In class we developed a single fairly complex example: form1.html. The HTML for the page gets the user's name, age, favorite color, and password and sends it to the "demoB.sxml" page for processing.

<html><body bgcolor=lightgreen> <form method=post action="demoB.sxml"> <ul> <li> Name: <input type=text name="who"> </li> <li> Age: <input type=text name="age"> </li> <li> Favorite color: <select name="favcol"> <option> red </option> <option> lightgreen </option> <option> blue </option> <option> yellow </option> </select> <li> Password: <input type=password name="pw"> </li> </ul> <input type=submit> </form> </body> </html>

This servlet page demoB.sxml. then

  1. reads the four input parameters (and converts the "age" parameter to a decimal number).
  2. checks to see if the password is "seven!", and if the password is wrong, it generates an error page
  3. if the password is "seven!", it as follows:
    (let ( (thecolor (.getParameter request "favcol")) (person (.getParameter request "who")) (age (Double. (.getParameter request "age"))) (pw (.getParameter request "pw")) ) (if (not(equal? pw "seven!")) <xml> <html><body bgcolor=black text=red> <h1>WRONG WRONG WRONG</h1></body></html> </xml> <xml> <html> <body bgcolor= <scheme>thecolor</scheme> > Hello, your name is <font color=red> <scheme>person</scheme></font> and your age is<font color=blue> <scheme>age</scheme> </font> <br> Your age is <scheme> (/ (* age 365 24 60 60) 1000000.0) </scheme> million seconds. See you. </body> </html> </xml> ) )