Home

MassLight presents

Chapter 5. Advanced Struts

Conditional Logic, Looping, Headers, and Cookies

Goals After completing this chapter, the student will be able to
  • use the conditional tags from the Struts framework.
  • use the iterate tag from the Struts framework.
  • handle HTTP headers using Struts.
  • handle cookies with Struts and with the response object.
Prerequisites In order to complete this chapter successfully, the student must have
  • an understanding of the request-response cycle.
  • an understanding of cookies.
  • a basic understanding of Struts.
  • a basic understanding of beans and tags.
Objectives This chapter is presented in order to provide the student with information about the logic, cookie, and header tags of Struts.

Conditional tags

The logic:present tag

The logic:present tag checks to see if something exists. If it does exist, then the body of the logic:present tag is executed, otherwise the body of the logic:present tag is ignored entirely. It's one big fancy if statement.

logic:notPresent does the opposite, but works the same way (and has the same attributes) as the logic:notPresent tag.

logic:present most commonly checks for the presence of a cookie, a header, or a bean using the cookie, header, or name attributes. Remember that an attribute in a scope is considered a bean, so the presence of an attribute may be checked using logic:present, as well.
 

<logic:present name="person"> 
<bean:write name="person" property="firstName"/>
...
...
</logic:present> 

Attributes of the logic:present tag

value 
property
cookie Checks for the presence of a cookie with the specified name
header Checks for the presence of a header with the specified name
name Checks for the presence of a bean with the specified name
parameter Checks for an instance of at least one parameter from the request
property Checks for the presence of a non-null property of the bean with the name specified in the name property 
role Checks to see if the currently authenticated user has the specified security role
scope  Specifies the scope of where to find the bean
user Checks to see if the currently authenticated user has the specified name

Using comparison tags

Comparison tags allow two arguments to be compared; if the comparison evaluates to be true, then the content contained in the tag will be executed. Comparison tags can be equal, notEqual, greaterEqual, lessEqual,lessThan, or greaterThan. Later in this chapter, the ConditionalStruts example will show how to use these more fully.

Attributes of comparison tags

value value to be compared to a value from the cookie, header, parameter, property or name property - required
cookie name of cookie to compare to the value property
header the name of the HTTP header to compare to the value property
name the name of the bean whose value will be compared to the value property - if the property attribute is also specified, then the value of the property attribute will be compared to the value property 
parameter the name of the request parameter to compare to the value property
property the property of the bean to compare to the value property - if this attribute is used then the name attribute must be used as well
scope the scope within which to search for the bean specified by name

ConditionalStruts: using conditional tags in Struts

This example demonstrates the use of the conditionals tags from the Struts framework. The example is an application where the user must guess a number. We will use Struts tags to implement conditional logic in the JSP to test whether the number is correct, too high, or too low.

We will build on the example from the previous chapter, which asked for a name and then displayed the name to the user. Note how little has to change: only index.jsp (to add the conditional logic), ApplicationResources.properties (to change the labels displayed to the user), and build.xml (to deploy the application under a different name). Everything else remains the same.

So, we will be reusing most of our code from the previous chapter, and only changing what we need to, which is very little.

(If you have not already done so, you can download this and other examples used in this course. Mac OS X or other UNIX users click here instead.)

Do this:

  1. Duplicate the entire directory of the SimpleStruts example from the previous chapter. Rename it to ConditionalStruts. Your directory structure should look very familiar:
code/Chapter5/ConditionalStruts
ConditionalStruts
  |
  +-- index.jsp (*)
  |
  +-- build.xml (*)
  |
  +-- WEB-INF
        |
        +-- web.xml (*)
        |
        +-- struts-config.xml (*)
        |
        +-- app.tld (*)
        |
        +-- struts-bean.tld (*)
        |
        +-- struts-form.tld (*)
        |
        +-- struts-html.tld (*)
        |
        +-- struts-logic.tld (*)
        |
        +-- struts-template.tld (*)
        |
        +-- struts.tld (*)
        |
        +-- classes
        |     |
        |     +-- com
        |           |
        |           +-- masslight
        |                 |
        |                 +-- strutsExampleClasses
        |                       |
        |                       +-- ApplicationResources.properties (*)
        |                       |
        |                       +-- NameForm.java (*)
        |                       |
        |                       +-- Name.java (*)
        |                       |
        |                       +-- SetNameAction.java (*)
        |
        +-- lib
              |
              +-- struts.jar (*)

