First, let's start by digesting some web-technology buzzwords:
Exercise 1:
Which one of these is not an Ecommerce technology buzzword?
Apache, ASP, clientserver, Cookies, Certificates, ColdFusion, CGI,
CSS, DHTML, Forms, Get, HTML, HTTP, Java, Javascript, JSP, NAB, Perl, Post,
Tcl, TCP/IP, SOAP, Spider, Search engine, SSI, SSL, XML.
What is HTML?
HTML creation tools:
Exercise 2:
Learn more about HTML
Demonstrate both pages (but not the form action)
using these instructions.
What is CGI?
Exercise 3:
How does a webserver call a CGI program? Three possible ways:
(e.g., webserver is an Oracle OCI program).
Before this is sent out by the webserver, the code is executed,
which writes "in place".
The HTML actually received by the requesting browser is:
Here is a simple ASP page:
<html> <head> <title> Hello World </title> </head>
<body>
Hello World! (plain HTML text).
<%
Dim str
str = "Hello World (from Visual Basic string)"
Response.write (str)
%>
</body>
</html>
<html> <head> <title> Hello World </title> </head>
<body>
Hello World! (plain HTML text).
Hello World (from Visual Basic string)
</body>
</html>
Exercise 4:
Find a webpage with Javascript or Visual Basic.
Javascript, Visual Basic Script
Use servlets and a servlet-compatible server.
(e.g., http://www.obvious.com/servlets/blah)
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloWorld extends HttpServlet {
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// Set the content type of the response.
resp.setContentType ("text/html");
// Create a PrintWriter to write the response.
java.io.PrintWriter out = new PrintWriter (resp.getOutputStream());
// The first part of the response.
out.println ("<html>");
out.println ("<head><title> Test </title></head>");
out.println ("<body>");
// The greeting.
out.println ("Yo, Hello World!");
// Last part.
out.println ("</body>");
out.println ("</html>");
out.flush();
// Screen I/O
System.out.println ("Inside servlet ... servlet complete");
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doGet (req, resp);
}
}
http://www.yahoo.com/search?music
Here, the text field contains music.
Now let's write Java - a simple servlet that writes "Hello World!" to
the browser: (source file)
Note:
Exercise 5:
Modify the HelloWorld example to print something else and test
it using these instructions.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloWorld extends HttpServlet {
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// Set the content type of the response.
resp.setContentType ("text/html");
// Extract the PrintWriter to write the response.
PrintWriter out = resp.getWriter ();
// The first part of the response.
out.println ("<html>");
out.println ("<head><title> Test </title></head>");
out.println ("<body>");
// The greeting.
out.println ("Yo, Hello World!");
// Last part.
out.println ("</body>");
out.println ("</html>");
out.flush();
// Screen I/O
System.out.println ("Inside servlet ... servlet complete");
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// Default, for now.
doGet (req, resp);
}
}
// Set the content type of the response.
resp.setContentType ("text/html");
out.println ("<html>");
out.println ("<head><title> Test </title></head>");
out.flush();
System.out.println ("Inside servlet ... servlet complete");
Next, let us create an HTML Form, and have a servlet pick up the
Form data entered by the user.
First, an HTML page with a form:
Next, the TestForm.java servlet: (source)
Note:
Exercise 6:
Compile and test the above servlet using your assigned port number
with these instructions.
Exercise 7:
PART I: Change the HTML page by adding the following inside the "body"
<html>
<head><title>Test Post</title>
<body>
<form action="http://rabbit.cs.gwu.edu:9013/servlets/TestForm" method="post">
Enter a string: <input type="text" name="param1">
And then press "Go": <input type="submit" value="Go">
</form>
</body>
</html>
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class TestForm extends HttpServlet {
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// Set the content type of the response.
resp.setContentType ("text/html");
// Extract the PrintWriter to write the response.
PrintWriter out = resp.getWriter ();
// The first part of the response.
out.println ("<html>");
out.println ("<head><title> Test </title></head>");
out.println ("<body>");
// Now get the parameters and output them back.
out.println ("Request parameters: ");
Enumeration e = req.getParameterNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = req.getParameter (name);
if (value != null)
out.println ("<li> name=[" + name + "] value=[" + value + "]");
else
out.println ("<li> name=[" + name + "] did not have a value");
}
// Last part.
out.println ("</body>");
out.println ("</html>");
out.flush ();
}
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doPost (req, resp);
}
}
Enumeration e = req.getParameterNames();
Enter a string: <input type="text" name="param1">
String whatTheUserTyped = req.getParameter ("param1");
<input type="hidden" name="hidden1" value="hiddenvalue1">
Use the same servlet as above (TestForm.java) as the form
action. You should see the hidden parameter.
PART II: log in to any web-based system where you have an
account, and examine the page sources to see whether there are hidden
parameters.
Important observations about HTTP and webservers:
Using hidden parameters to maintain user information in webpages:
For example, suppose this is the login page:
After logging in, the user sees:
Upon clicking on "Fortune", say, the result is something like:
Note:
Let us build this application step by step:



