CS2a/Spr09: Introduction to Computers
Scheme Servlets

In this section, we explain how to develop interactive web pages. These pages will typically prompt the user for some information (using a web form or a hyperlink) and then will generate a new web page, based on the user input. They may also perform other actions such as read/writing information on the servers disk, sending email, or accssing a database.

The language we use to specify these interactive web pages is a simple combination of Scheme, HTML, and CSS. For most of the examples in this section, the scheme will be used in relatively simple ways and hence you will not need to know much about the language itself beyond the few examples we demonstrate below. In Chapter ??, we will give a full introduction to Scheme and you can then use that to build even more complex servlets.

Dynamic Content and Scheme Servlets

The key idea behind servlets is that they provide a way to generate dynamic webpages, that is webpages in which the HTML is different each time someone visits it. Servlets can be specified in many different languages. In this book, we will look closely at servlets specified in Scheme.

To run these servlets you will need to have access to a server which has a Scheme webapp. The appendix explains how to download and install such a server. If someone can provide you access to a Scheme server then you will not need to download and install the server yourself.

Once you have access to a server, you create a scheme servlet simply by creating a file in the "webapp" folder and adding the suffix ".servlet" to the file name. When someone tries to view that file, the server will read the code that you have written in the ".servlet" file and will use that code to generate a new webpage which is then sent back to the user.