(*) denotes a file

  1. Change the JSP file to include our new conditional logic:
code/Chapter5/ConditionalStruts/index.jsp
<%@ page language="java" %> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> 
<html:html> 
  <head> 
    <title> 
      <bean:message key="welcome.title"/> 
    </title> 
    <html:base/> 
  </head> 
  <body> 

    <!-- This will set the number to be guessed -->
    <bean:define id="theNumber" value="7"/> 

    <html:errors/> 
    <html:form action="/setName"> 
        <html:hidden property="action"/> 
        <bean:message key="prompt.name"/> 
        <html:text property="name" size="16" maxlength="16"/> 
        <br></br> 
        <html:submit> 
          <bean:message key="button.save"/> 
        </html:submit> 
        <html:reset> 
          <bean:message key="button.reset"/> 
        </html:reset> 
    </html:form> 
    <hr></hr> 
    <logic:present name="name"> 

        <bean:write name="name" property="name"/>
        <br></br>

        <!-- Equal To -->
        <logic:equal name="name" property="name" value="<%= theNumber %>" >
         <bean:message key="result.correct"/>
        </logic:equal>

        <logic:notEqual  name="name" property="name" value="<%= theNumber %>">
          <!-- Less Than -->
          <logic:lessThan name="name" property="name" value="<%= theNumber %>" >
            <bean:message key="result.lessThan"/>
          </logic:lessThan>
          <!-- Greater Than -->
          <logic:greaterThan name="name" property="name" value="<%= theNumber %>" >
            <bean:message key="result.greaterThan"/>
          </logic:greaterThan>
        </logic:notEqual>
        <hr></hr> 
     </logic:present> 
  </body> 
</html:html>

  1. Change the labels in the properties file, and add the new messages we'll need for this application:
code/Chapter5/ConditionalStruts/WEB-INF/classes/com/masslight/strutsExampleClasses/ApplicationResources.properties
button.save=Guess the number 
button.reset=Reset 
error.name.required=To guess the number, a number must be entered 
prompt.name=Enter number: 
welcome.title=Number Guesser
result.correct=WOOHOO - ROCK ON!
result.lessThan=A little higher
result.greaterThan=A little lower

  1. Change the project name and the .war file name in the Ant build script; everything else is unchanged.