http://rabbit.cs.gwu.edu:9003/servlets/examples/TestLogin
<html>
<head><title>Test Login</title>
<body>
<form action="http://rabbit.cs.gwu.edu:9003/servlets/examples/TestLogin" method="post">
Enter username: <input type="text" name="username">
<input type="submit" value="login">
<input type="hidden" name="page" value="loginpage">
</form>
</body>
</html>
public class TestLogin extends HttpServlet {
static final boolean debug = false;
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// Set the content type of the response.
resp.setContentType ("text/html");
// Extract the PrintWriter to write the response.
PrintWriter out = resp.getWriter ();
// The first part of the response.
out.println ("<html>");
out.println ("<head><title> Test Login</title></head>");
out.println ("<body>");
// Write out the action, since that's common to all.
out.println ("<form action=\"http://rabbit.cs.gwu.edu:9003/servlets/examples/TestLogin\" method=\"post\">");
// Get the page info from hidden fields:
String whichPage = req.getParameter ("page");
String userName = req.getParameter ("username");
if (debug) {
// During debugging, it helps to print out the parameters in the response.
printParams (out, req);
}
// Determine action based on which page fired the request.
if (whichPage.equalsIgnoreCase ("loginpage")) {
handleLoginPage (out, userName);
}
else if (whichPage.equalsIgnoreCase ("menupage")) {
handleMenuPage (out, userName, req);
}
else {
handleError (out);
}
// End the form.
out.println ("</form>");
// Last part.
out.println ("</body>");
out.println ("</html>");
out.flush();
// Screen I/O
System.out.println ("Inside servlet ... servlet complete");
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// We need to implement POST because the forms are written as such.
doGet (req, resp);
}
void handleLoginPage (PrintWriter out, String userName)
{
out.println ("Hello " + userName + "! Choose from these options: ");
// The two buttons.
out.println ("<input type=\"submit\" name=\"Time\" value=\"Time\">");
out.println ("<input type=\"submit\" name=\"Fortune\" value=\"Fortune\">");
// Write out the extracted username:
out.println ("<input type=\"hidden\" name=\"username\" value=\"" + userName + "\">");
out.println ("<input type=\"hidden\" name=\"page\" value=\"menupage\">");
}
void handleMenuPage (PrintWriter out, String userName, HttpServletRequest req)
{
// Check which button was pressed:
String timeButtonPressed = req.getParameter ("Time");
out.println (userName + ", ");
if (timeButtonPressed != null) {
// Time event.
Date d = new Date ();
out.println ("the date/time is: " + d + ".");
}
else {
// Fortune event.
String fortune = "";
if ( (int)userName.charAt(0) % 2 == 0) {
fortune = "go out, meet people. Tomorrow is going to be great for you.";
}
else {
fortune = "stay at home. Tomorrow is going to be a lousy day for you.";
}
out.println (fortune);
}
}
void handleError (PrintWriter out)
{
out.println ("Enter username: <input type=\"text\" name=\"username\">");
out.println ("<input type=\"submit\" value=\"login\">");
out.println ("<input type=\"hidden\" name=\"page\" value=\"loginpage\">");
}
// For debugging:
void printParams (PrintWriter out, HttpServletRequest req)
{
out.println ("<p><hr><p> Request parameters: <ul>");
Enumeration e = req.getParameterNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = req.getParameter (name);
if (value != null)
out.println ("<li> name=[" + name + "] value=[" + value + "]");
else
out.println ("<li> name=[" + name + "] did not have a value");
}
out.println ("</ul><hr>");
}
}
<html>
<head><title> Test Login</title></head>
<body>
<form action="http://rabbit.cs.gwu.edu:9003/servlets/examples/TestLogin" method="post">
Hello Morpheus! Choose from these options:
<input type="submit" name="Time" value="Time">
<input type="submit" name="Fortune" value="Fortune">
<input type="hidden" name="username" value="Morpheus">
<input type="hidden" name="page" value="menupage">
</form>
</body>
</html>
We will use this example to illustrate session tracking:
Note that we've added a "back" button to go back to the menu page.
Exercise 8:
Run the above servlet. Make sure you use your assigned port number.
Use two browsers to simultaneously login with the same username.
Alternate between them. What do you notice?
About session tracking:
Let's modify the servlet to handle "page counts" using server-side
session tracking:
Some improvements:
Next, let's examine the code:
(source file)



