CPSC 371 Lab, 21 November 2003
Struts

In this lab, you will be modifying a simple web application to make it use Struts. The point is not so much to get the application working but to get some experience with the basic things that you have to do to work with struts.

You will start with a working application that does not use Struts. Copy the file mboard.war from the directory /home/cs371/lab7 into your Tomcat webapps directory. (Note for people working in Windows: You will need several files from this directory. To make it easier for you, you can get the single zip file /home/cs371/lab7.zip and unzip it to get a complete copy of the lab7 directory.)

Start Tomcat to give it a chance to unpack the war file. You should be able to access the web application on your server. The application is a version of the message board that we did in a previous lab. It uses a database instead of files to store the messages, and it does not use users or authentication. Anyone can post a message. The database is on the machine cslab13, so that everyone in the class will be sharing the same set of messages.

The page index.jsp shows all the messages and has a link to another page, post.jsp, that has the form for posting a message. The form data is submitted to another JSP page, process_post.jsp, for processing. (Note that the jsp pages use the database taglib that you saw in the previous lab.)

The goal in the lab is to add Struts functionality to the application, to use Struts custom tags on post.jsp, and to process the data from the form with an Action. Most of the modifications that you will need are already written and are available in /home/cs371/lab7. You will just copy the relevant files and compile the java code. However, you will have to do some work on post.jsp.

At the end of the lab, you should print your modified copy of the file post.jsp and turn it in. If you can, you should show your Struts Web site to me in action. If you have made reasonable progress, you will receive 10 points for the lab, whether the whole site is working or not.


Adding Struts Components

The basic functionality of Struts is contained in a jar file named struts.jar. This file contains the ActionServlet, ActionError, and custom tag classes. These files depend on classes contained in a variety of other jar files. You should copy all the jar files from /home/cs371/lab7/jars into the WEB-INF/lib directory of your mboard application directory.

The Struts custom tags are specified in tld files such as struts-bean.tld and struts-html.tld. You will find these and other Struts tld files in /home/cs371/lab7/tlds. Copy them into the WEB-INF directory. (For this lab, you only really need the bean and html tld's.)

For Struts to function, certain things have to be in the web.xml file (to map URL's ending in ".do" to the ActionServlet, for example). Of course, you also need a struts-config.xml file to say which web addresses are associated with which actions. You can copy these files from /home/cs371/lab7 into the WEB-INF directory in mboard. Take a look at struts-config.xml. You will see that it defines several global forwards, a single action, and a message-resources tag. This action represents the processing that should be done when a new message is submitted.

To process the "postmessage" action, you need an ActionForm class and an Action class. That is, you need Java files that define the subclasses of these classes. The Java files that you need are PostActionForm.java and PostAction.java. You have to make copies of these, compile them, and put the class files in WEB-INF/classes.

Note on compiling the java files: These files refer to classes that are part of Struts, but not part of standard java. The compiler needs access to these classes in order to compile the files. The classes are located in the file struts.jar. This file must be put on the "classpath" that is used by the compiler. One way to do this would be to put struts.jar in the ext/lib directory of the Java SDK. Another way is to add struts.jar to the classpath in the javac command. Assuming that you are working in WEB-INF/classes and that struts.jar is in WEB-INF/lib, you can do this with a command such as:

javac -classpath ../lib/struts.jar:. PostActionForm.java

The "." at the end of the the classpath represents the current directory, which is not automatically searched when you specify a classpath with the "-classpath" option.

(Take a look at the java files. The PostActionForm class contains a property for each input of the form, a reset() method, and a validate() method. The Action class takes the data from the form, representing a message, and adds it to the database. The PostAction class is not in really good MVC style, since it manipulates the "model" directly rather than by calling on other classes that represent the model data, and in case of an error it generates output itself rather than forwarding to an error page in the view component.)

The ActionError class, which is used in the validate() method of PostActionForm.java, requires a properties file to hold the error messages. The properties file is named ApplicationResources.properties. This file must be on the Java classpath, so you should copy it into your WEB-INF/classes directory. If you look at it, you will see that it only defines three error messages.


A Struts Form Page

After you put all the Struts components in place, you will have a Web application that behaves exactly as it did before! This is because the ActionServlet class will only be invoked for a URL that ends in ".do". Unless ActionServlet gets its hands on a request, Struts is not invoked. You must modify post.jsp so that it sends the form data to the ActionServlet.

Open post.jsp in an editor. You will be using the Struts html taglib and maybe the bean taglib, so add the following taglib directives to the top of the page:

            <%@ taglib prefix="html" uri="struts-html" %>
            <%@ taglib prefix="bean" uri="struts-bean" %>

Note the uri's in these directives. They are not file names. These uri's are configured in the web.xml file to refer to the actual file names of the tld's. This is considered good style because it makes your jsp files less dependent on the acutal file locations.

Now, modify the <form> tag to be an <html:form> tag. The action attribute of the tag should be changed from "process_post.jsp" to "ProcessPost.do", which is mapped in struts-config.xml to the message posting action. Don't forget to change the closing </form> tag. Change the input elements in the tag to the corresponding html custom tags. These tags use an attribute named "property" instead of one named "name". For example, the input box for the poster becomes:

           <html:text property="poster" size="40" />

Similarly, the <textarea> tag becomes an <html:textarea> tag.

To get error reporting on the page, you only need to add the line

           <html:errors/>

before the form. This will list all errors at the top of the page. (It is also possible to put the errors next to each input box, but let's keep it easy.)

To make relative URLs work properly when you are forwarding requests all over the place, you have to add a "base" directive to the head of the page. The <html:base/> tag will do this. Add this tag at the end of the <head> of the page, just after the <title>. If you do this consistently on all your pages, you will not have to worry about specifying absolute URLs, which will make your application less transportable if you use them.

If you've done all this correctly, your Struts application should be working. You might need to restart the server to get all the new components loaded. Try it. Try posting a message with one or more of the input boxes left blank. You should be returned to the input page, with an error message at the top. When this happens, any text that you entered into the input boxes will still be there -- this is done automatically by the Struts html custom tags working together with the ActionForm.


Towards Internationalization

You could improve the application by getting the actual English text off the post.jsp page and into the ApplicationResources properties file. If you want to do this, just add some extra lines to the properties file. Each line will represent a piece of text on the page. The line starts with a key such as post.text.headline, followed by a "=" and the value. The key can then be used in a <bean:message> tag on the page, such as:

             <bean:message key="post.text.headline" />

This line would replace the actual text of the headline on the page.

(Of course, you should also internationalize the rest of the application, including index.jsp and PostAction.java. But then, to get a real Struts application, you would have to apply the Struts MVC pattern more thoroughly to these files, before you really begin to think about internationalization.)


David Eck