Let us now consider a few simple examples of Scheme servlets. These examples are not very useful by themselves but they allow us to explore the "idea" of Scheme servlets in a simpler context. The first example is the following program which date.servlet (run or (view) simply returns the date:

; date.servlet -- returns the current time and date ; lines beginning with a semicolon are comments (Date.)

The first two lines are comments (as they begin with a semicolon) and so are ignored by Scheme. The second line is a Scheme expression which returns the current local date and time

Actually, (Date.) returns a "Date" object representing the current time and date. This Date object is turned into a string representing the date in the local dialect.

To view this servlet, one must visit the URL:

http://MY.DOMAIN.EDU:8080/scheme/date.servlet where MY.DOMAIN.EDU is the domain name of the scheme server you are using. If you have installed a Scheme server on your home computer, then you can use the IP address of your home computer in place of MY.DOMAIN.EDU or you can use the "self-loop" IP address 127.0.0.1 which always refers to the computer itself. Visiting this address with a standard browser will bring you to page that contains the current time and date: Sun Jan 20 07:46:44 EST 2002 The expression (Date.) is an example of a Scheme expression. It is an invocation of the Date. procedure with no arguments.

Arithmetic Expressions in Scheme

Another simple example of a servlet is the following which we assume is stored in a file named sumToTen.servlet:

; sumToTen.servlet -- this returns the sum of 1 to 10 (+ 1 2 3 4 5 6 7 8 9 10) When one visits this servlet with a browser, the server evaluates this expression and applies the addition operator + to the arguments that follow it in the parenthesized list. The result that is return to the browser is the number 55 In a way the scheme server can be viewed as a calculator, where you put the expression you want to compute into a file and when you view the file with a browser it will evaluate that expression and return your answer. A slightly more complex example is the following: ; hypotenuse34.servlet -- this returns the length ; of the hypotenuse of a right triangle who other sides ; have length 3 and 4 (sqrt (+ (* 3 3) (* 4 4))) This servlet contains a more complex scheme expression with four operators (two multiplication operators "*", one addition "+", and one square root "sqrt"). The Scheme server evaluates such an expression by first evaluating the innermost expressions (* 3 3) and (* 4 4) to get 9 and 16 respectively. These values are subsituted back into the expression to yield the simpler expression: (sqrt (+ 9 16)) Next the sum is evaluated to yield 25 which is substituted back into the expression to get: (sqrt 25) which evaluates to 5.0 and this is sent back to the browser.

Scheme provides a large set of arithmetic operators including the following

(+ a b ... c) addition (- a b) subtraction (* a b ... c) multiplication (/ a b) division (sqrt a) square root (exp a) exponential function (log a) natural logarithm (sin a) sine (in radians) (cos a) cosine (in radians) (tan a) tangent (in radians) (asin a) arcsin (acos a) arccosine (atan a) arctangent (round a) rounds to the nearest integer (expt a b) raise a to the b power

EXERCISE: What is the result of evaluating the following Scheme expressions: (* 1 2 3 4 5) (+ 5 (* 3 (+ 6 (* 7 2)))) (+ (* 1 1) (* 2 2) (* 3 3) (* 4 4) (* 5 5))

Interacting with HTTP headers

Another example of a servlet is the following which sends back a message to the browser (using the HTTP protocol) telling it to visit another page instead:

(.sendRedirect response "http://www.nsf.gov") Visiting this page in a browser will bring you directly to the web page of the National Science Foundation. In this example, the scheme expression that is evaluated has an operator .sendRedirect and two operands: response and "http://www.nsf.gov". The first operand is a special one that refers to the page that is sent back to the browser. The second operator is a string of characters which is indicated by the enclosing double quotes. There are two other "special" symbols used by the scheme server: request and httpservlet. The request symbol can be used to get information about the current request. For example, the IP address of the browser that is visiting the current page can be returned using the following servlet: ; yourURL.servlet (.getRemoteAddr request) Visiting this page with your browser will return your current IP address. If you are running the server on your own machine, it will probably return the "loop back" IP address: 127.0.0.1 You should try the examples in this section with your own server and browser.

EXERCISE: Try out servlets that report on the client's CPU and operating system using the Scheme call (.getHeader request "User-Agent")

Quasi-strings

The simplest type of useful servlet is one which just returns the same HTML each time to the user. These servlets are written as standard HTML files except that the file name must end in ".servlet" and the HTML ust be enclosed in a pair of curly braces as shown below:

{ <html><head><title>Simple servlet</title></head> <body> <h1> This is a simple servlet</h1> it has no dynamic content! </body> </html> } A slightly more interesting servlet is one that displays the current local time. This is done by including the text [(Date.)] at the point in the web page where you want the current time and date to appear. ; date.servlet -- this returns a page with the date/time { <html> <head><title>Current Time and Date</title></head> <body> The current local time and date is <br> [(Date.)] <br> (This page is powered by Scheme servlets!) </body> </html> } The square braces ``[`` and ``]'' in the date.servlet servlet tell the server that the element they enclose is a Scheme expression that should be run to get its value. That value is then inserted directly into the page. Returning to the date.servlet example, if you then visit the URL http://SERVER.DOMAIN:8080/scheme/date.servlet you will get a web page that contains the following text: The current local time and date is Sun Jan 20 07:46:44 EST 2002 (This page is powered by Scheme servlets!) Clearly, one can create a more interesting page by using CSS and more HTML markup.

EXERCISE: Modify the date.servlet example above to include more sophisticated HTML and CSS, then visit the page and hit the refresh button several times. You should notice that the time changes each time you hit the refresh button.
EXERCISE: Write a servlet that displays a random number using [(Math.random)] This scheme expression generates a random decimal number between 0.0 and 1.0. If you want a whole number between say 0 and 100, then you can use the following expression instead: [(round (* 100 (Math.random)))] By multiplying the random number by 100, we get a decimal number between 0.0 and 100.0. The round operator then rounds that number to the nearest whole number in the range 0 to 100.
EXERCISE: What is the result of evaluating the following Scheme expressions: { 3 + 4 = [(+ 3 4)] } { [(* 3 3)] - [(+ 2 5)] = [(/ 4 2)] } { A day contains [(* 24 60 60)] seconds!}

As mentioned above, the curly braces in a servlet {} indicate that the enclosed text is to be sent verbatim to the client, except that text enclosed in square braces [] is first evaluated to get some "interesting" value which is then inserted into the text. This curly brace/square brace notation is called quasi-string notation. It is another example of a Scheme expression.

Strong Quasi-strings

Note that if you want to include any curly braces or square brackets in your webpage you have to put backslashes in front of them. The backslash indicates that the following character is to be viewed as just a character. { <html><head><title>Simple servlet</title></head> <body> The current local time and date is <br> [(Date.)] and because we're using the usual quasi-string notation we need to quote (or escape) curly braces and brackets like this \{ and this \} and \[ this and \] this </body> </html> } An alternative approach is to use the "strong quasi-string" syntax in which you enclose your text with curly braces and number signs as follows: #{....}#. You also use number signs to flag the curly braces for escapes into dynamic code, like #[...]# this. If you use this syntax, then you don't have to quote the curly braces inside the string. #{ <html><head><title>Simple servlet</title></head> <body> The current local time and date is <br> #[(Date.)]# and because of the strong quasi-string notation we can write curly braces (like this { and this }) as well as square brackets (like this [ and this ]) without quoting them using back slashes. </body> </html> ]# We will alternate between the "strong" syntax and the usual syntax. The strong syntax is useful when generating CSS and other text containing lots of curly braces and parentheses. The other notation is better for little examples.

Quasi-strings and string-append

The general form of a quasi-string expression is as follows:

{...text...[A]..... ...text...[B]..... .... ...text...[C].....} while the strong quasi-strings have the form: #{...text...#[A]#..... ...text...#[B]#..... .... ...text...#[C]#.....}# The rule for evaluating such an expression is to first evaluate the embedded Scheme expressions A, B, ..., C, and then to insert the values one obtains in the corresponding places in the string. There is a Scheme function string-append which can be used to achieve a similar effect, e.g. instead of writing: {the sum of 5 and 7 is [(+ 5 7)] the difference is [(- 5 7)]} one could write (string-append {the sum of 5 and 7 is } (+ 5 7) { the difference is } (- 5 7) ) both of these return the string "the sum of 5 and 7 is 12 the difference is -2" Thus, the quasi-string notation is just a short-hand for the string-append expression.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License