public class PageCount extends HttpServlet {
static final boolean debug = false;
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...
// Extract page count:
String pageCountStr = req.getParameter ("pagecount");
int pageCount = -1;
try {
pageCount = Integer.parseInt (pageCountStr.trim());
}
catch (NumberFormatException e) {
// Handle exception ...
}
pageCount ++;
// Write out hidden field:
out.println ("<input type=\"hidden\" name=\"pagecount\" value=\"" + pageCount + "\">");
// Write out page count message:
out.println ("<br> <font color=\"#FF0000\">You have made " + pageCount + " page requests</font>");
// ...
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// We need to implement POST because the forms are written as such.
doGet (req, resp);
}
// ... (as before) ...
}
Note:
<html>
<head><title>Test Login</title>
<body>
<form action="http://rabbit.cs.gwu.edu:9003/servlets/examples/PageCount" method="post">
Enter username: <input type="text" name="username">
<input type="submit" value="login">
<input type="hidden" name="page" value="loginpage">
<input type="hidden" name="pagecount" value="0">
</form>
</body>
</html>
Here's the program
(source file)
public class SessionPageCount extends HttpServlet {
// Store session info (page count) by username in hashtable.
Hashtable sessionTable = new Hashtable ();
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...
// Check if session exists:
Integer pageCount = (Integer) sessionTable.get (userName);
if (pageCount == null) {
// Create a new page count.
pageCount = new Integer (0);
}
pageCount = new Integer (1 + pageCount.intValue());
sessionTable.put (userName, pageCount);
out.println ("<br> <font color=\"#FF0000\">You have made " + pageCount + " page requests</font>");
// We don't really need this, but we'll use it for confirmation:
out.println ("<input type=\"hidden\" name=\"pagecount\" value=\"" + pageCount + "\">");
// ...
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// We need to implement POST because the forms are written as such.
doGet (req, resp);
}
// ...
}
The program:
(source file)
(In this case, it's the page count, and the start-time of the session).
// An instance of this for each user:
class SessionInfo {
int pageCount; // We'll now put the counter here.
long startTime; // For timeout's.
}
public class SessionPageCount2 extends HttpServlet {
// Store session info (page count) by username in hashtable.
Hashtable sessionTable = new Hashtable ();
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...
// Get the page info from hidden fields:
String whichPage = req.getParameter ("page");
String userName = req.getParameter ("username");
// First extract session info.
SessionInfo session = (SessionInfo) sessionTable.get (userName);
// Check if inactive session.
if (session != null) {
long minutesSince = (System.currentTimeMillis() - session.startTime) / (1000*60);
// See if user has been inactive for more than 1 minute.
if (minutesSince >= 1) {
out.println ("Session timed out. Please login again.");
out.println ("</form></body></html>");
out.flush ();
return;
}
}
else {
// Make session.
session = new SessionInfo ();
session.pageCount = 0;
session.startTime = System.currentTimeMillis ();
}
// Active session. Continue ...
// Determine action based on which page fired the request.
if (whichPage.equalsIgnoreCase ("loginpage")) {
handleLoginPage (out, userName);
}
else if (whichPage.equalsIgnoreCase ("menupage")) {
handleMenuPage (out, userName, req);
}
else if (whichPage.equalsIgnoreCase ("featurepage")) {
// Back button on Time or Fortune page
handleLoginPage (out, userName);
}
else {
handleError (out);
}
// Page count.
session.pageCount ++;
// Put updated page count back in table, and write out to page:
sessionTable.put (userName, session);
out.println ("<br> <font color=\"#FF0000\">You have made " + session.pageCount + " page requests</font>");
// We don't really need this, but we'll use it for confirmation:
out.println ("<input type=\"hidden\" name=\"pagecount\" value=\"" + session.pageCount + "\">");
// ...
}
public void doPost (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// We need to implement POST because the forms are written as such.
doGet (req, resp);
}
// ...
}
What is persistence?
As an example, let us make the "page counts" persistent for users:
The topic of session tracking is complex:
Here's the program:
(source file)
// Use an instance of this class for each user.
class SessionInfo {
int pageCount; // Number of pages accessed.
long startTime; // Time at which session started in milliseconds.
}
public class SessionPageCount3 extends HttpServlet {
// Store session info (page count) by username in hashtable.
Hashtable sessionTable = new Hashtable ();
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...
String userName = req.getParameter ("username");
// First extract session info.
SessionInfo session = (SessionInfo) sessionTable.get (userName);
// Check if inactive session.
if (session != null) {
long minutesSince = (System.currentTimeMillis() - session.startTime) / (1000*60);
if (minutesSince >= 1) {
out.println ("Session timed out. Please login again.");
out.println ("</form></body></html>");
out.flush ();
return;
}
}
else {
// Make session.
session = new SessionInfo ();
// Get current page count, if it exists, from file.
File f = new File (userName);
if (! f.exists()) {
// Create one and write zero.
f.createNewFile ();
PrintWriter pw = new PrintWriter (new FileWriter(f));
pw.println (0);
pw.close ();
}
// Read from file.
LineNumberReader lnr = new LineNumberReader (new FileReader (f));
String pageCountStr = lnr.readLine ();
try {
session.pageCount = Integer.parseInt (pageCountStr.trim());
}
catch (NumberFormatException e) {
session.pageCount = 0;
}
lnr.close ();
// Record the start of the session.
session.startTime = System.currentTimeMillis ();
}
// Active session. Continue ...
// ... (some code not shown) ...
// Page count stuff.
session.pageCount ++;
sessionTable.put (userName, session);
out.println ("<br> <font color=\"#FF0000\">You have made " + session.pageCount + " page requests</font> in your lifetime");
// Write current count to file:
File outFile = new File (userName);
outFile.delete ();
PrintWriter pw = new PrintWriter (new FileWriter (userName));
pw.println (session.pageCount);
pw.close ();
// ...
}
// ...
}
Consider this example:
");
out.println ("Hello " + userName + "! Choose from these options: ");
// ...
}
}
Exercise 9:
Run the above servlet. Make sure you use your assigned port number.
Use two browsers to simultaneously login with two different
usernames, the first one should start with "M" and the second
one should NOT. Login first with the "M" name, and immediately
afterwards, login with the second.
Explain the result.
Here's the program:
public class VisitorCount extends HttpServlet {
// Count the total number of users:
int numLogins = 0;
public void doGet (HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ... as before ...
}
// ...
void handleLoginPage (PrintWriter out, String userName)
{
// Login count.
// Deliberately slow it down for users that start with "M".
if (userName.startsWith ("M")) {
try {
Thread.sleep (5000);
}
catch (InterruptedException e) {
// Handle exception ...
}
}
numLogins ++;
out.println ("Number of people who logged in before you: " + numLogins + "