code/Chapter5/ConditionalStruts/build.xml
<project name="ConditionalStruts" default="dist" basedir=".">

 <!-- set global properties for this build -->
 <property environment="env"/>
 <property name="top" value="."/>
 <property name="src" value="."/>
 <property name="build" value="build"/>
 <property name="dist" value="dist"/>
 <property name="war_dir" value="${dist}/lib"/>
 <property name="war_file" value="${war_dir}/ConditionalStruts.war"/>

 <property name="webinf" value="${top}/WEB-INF"/>
 <property name="web.xml" value="${webinf}/web.xml"/>
 <property name="classes" value="${webinf}/classes"/>
 <property name="lib" value="${top}/WEB-INF/lib"/>
 <property name="struts.jar" value="${env.STRUTS_HOME}/lib/struts.jar"/>
 <property name="servlet.jar" value="${env.TOMCAT_HOME}/lib/servlet.jar"/>
 <property name="deploy" value="${env.JBOSS_HOME}/deploy"/>

 <target name="clean">
   <!-- Delete our the ${build} and ${dist} directory trees -->
   <delete dir="${build}"/>
   <delete dir="${dist}"/>
   <delete dir="${war_dir}"/>
 </target>

 <target name="init">
   <!-- Create the build directory structure used by compile and dist -->
   <mkdir dir="${build}"/>
   <mkdir dir="${dist}"/>
   <mkdir dir="${war_dir}"/>
 </target>

 <target name="compile" depends="init">
   <!-- Compile the java code from ${src} into ${build} -->
   <javac
     srcdir="${top}/${src}"
     destdir="${build}"
     classpath="${servlet.jar}:${struts.jar}"/>
 </target>

 <target name="dist" depends="compile">
   <!-- Put everything in a war file -->
   <war warfile="${war_file}" webxml="${web.xml}">
     <!-- include all JSPs in root level, and all .properties files anywhere -->
     <fileset dir="${top}/${src}">
       <include name="*.jsp"/>
       <include name="**/*.properties"/>
     </fileset>

     <!-- include all tag libraries in WEB-INF, and all .xml config files,
          but not web.xml (that's handled separately) -->
     <webinf dir="${webinf}">
       <include name="*.tld"/>
       <include name="*.xml"/>
       <exclude name="web.xml"/>
     </webinf>

     <!-- include all libraries in WEB-INF/lib (like struts.jar) -->
     <lib dir="${lib}"/>

     <!-- include all compiled classes -->
     <classes dir="${build}"/>
   </war>
 </target>

 <target name="deploy">
   <!-- Copy the war file to the JBoss deploy directory -->
   <copy file="${war_file}" todir="${deploy}"/>
 </target>

 <target name="all" depends="clean,dist,deploy"/>

</project>

  1. ant all to compile, jar, and deploy.
  2. Go to http://localhost:8080/ConditionalStruts/index.jsp to test the application


Repeating Logic

The logic:iterate tag is used to repeat over the section in the JSP file defined by the <logic:iterate ..> and the </logic:iterate> tags. The iterate tag requires a collection to iterate over. The tag iterates over all the elements of the collection, unless the length property constrains the tag to a certain number of iterations. For each iteration, the tag selects the next element in the collection and sends the value of the element to a JSP bean with a name that is specified by the id property. Another Struts tag, the bean:write tag can then be used to output the value of the element.

The most important properties of the logic:iterate tag are shown in the following table. Following the table is an example that shows two ways to use the iterate tag, though the way using the name attribute is recommended.

<logic:iterate> properties

property description
id the name of a JSP bean that will contain the current element of the collection for each iteration - required
collection the value of a collection to be used, expressed as a String - please look at the second index.jsp in the following example that uses the collection property - one must use either the collection or name element to provide the collection of elements
length used to specify the maximum number of elements that will be iterated through - must evaluate to a java.lang.Integer or to an int
name name of the JSP bean that contains the collection that will be iterated over - one must use either collection or name to provide the collection of elements
offset the value, expressed as an integer or as a java.lang.Integer, of where the iterator tag begins the iteration of the collection - the default value is zero.
property the name of the property of the bean
type  the fully qualified Java class type of an element of the collection
scope the scope of the newly-created bean - page-wide scope is the default

IteratorStruts: Repeating HTML using Struts

Do this:

  1. Create the directory structure. The root directory is IteratorStruts, and it should contain a WEB-INF with all the Struts libraries and configuration files (copied from the previous examples). However, the class directory for this example is com.masslight.actions, so create the directory structure accordingly.
code/Chapter5/IteratorStruts
IteratorStruts
  |
  +-- index.jsp (*)
  |
  +-- build.xml (*)
  |
  +-- WEB-INF
        |
        +-- web.xml (*)
        |
        +-- struts-config.xml (*)
        |
        +-- app.tld (*)
        |
        +-- struts-bean.tld (*)
        |
        +-- struts-form.tld (*)
        |
        +-- struts-html.tld (*)
        |
        +-- struts-logic.tld (*)
        |
        +-- struts-template.tld (*)
        |
        +-- struts.tld (*)
        |
        +-- classes
        |     |
        |     +-- com
        |           |
        |           +-- masslight
        |                 |
        |                 +-- actions
        |                       |
        |                       +-- SetListAction.java (*)
        |
        +-- lib
              |
              +-- struts.jar (*)

(*) denotes a file

  1. Create the JSP
code/Chapter5/IteratorStruts/index.jsp
<%@ page language="java" %> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<html:html> 
  <header> 
   <title>Iterator</title> 
   <html:base/> 
  </header> 
  <body> 
     <logic:present name="list"> 
       <logic:iterate id="myCollectionElement" name="list"> 
         Element Value: <bean:write name="myCollectionElement" /><br /> 
       </logic:iterate> 
     </logic:present> 
   </body> 
</html:html>

  1. Create the Java file
code/Chapter5/IteratorStruts/WEB-INF/classes/com/masslight/actions/SetListAction.java
package com.masslight.actions;

import java.util.Vector;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Hashtable;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;

public final class SetListAction extends Action {

    // The constructor method for this class
    public SetListAction() {
    }

    // This sets the list as a session bean
    public ActionForward perform(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws IOException, ServletException {

        HttpSession session = request.getSession();

        java.util.ArrayList list = new java.util.ArrayList();
        list.add("ONE");
        list.add("TWO");
        list.add("THREE");

        session.setAttribute("list",list);

        return (mapping.findForward("success"));
    }
}

  1. Create the Struts configuration file
code/Chapter5/IteratorStruts/WEB-INF/struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE struts-config PUBLIC 
           "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" 
           "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd"> 

<struts-config> 

   <!-- ========== Form Bean Definitions =================================== --> 

   <!-- ========== Global Forward Definitions ============================== --> 
   <global-forwards> 
     <forward name="success" path="/index.jsp"/> 
   </global-forwards> 

   <!-- ========== Action Mapping Definitions ============================== --> 
   <action-mappings> 
     <!-- Save user registration --> 
     <action path="/setList" 
       type="com.masslight.actions.SetListAction" />
   </action-mappings> 

</struts-config>

  1. Copy the Ant build script from the previous example. Change IteratorStruts to HeaderStruts in the project name and .war file name. Everything else is unchanged.
  2. ant all
  3. Go to http://localhost:8080/IteratorStruts/setList.do to test the application. This is because there is no input in this application; everything happens in the Action, defined in SetListAction.java. In order to see the output of this Action, we need to invoke the Action directly, by going to the URL that is mapped to the Action (in struts-config.xml).

Accessing HTTP headers

The HTTP request that a client sends to a server and the HTTP response that a server sends to a client can both include multiple headers. Associated with each header is a name and a value. A header can provide information about the hostname of the client, the default human language setting on the machine, or anything else that can be contained in a name and a value.

In JSPs and servlets, the java.servlet.http.HttpServletRequest class provides access to the HTTP header information from the request and the java.servlet.http.HttpServletResponse class provides access to the header information for the response. The HTTPServletRequest and HTTPServletResponse methods that allow access to HTTP header information are shown in the following tables. The request and response objects are the instantiations of the HTTPServletRequest and HTTPServletResponse classes in JSP pages. The important methods of the two classes are listed below.

HTTPServletRequest methods for reading incoming HTTP headers

return type
method name
description
long getDateHeader(String nameOfHeader) returns the long value of the date 
String getHeader(String nameOfHeader) returns the value of the header with the name nameOfHeader
Enumeration getHeaderNames() returns an Enumeration of the names of all the headers
Enumeration getHeaders(String nameOfHeader) returns all the values of a specific header
int getIntHeader(String nameOfHeader) returns the int value of a header with the name nameOfHeader - if the value cannot be returned as an integer, then a NumberFormatException is thrown - if the request does not contain a header with the name of nameOfHeader, then a -1 is returned

HTTPServletResponse methods for setting outgoing HTTP headers

return type
method name
description
void addDateHeader(String nameOfHeader, long date) adds a header with the name nameOfHeader and the date, expressed in the number of milliseconds since 1-1-1970 GMT
void addHeader(String nameOfHeader, String value) adds a header with the name nameOfHeader and the value named value
void addIntHeader(String nameOfHeader, int value) adds a header with the name nameOfHeader and the int value named value.
boolean containsHeader(String nameOfHeader) returns true if there is header named nameOfHeader that exists, otherwise returns false
void setDateHeader(String nameOfHeader, long date) sets the time value for a specified time, expressed in the number of milliseconds since January First, 1970 GMT, for a header named nameOfHeader
void setHeader(String nameOfHeader, String value) sets a header with the name nameOfHeader to the value value.
void setIntHeader(String nameOfHeader, int value) sets a header with the name nameOfHeader to the int value value.

Common header names and possible associated values

Cache-Control = no-cache
Cookie = $Version=1; JSESSIONID=rkoo4wrr11; $Path="/AllHeaders"
Host = localhost:8080
Accept = text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */*
User-Agent = Mozilla/5.0 (Windows 2000; U) Opera 6.0 [en]
Accept-Language = en
Accept-Encoding = deflate, gzip, x-gzip, identity, *;q=0
Pragma = no-cache
TE = deflate, gzip, chunked, identity, trailers
Accept-Charset = windows-1252;q=1.0, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1
Connection = Keep-Alive, TE

Accessing Headers with Struts

Struts provides a tag called bean:header that can read the value of an HTTP header. Below is a table describing the different properties of the bean:header tag, followed by an example that demonstrates how to use the tag.

bean:header tag properties

property name description
id the name of the scripting variable with page scope - required
messages this property requires the name of an application scope message variable - this property is not discussed in this chapter
multiple if there might be more than one header with the same name, this property should not be null - the scripting variable will then hold an array of headers, if necessary
name the name of the header - required
value the value to return if no header exists with the name specified in the name property

HeaderStruts: Accessing HTTP Headers with Struts

Do this:

  1. Create the directory structure, with HeaderStruts as the root directory. Create the WEB-INF directory, and copy all the Struts libraries and configuration files from the previous example. However, there is no JavaBean in this example, so you can skip the classes directory altogether.
code/Chapter5/HeaderStruts
HeaderStruts
  |
  +-- index.jsp (*)
  |
  +-- build.xml (*)
  |
  +-- WEB-INF
        |
        +-- web.xml (*)
        |
        +-- app.tld (*)
        |
        +-- struts-bean.tld (*)
        |
        +-- struts-config.xml (*)
        |
        +-- struts-form.tld (*)
        |
        +-- struts-html.tld (*)
        |
        +-- struts-logic.tld (*)
        |
        +-- struts-template.tld (*)
        |
        +-- struts.tld (*)
        |
        +-- lib
              |
              +-- struts.jar (*)

(*) denotes a file

  1. Create the JSP file
code/Chapter5/HeaderStruts/index.jsp
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html>
   <head>
     <title>
       Headers with Struts
     </title>
   </head>
   <body>
     <logic:present header="User-Agent">
       <bean:header id="theheader" name="User-Agent"/>
       You are currently running <bean:write name="theheader"/>
     </logic:present>
   </body>
</html>

  1. Create the web.xml file. Since this application has no Actions or JavaBeans, this file is much simpler than the previous examples.
code/Chapter5/HeaderStruts/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app 
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 
  "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> 
 

<web-app>
    <taglib>
         <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
         <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    </taglib>
    <taglib>
         <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
         <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
    </taglib>
</web-app>

  1. Copy the build.xml file from the previous example. Change IteratorStruts to HeaderStruts.
  2. ant all to compile, build, and deploy.
  3. Go to http://localhost:8080/HeaderStruts/index.jsp to test your application.

Cookies

Reading cookies

The bean:cookie tag allows the developer to access cookies and their values. Below is a table that describes the different properties of the tag. The values of id, multiple, name, and value can all be accessed from the scripting bean that represents the cookie. The message property is not discussed in this chapter. Following the table is an example that demonstrates how to access cookie information using Struts. Remember, it's good to check if the cookie is present before using the bean:cookie tag.

bean:cookie tag properties

property name
description
id the name of the scripting variable with page scope - required
messages this property requires the name of an application scope message variable - this property is not discussed in this chapter
multiple if there might be more than one cookie with the same name, this property should not be null - the id scripting variable will then hold an array of cookies
name the name of the cookie - required
value the value to return if no cookie exists with the name specified in the name property

Writing cookies

Using Struts, cookies cannot be sent with the response to the client. To send a cookie with the response, a javax.servlet.http.Cookie object must be added to the response object. The cookie is then added to the client's cookie library and may be included in the client’s requests, depending on how the cookie was set. The response object was discussed in chapter two.

Properties of the Cookie class

property description
name The name of the Cookie object
value The value of the cookie
path The path on the server where the browser will return the Cookie object
maxAge The maximum length of time that the cookie will persist in seconds - 
a value of -1 means that the cookie will persist until shut down

Here is a sample Java snippet that creates a new cookie:

String newValue = "" + System.currentTimeMillis(); 
info = new Cookie("MyCookie", newValue);
info.setMaxAge(60); 
info.setPath("/"); 
response.addCookie(info);

CookieStruts: Reading and Writing Cookies with Struts

Do this:

  1. Duplicate the directory with used in ConditionalStruts and rename it to CookieStruts.
code/Chapter5/CookieStruts
CookieStruts
  |
  +-- index.jsp (*)
  |
  +-- build.xml (*)
  |
  +-- WEB-INF
        |
        +-- web.xml (*)
        |
        +-- struts-config.xml (*)
        |
        +-- app.tld (*)
        |
        +-- struts-bean.tld (*)
        |
        +-- struts-form.tld (*)
        |
        +-- struts-html.tld (*)
        |
        +-- struts-logic.tld (*)
        |
        +-- struts-template.tld (*)
        |
        +-- struts.tld (*)
        |
        +-- lib
        |     |
        |     +-- struts.jar (*)
        |
        +-- classes
              |
              +-- com
                    |
                    +-- masslight
                          |
                          +-- strutsExampleClasses
                                |
                                +-- ApplicationResources.properties (*)
                                |
                                +-- NameForm.java (*)
                                |
                                +-- Name.java (*)
                                |
                                +-- SetNameAction.java (*)

(*) denotes a file

  1. Create the JSP
code/Chapter5/CookieStruts/index.jsp
<%@ page language="java" %> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> 
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> 
<html:html> 
  <head> 
    <title> 
      <bean:message key="welcome.title"/> 
    </title> 
    <html:base/> 
  </head> 
  <body> 

    <!-- This will set the number to be guessed -->
    <bean:define id="theNumber" value="7"/> 

    <html:errors/> 
    <html:form action="/setName"> 
        <html:hidden property="action"/> 
        <bean:message key="prompt.name"/> 
        <html:text property="name" size="16" maxlength="16"/> 
        <br>
        <html:submit> 
          <bean:message key="button.save"/> 
        </html:submit> 
        <html:reset> 
          <bean:message key="button.reset"/> 
        </html:reset> 
    </html:form> 
    <hr> 
    <logic:present cookie="name"> 

        <bean:cookie id="namecookie" name="name"/>
        <bean:write name="namecookie" property="name"/>
        <bean:write name="namecookie" property="value"/>
        <br>

        <!-- Equal To -->
        <logic:equal name="namecookie" property="value" value="<%= theNumber %>" >
         <bean:message key="result.correct"/>
        </logic:equal>

        <logic:notEqual name="namecookie" property="value" value="<%= theNumber %>">
          <!-- Less Than -->
          <logic:lessThan name="namecookie" property="value" value="<%= theNumber %>" >
            <bean:message key="result.lessThan"/>
          </logic:lessThan>
          <!-- Greater Than -->
          <logic:greaterThan name="namecookie" property="value" value="<%= theNumber %>" >
            <bean:message key="result.greaterThan"/>
          </logic:greaterThan>
        </logic:notEqual>
        <hr>
     </logic:present> 
  </body> 
</html:html>

  1. Open build.xml and change the references in the project name and .war file from ConditionalStruts to CookieStruts.
  2. ant all to compile, jar, and deploy
  3. Go to http://localhost:8080/CookieStruts/index.jsp to test the application

Exercises

Exercise 1. Show all headers

Make an application that shows all the headers included in the request.

Exercise 2. Reload game

Make an application where the user tries to "hit" or reload the page when the second hand of the system clock is even. The user wins a game every time he or she reloads the page when there is an even amount of seconds. The application will have one cookie that keeps track of how many times the user has "won" and another cookie that remembers how many times the user has "played". The application will display the winning percentage of the user, the number of games played, and the number of games won.


Exercise 3. Tables

Make an application with a web page that displays a table. The table should have at least three columns and at least three rows. Each column should have a heading. The display of the information should use an HTML <table>. Use a two-dimensional array to store the data internally within a JavaBean. The display should look similar to this:


Name Favorite Food Quote
Joey
Pizza
Da Bulls
Mikey
Ice Cream
Da Bears
Louie
Tomatoes
Da Cubs