Scheme Servlets: Counters, Logs, and Email

Required Reading

Loading the library

To use the capabilities described in this section, you need to have your sxml servlet load in the "schemelib/" library. This is done by writing your servlet in the following form:
(begin (load "schemelib/") (let ( (var1 (.getParameter request "var1")) ... ) ... ) )


Our first example, is a simple servlet that asks the user a question and then email them an acknowledgement:

(begin "This is the mail_test.sxml servlet" (load "schemelib/") (let ( (email (.getParameter request "email")) (opsys (.getParameter request "opsys")) ) (if (equal? email #null) <xml> <html><head><title>Mail demo</title></head> <body bgcolor=lightgreen> <h1>Mail demo</h1> <form method=post action="mail_test.sxml"> Enter your email address: <input type=text name=email><br> Select your favorite type of operating system: <select name="opsys"> <option>windows</option> <option>mac</option> <option>linux</option> </select><br> <input type=submit value="vote"> </form> </body></html></xml> (begin (send-mail request email "" "servlet mail test" <xml> Thanks for visiting the servlet mail test page on <scheme>(Date.)</scheme> and voting for <scheme>opsys</scheme> </xml>) <xml> <html> <head><title>Test</title></head> <body bgcolor=lightgreen> <h1> Mail has been sent to <scheme>email</scheme></h1> Thanks. </body> </html> </xml> ) )))
Observe that the servlet first loads in the library. Then it reads the "email" parameter. If that parameter is #null (e.g. the user did not fill out the form), then the servlet will generate a form asking for an email address and asking a question about operating systems. If "email" is not #null, then the servlet does two things. First it sends mail to the given address from "" with the subject "servlet mail test". The text of the email message contains both the date and their vote. In general the format for the send-mail command is
(send-mail request ;; this is mandatory TO ;; email address of recipient FROM ;; your email address SUBJECT ;; subject of the message TEXT ;; body of the message )
Please don't abuse this feature by sending unwanted email.

Implementing a counter

To implement a counter we need to use two of the library procedures
  (read-from-file httpservlet request "NAME-OF-FILE" INITIAL-VALUE)
  (write-to-file  httpservlet request "NAME-OF-FILE" VALUE-TO-WRITE)
The following example shows a simple servlet that does nothing but count hits.
(begin (load "schemelib/") (let ( (count (read-from-file httpservlet request "count" 0)) ) (write-to-file httpservlet request "count" (+ 1 count)) <xml> <html> <head><title>Test</title></head> <body bgcolor=lightgreen> <h1> This page has been visited <scheme>count</scheme> times </h1> </body> </html> </xml> ))

Implementing a log

Next we show how to take information from the webpage form and store it in a file in your folder on the server. This again uses the "schemelib/" library
(begin (load "schemelib/") (let ( (data (read-string-from-file httpservlet request "mylogfile" "no log yet")) ) (append-to-file httpservlet request "mylogfile" (list (Date.) (.getRemoteHost request) )) <xml> <html> <head><title>Test</title></head> <body bgcolor=lightgreen> <h1> The log of browsers visiting the page is shown below <pre><scheme>data</scheme> </pre> The current local time is <scheme>(Date.)</scheme> </h1> </body> </html> </xml> ))

The key procedures here are

(read-string httpservlet request LOGFILENAME INITIAL_VALUE)
This reads in the logfile as a big string assuming it is stored in your folder in a file named YOURSERVLET_LOGIFILENAME.

(append-to-file httpservlet request LOGFILENAME VALUE_TO_APPEND)
This adds the "VALUE_TO_APPEND" to the logfile with the specified name.