6. HTML Forms
So far, we have used a single form containing only two input fields. Here, we propose to create and process a form using standard graphical components (radio buttons, checkboxes, input fields, combo boxes, lists).
6.1. The application views
The application will have only two views. The first displays a blank form:
VIEW 1 - form

This first view, named form.jsp, will allow us to implement various tags from the struts-html library. The user fills out the form:

The [Submit] button confirms the entered values. This will be the second view:

This second view will allow us to use two other tag libraries: struts-bean and struts-logic. The [Back to Form] link allows us to return to the form as we filled it out. We are then taken back to the first view.
6.2. The application architecture
![]() |
- The form (view 1) will be represented by a dynamic Struts object called dynaFormulaire, a subclass of DynaActionForm. It will be displayed by the form.jsp view.
- The Struts action InitFormulaireAction will be responsible for retrieving the data needed to display the form
- The completed form will be processed by a ForwardAction, which will simply redirect the request to the second view, confirmation.jsp. This view will be responsible for displaying the form values.
6.3. Application configuration
6.3.1. The server.xml file
The application context will be named /formulaire2. We will therefore add the following line to Tomcat’s server.xml file:
Once this is done, we may need to restart Tomcat so that it recognizes the new context. We can verify that it is valid by requesting the URL http://localhost:8080/formulaire2:

6.3.2. The web.xml file
The application's web.xml configuration file will be as follows:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<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>
Compared to the web.xml configuration files we’ve already seen, we’re making a few changes:
- We are introducing two new tag libraries: struts-bean and struts-logic. These will be used in the confirmation.jsp view. The formulaire.jsp view, on the other hand, will use the struts-html library.
6.3.3. The struts-config.xml file
The struts-config.xml file will be as follows:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="dynaForm" type="istia.st.struts.formulaire.DynaForm">
<form-property name="opt" type="java.lang.String" initial="no"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="inputField" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="inputBox" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="singleList" type="java.lang.String"/>
<form-property name="multipleList" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="comboValues" type="java.lang.String[]" />
<form-property name="singleListValues" type="java.lang.String[]" />
<form-property name="multipleListValues" type="java.lang.String[]"/>
</form-bean>
</form-beans>
<action-mappings>
<action
path="/confirmation"
name="dynaForm"
validate="false"
scope="session"
parameter="/views/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaForm"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="displayForm" path="/views/form.jsp"/>
</action>
<action
path="/display"
parameter="/views/form.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
<message-resources
parameter="ApplicationResources"
null="false"/>
</struts-config>
It contains three main sections:
- the declaration of forms in the <form-beans> section
- the declaration of actions in the <action-mappings> section
- the declaration of the resource file in <message-resources>
6.3.4. The application's form objects (beans)
The objects used to represent the application’s HTML forms are of type ActionForm or a derived type (DynaActionForm, DynaValidatorForm, etc.). They are called beans because their construction follows the rules of JavaBeans. There is only one form bean in our application, called dynaFormulaire and derived from DynaActionForm. It will be used in the following situations:
- to contain the data needed to display view #1
- retrieve the values from the form in view #1 when the user submits it
- to contain the data needed to display view #2
The structure of the dynaFormulaire bean is closely tied to the form in view #1. Let’s examine it:
![]() |
No. | HTML Type | Role |
<input name="opt" type="radio" value="yes"> <input name="opt" type="radio" value="no"> | group of radio buttons linked together (same name) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | groups of checkboxes (not the same name) | |
<input type="text" name="inputField"> | a text field | |
<input type="password" name="password"> | a password field | |
<textarea name="inputBox">...</textarea> | a multi-line input field | |
<select name="combo" size="1">..</select> | a dropdown | |
<select name="simpleList" size="3">..</select> | a single-select list | |
<select name="listeMultiple" size="3" multiple>..</select> | a multiple-select list | |
<input type="button" value="Clear" onclick='clearList("singleList")'> | button to deselect the selected items in simpleList (7) | |
<input type="button" value="Clear" onclick='clearList("multipleList")'> | button to deselect the selected items in multipleList (8) | |
<input type="submit" value="Submit"> | form submit button | |
<input type="hidden" name="secret" value="..."> | a hidden field |
Let's consider several cases:
- The dynaFormulaire object is used to hold the values from the HTML form above, which will be submitted via the [Submit] button. It must therefore have the same fields as the HTML form. The field type is determined by the following rule:
- if the HTML field provides only one value, then the dynaFormulaire field will be of type java.lang.String
- if the HTML field provides multiple values, then the dynaFormulaire field will be of type java.lang.String[]
In the HTML form above, only the listeMultiple field can be associated with multiple values (those selected by the user). Therefore, an initial definition of the **dynaFormulaire** object would be as follows:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="no"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="inputField" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="inputBox" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="singleList" type="java.lang.String"/>
<form-property name="multipleList" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
</form-bean>
How will dynaFormulaire be populated with the HTML form values sent by the web client?
The opt field will receive the value "yes" if the HTML field <input type="radio" name="opt" value="yes"> has been checked, and the value "no" if the field <input type="radio" name="opt" value="no"> has been checked. | |
The chk1 field will receive the value "on" if the HTML field <input name="chk1" type="radio" value="1"> has been selected; otherwise, it will receive nothing. In the latter case, the chk1 field will retain its previous value. | |
same | |
same | |
The `champSaisie` field will receive the text entered by the user in the HTML field `<input type="text" name="champSaisie">`. This text may be an empty string. | |
The mdp field will receive the text entered by the user in the HTML field <input type="password" name="mdp">. This text may be an empty string. | |
The inputBox field will receive the text entered by the user in the HTML field <textarea name="inputBox">...</textarea>. This text forms a single string, consisting of the lines typed by the user separated from one another by the character sequence "\r\n". The resulting text may optionally be an empty string. | |
The combo field will receive the option selected by the user in the HTML field <select name="combo" size="1">..</select>. The selected option is the one that appears in the combo box. If the selected HTML option is of the type <option value="XX">YY</option>, the combo field will receive the value "XX". If the selected HTML option is of the type <option>YY</option>, the combo field will receive the value "YY". | |
The simpleList field will receive the option selected by the user in the HTML field <select name="simpleList" size="..">..</select> if there is one. If there is none, the simpleList field will receive no value and retain its previous value. The value actually assigned to the simpleList field follows the rules specified for the combo box. | |
The listeMultiple field of type String[] will receive the options selected by the user in the HTML field <select name="listeMultiple" size=".." multiple>..</select> if any. If there are none, the listeMultiple array will receive no value and its content will remain unchanged. The values actually assigned to the listeMultiple array follow the rules specified for the combo box. | |
The secret field will receive the value XX from the HTML field <input type="hidden" name="secret" value="XX">. This text may optionally be an empty string. |
- The dynaFormulaire object is used to provide the initial content for view #1. The values of the preceding fields will be used for the following purposes:
must have the value "yes" or "no" so that the browser knows which radio button to select | |
If chk1 has the value "on," the checkbox will be checked; otherwise, it will not be checked | |
same | |
same | |
the field value will be displayed in the input field fieldInput | |
the field value will be displayed in the mdp input field | |
the field value will be displayed in the input box inputBox | |
The value of this field indicates which item in the combo box should be selected when the form is displayed | |
same | |
The values in the multipleList array indicate which items in the multiple list should be selected when the form is displayed | |
The field's value will be assigned to the value attribute of the secret HTML field. |
View #1 requires additional information:
- the list of values to display in the combo list
- the list of values to display in the `listeSimple` list
- the list of values to display in the multipleList
There are several ways to provide this information to the view. For example, arrays placed in the request passed to the view would work. Here, we place these arrays in the dynaFormulaire bean:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<form-property name="comboValues" type="java.lang.String[]" />
<form-property name="singleListValues" type="java.lang.String[]" />
<form-property name="multipleListValues" type="java.lang.String[]"/>
</form-bean>
The dynaFormulaire form will be initialized by the /init action, which will call an object derived from Action called InitFormulaireAction. This object will be responsible for creating the three arrays needed to display the three lists and placing them in the dynaFormulaire bean. The configuration file sets this bean’s scope to session. As a result, the Struts controller will place this bean in the session. We will therefore not need to regenerate it between request-response cycles. Consequently, the /init action will be called only once.
- The dynaFormulaire object is also used to populate view #2. This view simply displays the values.
6.3.5. Application Actions
Actions are handled by objects of type Action or derived types. Action configuration is done within the <action-mappings> tags:
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/views/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaForm"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="displayForm" path="/views/form.jsp"/>
</action>
<action
path="/display"
parameter="/views/form.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
Note that there isn’t always a form associated with an action. This is the case, above, with the /affiche action. Before detailing each action, let’s review how the action-form pair works within an <action> tag:
- An action begins with a request from a web client and ends with the sending of a response page. This is the client-server web request-response cycle. The request is received by the Struts controller of type ActionServlet or a derived class. This controller also sends the response.
- The form bean of type ActionForm or a derived class is created if it does not already exist. The controller checks whether it can find an object named name in the scope specified by scope. If so, it uses it. If not, it creates it and places it in the scope specified by scope, associated with the attribute specified by name.
In the example of the /init action, for instance, the controller will call request.getSession().getAttribute("dynaFormulaire") to determine whether dynaFormulaire has already been created or not. If not, it will create it and add it to the session using a statement like request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- The controller will also look for an Action object of the type specified by the type attribute. If it does not find one, it creates it; otherwise, it uses it.
- The reset method of the form bean will be called. This bean, except during its initial creation, is reused. It therefore contains data that you may want to "clean up." This is done in the reset method of the ActionForm bean or a derived class.
- If the action is the target of a submitted form, then the form values found in the client request are copied into the fields of the same name in the form bean. Note that the reset method was called before this copying.
- If the configuration specifies the attribute validate="true", the validate method of the form bean will be called. This method must then validate the data in the bean. This validation typically occurs only when the form has just received new data via a submitted form and you want to verify the validity of that data. This method returns any list of errors to the controller in an ActionErrors object.
- If the ActionErrors object is not empty, the controller displays the view specified by the action’s input attribute.
- If data validation is not required or if it was successful, the controller calls the `execute` method of the `Action` object (or a derived class) associated with the current action. It is within this method that the web client's request is processed. The `execute` method returns an `ActionForward` object indexed by string keys. These keys are those declared by the `forward` tags of the configured action. In our example, the `/init` action has a single `forward` tag. It associates the key "displayForm" with the `form.jsp` view.
- The controller displays the view associated with the received key. This view may in fact be an action, in which case the previous process is repeated.
The /init action
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="displayForm" path="/views/form.jsp"/>
</action>
- The /init action normally occurs once during the first request-response cycle when the user requests the URL http://localhost:8080/formulaire2/init.do
- The dynaForm object is created or recycled. It is retrieved (recycling) or placed (creation) in the session as specified by the scope attribute.
- Its reset method is called. What should it do? Normally, the fields of the ActionForm object are reset to default values. However, in this case, we will not do so, because the dynaFormulaire object is placed in the session (scope="session"). The fields of dynaFormulaire must therefore retain their values. What are these values during the initial creation of the dynaFormulaire object? There are two cases:
- the field has an initial value specified in the configuration file:
In this case, the Struts controller will create this field with this initial value.
- the field has no initial value specified in the configuration: Java’s initialization rules apply. Generally, numeric fields will have the value zero, strings will have the empty string, and other objects will have the value null.
Let’s look at the initial configuration of dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="no"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="inputField" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="inputBox" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="singleList" type="java.lang.String"/>
<form-property name="multipleList" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="comboValues" type="java.lang.String[]" />
<form-property name="singleListValues" type="java.lang.String[]" />
<form-property name="multipleListValues" type="java.lang.String[]"/>
</form-bean>
The initial values of the dynaFormulaire fields after creation will be as follows:
Field | Initial Value |
"no" | |
empty string | |
empty string | |
empty string | |
empty string | |
empty string | |
empty string | |
array of empty strings | |
"xxx" | |
array of empty strings |
- One might imagine that the reset method of dynaFormulaire assigns values to the three arrays that populate the three lists in the formulaire.jsp view. This would be possible here because the data in these three arrays is generated arbitrarily. However, the most common scenario is that this data comes from the application model, the M in MVC. Here, we’ll take a middle ground—to keep the example simple—by having these values generated by the InitFormulaireAction action, i.e., by the C in MVC.
- There is no requirement to write a reset method in dynaFormulaire, since the ActionForm class from which it derives already has such a method that does nothing (no initializations).
- Once the reset method of dynaFormulaire is called, the controller checks the validate attribute of the action. Here, it has the value "false". The validate method of dynaFormulaire will not be called.
- The InitFormulaireAction object is created or reused if it already existed, and its execute method is called. This method assigns arbitrary values to the three arrays of dynaFormulaire: valeursCombo, valeursListeSimple, and valeursListeMultiple. The method returns an ActionForward with the key "afficherFormulaire".
- The controller displays the /vues/formulaire.jsp view, which has been associated with the "afficherFormulaire" key via a forward tag from the /init action.
The /confirmation action
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/views/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- The /confirmation action occurs when the user clicks the [Submit] button on view #1. The browser then "posts" the form filled out by the user to the Struts controller.
- The dynaFormulaire object is retrieved from the session
- its reset method is called. Once it has been called, the Struts controller will copy the values of the form fields posted by the client into the fields of the same name in dynaFormulaire. Let’s review the list of fields in dynaFormulaire and see how this copying works:
Field | Associated HTML code | Field value after copying the form values |
<input type="radio" name="opt" value="yes">Yes <input type="radio" name="opt" value="no" checked="checked">No | - "yes" or "no" depending on the selected radio button | |
<input type="checkbox" name="chk1" value="on"> | - "on" if the chk1 checkbox has been checked - retains its previous value if the chk1 checkbox has not been checked | |
<input type="checkbox" name="chk2" value="on"> | - "on" if the chk2 checkbox has been checked - retains its previous value if the chk2 checkbox has not been checked | |
<input type="checkbox" name="chk2" value="on"> | - "on" if the chk3 checkbox has been checked - retains its previous value if the chk3 checkbox has not been checked | |
<input type="text" name="inputField" value=""> | - value entered by the user in inputField | |
<input type="password" name="password" value=""> | - value entered by the user in password | |
<textarea name="inputBox"></textarea> | - value entered by the user in textbox | |
<select name="combo">...</select> | - value selected by the user in combo | |
<select name="simpleList" size="3">...</select> | - value selected by the user in simpleList | |
<select name="listeMultiple" multiple="multiple" size="5"> | - array of strings containing the values selected by the user in multipleList | |
<input type="hidden" name="secret" value="xxx"> | - "xxx". |
We encounter an issue with fields that do not necessarily receive a value in the request sent by the browser. This applies to checkboxes chk1 through chk3 and the two lists listeSimple and listeMultiple. In this case, these fields retain their previous values—those acquired during the previous request-response cycle.
Let’s consider the checkbox chk1, for example, and assume that in the previous request-response cycle, the user had checked this box. The browser then sent the information chk1="on" in the parameter string of its request. The constructor therefore assigned the value "on" to the chk1 field of dynaFormulaire. Now suppose that in the current cycle, the user does not check the chk1 checkbox. In this case, in the parameter string of the new request, the browser does not send something like chk1="off" but sends nothing. As a result, the chk1 field in dynaFormulaire will retain its "on" value and thus have a value that does not reflect that of the form validated by the user. We will use the reset method of dynaFormulaire to resolve this issue. In this method, we will set the three fields chk1, chk2, and chk3 to "off". In our chk1 example, either the user:
- check the chk1 checkbox. In this case, the browser sends the information chk1="on" and the chk1 field in dynaFormulaire will change to "on"
- does not check the chk1 checkbox. Then the browser does not send a value for the chk1 field, which will retain its previous value "off". In both cases, the value stored in the chk1 field of dynaFormulaire is correct.
The issue is similar for both the simpleList and multiList lists. If no option has been selected in these lists, they will not be present in the request parameters and will therefore retain their previous values. In dynaFormulaire’s reset method, we will reset simpleList with an empty string and multiList with an array of strings of length 0.
- Once the dynaFormulaire reset method is called, the controller copies the information sent to it in the client request back into the dynaFormulaire fields
- A ForwardAction object is created or reused, and its execute method is called. ForwardAction is a predefined class that returns an ActionForward object pointing to the view defined by the action’s “parameter” attribute, in this case /vues/confirmation.jsp.
- The controller sends this view. The cycle is complete.
The /display
<action
path="/display"
parameter="/views/form.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- The /display action is triggered by clicking the [Back to form] link on view #2.
- Here, there is no form associated with the action. We therefore proceed directly to executing the `execute` method of a `ForwardAction` object, which will return an `ActionForward` object pointing to the view `/vues/formulaire.jsp`.
6.3.6. The application's message file
The third section of the struts-config.xml file is the message file:
The ApplicationResources.properties file is located in WEB-INF/classes. It will be empty. Even though it is empty, it must still be declared in the configuration file; otherwise, the struts-bean tag library, which we will discuss later, will generate an error. This library is used by the confirmation.jsp view.
6.4. The view code
6.4.1. The formulaire.jsp view
Remember that this view is displayed in two cases:
- when the /init action is called during the first request-response cycle
- when the /affiche action is called during subsequent cycles
The code for the formulaire.jsp view is as follows:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>form</title>
</head>
<body background='<html:rewrite page="/images/standard.jpg"/>'>
<h3>Struts Form</h3>
<hr>
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<table border="0">
<tr>
<td>radio button</td>
<td>
<html:radio name="dynaFormulaire" property="opt" value="yes">Yes</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="no">No</html:radio>
</td>
</tr>
<tr>
<td>Checkboxes</td>
<td>
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox>
</td>
</tr>
<tr>
<td>Input field</td>
<td>
<html:text name="dynaFormulaire" property="inputField" />
</td>
</tr>
<tr>
<td>Password</td>
<td>
<html:password name="dynaFormulaire" property="mdp" />
</td>
</tr>
<tr>
<td>Multi-line text box</td>
<td>
<html:textarea name="dynaFormulaire" property="boiteSaisie" />
</td>
</tr>
<tr>
<td>Combo</td>
<td>
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="comboValues"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Single-select list</td>
</tr>
<tr>
<td>
<input type="button" value="Clear" onclick="this.form.simpleList.selectedIndex=-1"/>
</td>
</tr>
</table>
<td>
<html:select name="dynaFormulaire" property="simpleList" size="3">
<html:options name="dynaFormulaire" property="simpleListValues"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Multiple-selection list</td>
</tr>
<tr>
<td>
<input type="button" value="Clear" onclick="this.form.listeMultiple.selectedIndex=-1"/>
</td>
</tr>
</table>
</td>
<td>
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="multipleListValues"/>
</html:select>
</td>
</tr>
</table>
<html:hidden name="dynaFormulaire" property="secret"/>
<br>
<hr>
<html:submit>Submit</html:submit>
</html:form>
</body>
</html>
This JSP page uses tags from the struts-html library. Remember that to use a tag library, you must:
- declare it in the application's web.xml file using a <tag-lib> tag
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- Place the code for this library somewhere in the application directory tree, here WEB-INF/struts-html.tld
- Declare the use of this library at the beginning of the JSP pages that use it:
The formulaire.jsp view uses tags that we will now explain:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
The html:rewrite tag allows you to omit the application name from URLs. It has one attribute:
So, in the example above, if you decide to name the application "form3," the code for the background attribute does not need to be rewritten. The `html:rewrite` tag will generate the new HTML code background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
The html:form tag generates the HTML form tag. It has several attributes:
We can see that by default, the generated HTML code uses the POST method. In this same HTML code, the action URL has been rewritten to be prefixed with the application name and suffixed with .do. |
<html:radio name="dynaFormulaire" property="opt" value="yes">Yes</html:radio> | |||||||
The html:radio tag is used to generate the HTML tag <input type="radio" ...>. It supports various attributes:
The text between the start and end tags is the text that will be displayed next to the radio button. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
The html:checkbox tag is used to generate the HTML tag <input type="checkbox" ...>. It supports various attributes:
The text between the start and end tags is the text that will be displayed next to the checkbox. |
<html:text name="dynaFormulaire" property="inputField" /> | |||||||
The html:text tag is used to generate the HTML tag <input type="text" ...>. It supports various attributes:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
The html:password tag is used to generate the HTML tag <input type="password" ...>. It supports various attributes: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
The HTML:textarea tag is used to generate the HTML tag <textarea>...</textarea>. It supports various attributes:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
The HTML:select tag is used to generate the HTML tag <select>...</select>. It supports various attributes:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |||||
The HTML:options tag is used to generate the HTML tags <option>...</option> inside an HTML <select> tag. There are various ways to specify how to find the values to populate the select element. Here, we have used the name and property attributes:
|
The other two lists are generated in a similar way to the previous one:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
Above, we specify a size attribute other than 1 to create a list instead of a combo box.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="multipleListValues"/>
</html:select>
Above, we specify the multiple="true" attribute to create a list with multiple selections.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
The html:hidden tag is used to generate the HTML tag <input type="hidden" ...>.
|
To fully understand the relationship between the formulaire.jsp view and the dynaFormulaire bean that represents it in memory, it is important to remember that the dynaFormulaire bean is used for both reading and writing:
![]() |
The request occurs when the user clicks the [Submit] button on the form. The browser then "posts" the HTML form to the /confirmation action. We have already explained what happens then, and in particular that the dynaFormulaire fields will receive the values of the fields with the same name in the HTML form.
What happens when the controller requests that the formulaire.jsp page be displayed in response to a request? Let's take a closer look at the tags one by one:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
generates the HTML code |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
generates the HTML code |
<html:radio name="dynaFormulaire" property="opt" value="yes">Yes</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">No</html:radio> | |
If the opt field of dynaFormulaire is "yes", generate the HTML code |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox> <html:checkbox name="dynaForm" property="chk3">3</html:checkbox> | |
If the chk1 and chk3 fields of dynaFormulaire are "on" and the chk2 field is "off", generate the HTML code |
<html:text name="dynaFormulaire" property="inputField" /> | |
if the input field is set to "this is a test", generate the HTML code |
<html:password name="dynaFormulaire" property="password" /> | |
if the password field is "azerty", generate the HTML code |
<html:password name="dynaFormulaire" property="mdp" /> | |
If the "mdp" field is "azerty", generate the HTML code |
<html:password name="dynaFormulaire" property="mdp" /> | |
If the "mdp" field is "azerty", generate the HTML code |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |
if the combo field is "combo2", generates the HTML code |
<html:select name="dynaFormulaire" property="simpleList" size="3"> <html:options name="dynaFormulaire" property="simpleListValues"/> </html:select> | |
if the simpleList field is "simple1", generates the HTML code |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="multipleListValues"/> </html:select> | |
If the listeMultiple field is the array {"multiple0", "multiple2"}, generates the HTML code |
<html:hidden name="dynaFormulaire" property="secret"/> | |
if the secret field has the value "xxx", generate the HTML code |
<html:submit>Submit</html:submit> | |
generates the HTML code |
The last thing to explain is the JavaScript code included in the JSP page and associated with the two [Clear] buttons that deselect the selected items in the simpleList and multipleList lists:
<input type="button" value="Clear" onclick="this.form.simpleList.selectedIndex=-1"/>
<input type="button" value="Clear" onclick="this.form.listeMultiple.selectedIndex=-1"/>
The tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
generates the following HTML code:
To understand the JavaScript code associated with the [Clear] buttons, let’s review how the various elements of a web document are referenced within JavaScript code that uses that document:
Data | Meaning |
refers to the entire web document | |
refers to the collection of forms defined in the document | |
refers to form number i in the document | |
refers to the <form> form with the name attribute set to "formName" | |
refers to the <form> form with the name attribute equal to "formName" | |
refers to the collection of elements belonging to the form designated by the expression [form]. This collection includes all <input>, <textarea>, and <select> tags in the designated form. | |
refers to element number i of [form] | |
refers to the element in [form] whose name attribute is equal to componentName | |
refers to the element in [form] whose name attribute equals componentName | |
refers to the value of the [component] component of the [form] form when its HTML code may have a value attribute (<input>, <textarea>) | |
refers to the index of the selected option in a list. Can be used for both reading and writing. Setting this property to -1 deselects all items in the list. | |
refers to the array of options associated with a <select> tag | |
refers to option number i of the specified <select> tag | |
A boolean indicating whether option #i of the specified [select] element is selected (true) or not. Can be used for both reading and writing |
Let’s revisit the JavaScript code for the two buttons:
<input type="button" value="Clear" onclick="this.form.simpleList.selectedIndex=-1"/>
<input type="button" value="Clear" onclick="this.form.listeMultiple.selectedIndex=-1"/>
When the button is clicked, the code associated with the "onclick" attribute is executed. Here, it is inline code. Most often, we write onclick="function(...)", where function is a function defined within a <script language="javascript">...</script> tag. What does the code above do? Let’s break down the code for the first button:
refers to the web document in which the button is located | |
refers to the form in which the button is located | |
refers to the simpleList component of the form | |
refers to the index of the selected option in listeSimple. Setting this property to -1 deselects all options. |
6.4.2. The confirmation.jsp view
Recall that this view is displayed after the /confirmation action, i.e., after the form contained in the formulaire.jsp view has been submitted by the web client. Its sole purpose is to display the values entered by the user. Its code is as follows:
<%@ 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>
<head>
<title>Confirmation</title>
</head>
<body background="<html:rewrite page="/images/standard.jpg"/>">
<h3>Confirmation of entered values</h3>
<hr/>
<table border="1">
<tr>
<td>Radio button</td>
<td><bean:write name="dynaFormulaire" scope="session" property="opt"/></td>
</tr>
<tr>
<td>Checkbox chk1</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk1"/></td>
</tr>
<tr>
<td>Checkbox chk2</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk2"/></td>
</tr>
<tr>
<td>Checkbox chk3</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk3"/></td>
</tr>
<tr>
<td>Input field</td>
<td><bean:write name="dynaFormulaire" scope="session" property="inputField"/></td>
</tr>
<tr>
<td>Password</td>
<td><bean:write name="dynaFormulaire" scope="session" property="mdp"/></td>
</tr>
<tr>
<td>Input field</td>
<td><bean:write name="dynaFormulaire" scope="session" property="inputField"/></td>
</tr>
<tr>
<td>combo</td>
<td><bean:write name="dynaFormulaire" scope="session" property="combo"/></td>
</tr>
<tr>
<td>simple list</td>
<td><bean:write name="dynaFormulaire" scope="session" property="simpleList"/></td>
</tr>
<logic:iterate id="choice" indexId="index" name="dynaForm" property="multipleList">
<tr>
<td>multiple list[<bean:write name="index"/>]</td>
<td><bean:write name="choice"/></td>
</tr>
</logic:iterate>
</table>
<br>
<html:link page="/affiche.do">
Back to form
</html:link>
</body>
</html>
Here we introduce two new tag libraries: struts-bean and struts-logic. The struts-bean library provides access to objects in the request, session, or application context. The struts-logic library allows you to implement execution logic using tags. Neither of these libraries is strictly necessary. As we have seen, a JSP page can:
- retrieve objects from the request (request.getAttribute(...)), the session (session.getAttribute(...), or the application context
- include dynamic elements in the HTML code using variables <%= variable %>
- contain Java code <% Java code %>
The inclusion of Java code in JSP pages bothers those who prefer a strict separation between application logic (Java code) and presentation (use of tags). That is why tag libraries were created for them.
We will proceed as we did for the formulaire.jsp view and explain each of the tags present in the confirmation.jsp code if they have not already been encountered in the formulaire.jsp view. First, note that the page begins by declaring the three tag libraries it will use:
<%@ 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" %>
Note also that these three libraries must be declared in the application’s web.xml file. We will now comment on the tags in the formulaire.jsp document:
writes a value to the current HTML stream. The bean:write tag supports the following attributes: name: name of the object to use scope: scope (request, session, context) in which to search for this object property: field of the object designated by name whose property is to be written. This field can be an object of any type. The object’s toString method will be used. Here, the value of the opt field in dynaFormulaire is written. The result will be either "yes" if the user has checked the radio button with the value="yes" attribute, or "no" if they have checked the radio button with the value="no" attribute |
writes the value of the chk1 field in dynaFormulaire. The result will be either "on" if the user has checked the box, or "off" otherwise. The same applies to chk2 and chk3. |
writes the value of the champSaisie field in dynaFormulaire, i.e., the text typed by the user in that field. The same applies to mdp and boiteSaisie. |
writes the value of the combo field in dynaFormulaire. This will be the value attribute of the <option> element selected by the user. |
writes the value of the simpleList field in dynaForm. It will contain the value attribute of the <option> element selected by the user, if one was selected. Otherwise, it will be an empty string. |
Here, we introduce logic tags. We are dealing with a multiple-choice list. The value of the listeMultiple field of the dynaFormulaire object is an array of Strings. In Java, we would write a loop. The logic:iterate tag allows us to perform this same loop without writing Java code. In this example, the logic:iterate tag has the following attributes: name="dynaFormulaire": name of the object to use property="listeMultiple": name of the property in the object specified by name that contains the collection to be iterated over in the loop. Here, this collection is the array of values selected in listeMultiple. This array may be empty. id="choix": identifier designating the current element of the array at each iteration. During the first iteration, choix will represent listeMultiple[0], during the second listeMultiple[1], and so on. indexID="index": identifier designating the index of the current array element at each loop iteration. During the first iteration, index will have the value 0; during the second, the value 1; and so on. The HTML code contained between the <logic:iterate ...> and </logic:iterate> tags is repeated for each element in the collection designated by the (name,property) pair. The dynamic part of this code is as follows:
Based on what was said earlier, at iteration number i (i>=0), the generated HTML code is equivalent to the following: |
generates a link relative to the application context, which eliminates the need to know the context. The HTML code generated by this tag is as follows: |
6.5. The Java classes
The struts-config.xml configuration file references two Java classes:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
The DynaFormulaire class is the class that will contain the values from view #1, formulaire.jsp. The InitFormulaireAction class is the class that will process the form values submitted via the [Submit] button on formulaire.jsp.
6.5.1. The DynaFormulaire class
To hold the values of a form, an object of type DynaActionForm is sufficient unless you need to override one of the reset or validate methods of this class. Here, the validate method does not need to be overridden since no data validation is performed. However, the reset method does need to be overridden. This is because the fields of the DynaFormulaire object will receive their values from the form submitted by the web client. However, some fields may not receive a value if they are not present in the request. This occurs in the following cases:
- a checkbox that has not been checked by the user
- a list with more than one option where none has been selected
For forms containing this type of component, the reset method must
- set the value "off" for the field associated with the checkbox
- set the empty string to the field associated with a single-select list
- assign an empty array of strings to the field associated with a multi-select list
Thus, if these fields do not receive a value from the query, they retain the value assigned by reset, which corresponds to the state of the component in the form validated by the user (checkbox unchecked, list with no items selected).
The code for the DynaFormulaire class, a subclass of DynaActionForm, is as follows:
package istia.st.struts.formulaire;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class DynaForm extends DynaActionForm {
public void reset(ActionMapping mapping, HttpServletRequest request){
// Reset checkboxes - value set to off
set("chk1", "off");
set("chk2", "off");
set("chk2", "off");
// reset simpleList - empty string
set("simpleList", "");
// reset multipleList - empty array
set("multipleList", new String[]{});
}
}
6.5.2. The InitFormAction class
The InitFormAction class is associated with the /init action in the struts-config.xml file:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="displayForm" path="/views/form.jsp"/>
</action>
The /init action is used only once during the initial construction of the DynaForm object. Its purpose is to provide content for the form's three combo lists: simpleList, multipleList, and dropdownList. This content is provided in the form of three arrays, which are properties of the dynaForm object:
<form-bean name="dynaForm" type="istia.st.struts.formulaire.DynaForm">
<form-property name="opt" type="java.lang.String" initial="no"/>
...
<form-property name="comboValues" type="java.lang.String[]" />
<form-property name="singleListValues" type="java.lang.String[]" />
<form-property name="multipleListValues" type="java.lang.String[]"/>
</form-bean>
Once the valuesCombo, valuesSingleList, and valuesMultipleList arrays have been initialized by InitFormAction, they no longer need to be initialized. This is because the dynaForm object is placed in the session and therefore retains its value across request-response cycles. This is why the /init action is executed only once. The code for InitFormAction is as follows:
package istia.st.struts.formulaire;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class InitFormAction
extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// prepares the form to be displayed
// populate the form bean with the necessary information
DynaFormulaire form = (DynaFormulaire) form;
form.set("comboValues", getValues(5, "combo"));
form.set("singleListValues", getValues(7, "single"));
form.set("multipleListValues", getValues(10, "multiple"));
// return control
return mapping.findForward("displayForm");
} //execute
// list of combo box values
private String[] getValues(int size, String label) {
String[] values = new String[size];
for (int i = 0; i < size; i++) {
values[i] = label + i;
}
return values;
}
}
- The class extends the Action class. This is mandatory.
- The Struts controller uses an Action object via its execute method. This is therefore the method that must be redefined. This method receives the following parameters:
- ActionMapping mapping: an object representing the application configuration in struts-config.xml
- ActionForm form: the form associated with the action, if one is defined in the action’s configuration (the action’s name attribute).
- HttpServletRequest request: the client request
- HttpServletResponse: the response to the client
- The InitFormulaireAction class must initialize the dynaFormulaire form. This is passed to the execute method as the ActionForm form parameter. Recall that dynaFormulaire is of type DynaFormulaire, a class derived from the DynaActionForm class, which itself is derived from the ActionForm class.
- In the execute method, values are assigned to the three fields valeursCombo, valeursListeSimple, and valeursListeMultiple using the set method of the DynaActionForm class. These values are arbitrary arrays for the sake of simplicity. Note that the set method assigns a value to an existing field. It cannot be used to create new fields. This is why it is necessary to define the three fields valeursCombo, valeursListeSimple, and valeursListeMultiple in the definition of the dynaFormulaire object in struts-config.xml.
- The execute method ends by returning the key of the view to be displayed to the controller as a response to the client. Here, it is the afficherFormulaire key, which in the struts-config.xml file has been associated with the /vues/formulaire.jsp view.
6.6. Deployment
The application directory structure is as follows:
![]() | ![]() |
![]() | ![]() |


Note that the ApplicationResources.properties file above is required by the struts-bean tag library. We know that this file contains the application’s messages. These are accessible to the struts-bean library. Here, our application does not define any messages. Therefore, the ApplicationResources.properties file exists but is empty.
6.7. Conclusion
In this lesson, we have detailed how to manage the various components of an HTML form. We can now use complex forms in our Struts applications.






