CPSC 371 Lab, 24 September 2003
Your First Web Application

The purpose of today's lab is to get started on creating your first web application. This is a simple, stripped-down example, and it will not show all the features of the MVC model. However, it will have some of the structure of a real application. The idea is to have a basic "members-only" bulletin board. Users who have logged in with a user name and password will be able to read messages that have been posted on the bulletin board and will be able to post new messages. Each message will have a headline and a body. The application's main page will show a list of all the headlines. Clicking on a headline will go to a page that includes the body of the message.

For this assignment, you will have only a fixed, small list of users. This list can be hard-coded into the program, or it can be read from a file. (If you want to do the extra credit part, you will have to store the list of users in a file.) The messages and their headlines will be stored in files. In a real application, all this information would probably be stored in a database.

Your web application should be finished by next Wednesday, October 1. You should turn in printouts of all your JSP and java source files, and your application should be available for testing on-line on math.hws.edu, as discussed below. You should use at least one servlet in your application.


Tomcat on Math.hws.edu

A copy of the Tomcat server is now running on port 8080 on math.hws.edu. I would like you to deploy your web application on this server so that I can test it easily. I have set up an application directory for each person in the class. The directories are in the directory /home/cs371. The name of your directory is the same as your last name, starting with an uppercase letter. For example, if your last name is Smith, then the directory is named /home/cs371/Smith and the web application is visible on the Web at URL http://math.hws.edu:8080/Smith/. The server is only accessible on the HWS campus network.

You can work on any of the lab computers, but you should work in your directory in /home/cs371. JSP files for the application go in the top-level directory. Any servlets that you write go in the WEB-INF/classes subdirectory.

The "Test" web application on math.hws.edu has a working version of the application you are supposed to write. Try it at http://math.hws.edu:8080/Test/. Use user name fred and password flintstone. You can also try the guessing game that was used as an example in class at http://math.hws.edu:8080/Test/game.jsp.

Note: You still have the option of working on your own copy of the Tomcat server if you like. But if you do this, you must copy the application to the proper directory on the math server when it is finished. Ask for information about how to do this, if you need it. If you work on your own server, you should create a new directory in tomcat's webapps directory. Inside that, make a WEB-INF directory, and in the WEB-INF directory, make a directory named classes. Also make a sub-directory named bbfiles in the WEB-INF directory. The data files for you web application should be in the bbfiles directory.


The Application

Here is some advice about how you might structure your web application:


Using Files

Your program will have to read from files and write to files that contain data for the users' messages. File I/O is not a trivial subject, but fortunately it is easy to read and write entire lines of text. For reading, you should use a BufferedReader. For writing, you should use a PrintWriter. In case you have forgotten how to open files for reading and writing, I give some examples below.

The data files for this project should not be directly visible on the web, so you should store them in a subdirectory of the WEB-INF directory. You should put the files in a directory named bbfiles inside the WEB-INF directory. On math.hws.edu, this directory has already been created for you -- it needs certain special permissions to work properly with the Tomcat server on math.

I suggest using a file named master, to store basic information about all the messages. (I have already created an empty file named master in your bbfiles directory on math.hws.edu. Like the directory, it needs certain permissions to work with the tomcat server.) For each message, there would be four lines in this file containing

The body of each message should be stored in a separate file. You could name the file message.nnn where nnn is the ID number of the message. Thus, the body of the message with ID number 17 would be in the file named message.17. In the end, I decided to redundantly store the headline on the first line of the message file and the posting time on the second line, followed by the message itself. This made it easier to access the headline and time of the message when displaying it in view.jsp.

Here, as an example, is the code for a JSP page that prints out a file named GuessingGameServlet.java from the directory WEB-INF/classes of the web application. One problem is getting the complete name for the file. In the code, this is done using the application.getRealPath("/") method to find the base directory for the web application. Then the relative path to the file is added to the base directory name. You can imitate this in your own code. The parts shown in boldface are the essential elements of finding and reading from a file in a web application directory:

      <%@ page import="java.io.*" %>

      <html>
      <head>
      <title>File Test</title>
      </head>
      <body>
      <h2>Here is the source code for GuessingGameServlet:</h2>
      <hr>

      <pre style="margin-left: 30pt">

      <%
         try {
            String basedir = application.getRealPath("/");
            String filename = basedir + "WEB-INF/classes/GuessingGameServlet.java";
            BufferedReader file = new BufferedReader(new FileReader(filename));
            while (true) {
               String line = file.readLine();  // will be null on end-of-file
	       if (line == null)
	          break;
	       for (int i = 0; i < line.length(); i++) {
	          if (line.charAt(i) == '<')
	             out.print("&lt;");
	          else if (line.charAt(i) == '>')
	             out.print("&gt;");
	          else if (line.charAt(i) == '&')
	             out.print("&amp;");
	          else
	             out.print(line.charAt(i));
	       }
	       out.println();
            }
         }
         catch (IOException e) {
            out.println("Sorry, an error occurred.  Can't access file.");
         }
      %>

      </pre>
      <hr>
      </body>
      </html>

In order to write text to a file, open the file with a line such as

      PrintWriter file = new PrintWriter(new FileWriter(filename));

If the file already exists and you want to write new lines at the end of the file, use the following to open the file:

This must be done inside a try..catch statement, just as in the file reading example above. Use the commands file.print(line) and file.println(line) to write to the file. For writing one of the user's messages to a file, you can use a single println statement to print out the entire contents of the textarea.

      PrintWriter file = new PrintWriter(new FileWriter(filename,true));

Forwarding, Requests, and Sessions

For reference, here is a review of some of the things that you will need in servlets and on JSP pages. A JSP page has pre-defined objects named request and session that can carry information from one page to another. Both objects have methods getAttribute(String) and setAttribute(String,Object) that can be used for storing and retrieving the information. The request object also has getParameter(String), which gets the values of parameters such as form data that were submitted along with the request. When using forwarding, you can use the request object to send information from one page to the next.

To do forwarding in a servlet, use

     getServletContext().getRequestDispatcher("PAGE").forward(request,response);

In a scriptlet on a JSP page, getServletContext() can be replaced by application:

     application.getRequestDispatcher("PAGE").forward(request,response);

It is also possible to do forwarding in the HTML parts of a JSP page. For this, use a forwarding directive:

     <jsp:forward page="PAGE" />

where PAGE is the name of the page, not including the web application name, such as page="/login.jsp".


Extra Credit: Using Style Sheets

For extra credit, you can implement a user preference feature that will allow each user to select one of several different styles for the pages that that user sees. There should be a web page where the user can set his preference. You will have to store the preference information in a file that contains user's names, their passwords, and their preference. The styles will be implemented with cascading style sheets, one sheet for each possible style. The style sheet that is used on a page will be determined by looking at the user's preference. Different styles will use different colors, and might also differ in things like font, background image, and layout (to the extent that it can be controlled by a style sheet).

As an example, this web page uses a cascading style sheet. CSS is a simple language and is easy to learn. You can create your style sheets by copying the one used for this page and making several modified versions of it. The sample style sheet contains comments which should tell you everything you need to know. You can get the style sheet off the web using this link:

http://math.hws.edu/eck/cs371/lab2.css

There is also a copy in the file /home/cs371/CSS-example.css.

To see all the effects of the style sheet, you can look at this page on the web at the address http://math.hws.edu/eck/cs371/lab2.html.


David Eck