6. Formularios HTML
Hasta ahora, hemos utilizado un único formulario que solo incluye dos campos de entrada. Aquí nos proponemos crear y procesar un formulario utilizando los componentes gráficos habituales (botones de radio, casillas de verificación, campos de entrada, cuadros combinados, listas).
6.1. Las vistas de la aplicación
La aplicación solo tendrá dos vistas. La primera presenta un formulario en blanco:
QZXW2HTMLP000638ZQX 1 - formulaire

Esta primera vista, denominada formulaire.jsp, nos permitirá implementar diferentes etiquetas de la biblioteca struts-html. El usuario rellena el formulario:

El botón [Envoyer] permite obtener una confirmación de los valores introducidos. Esta será la segunda vista:

Esta segunda vista nos permitirá utilizar otras dos bibliotecas de etiquetas: struts-bean y struts-logic. El enlace [Retour au formulaire] nos permite volver al formulario tal y como lo hemos rellenado. Así volvemos a la primera vista.
6.2. La arquitectura de la aplicación
![]() |
- El formulario (vista 1) estará representado por un objeto Struts dinámico denominado dynaFormulaire, de un tipo derivado de DynaActionForm. Se mostrará mediante la vista formulaire.jsp.
- La acción Struts InitFormulaireAction tendrá como objetivo obtener los datos necesarios para mostrar el formulario
- el formulario rellenado será procesado por una acción ForwardAction, que se encargará de redirigir la solicitud a la segunda vista confirmation.jsp. Esta se encargará de mostrar los valores del formulario.
6.3. Configuración de la aplicación
6.3.1. El archivo server.xml
El contexto de la aplicación se llamará /formulario2. Por lo tanto, añadiremos la siguiente línea en el archivo server.xml de Tomcat:
Una vez hecho esto, reiniciamos Tomcat para que tenga en cuenta el nuevo contexto. Podemos comprobar su validez solicitando el URL http://localhost:8080/formulaire2:

6.3.2. El archivo web.xml
El archivo de configuración web.xml de la aplicación será el siguiente:
<?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>
En cuanto a los archivos de configuración web.xml que ya hemos visto, realizamos algunas modificaciones:
- introducimos dos nuevas bibliotecas de etiquetas: struts-bean y struts-logic. Se utilizarán en la vista confirmation.jsp. La vista formulaire.jsp utilizará, por su parte, la biblioteca struts-html.
6.3.3. El archivo struts-config.xml
El archivo struts-config.xml será el siguiente:
<?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="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<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="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
</form-beans>
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
<message-resources
parameter="ApplicationResources"
null="false"/>
</struts-config>
Aquí encontramos las tres secciones principales:
- la declaración de los formularios en la sección <form-beans>
- la declaración de las acciones en la sección <action-mappings>
- la declaración del archivo de recursos en <message-resources>
6.3.4. Los objetos (beans) de formulario de la aplicación
Los objetos utilizados para representar los formularios HTML de la aplicación son objetos de tipo ActionForm o derivados (DynaActionForm, DynaValidatorForm, ...). Se denominan beans porque su construcción sigue las reglas de los JavaBeans. Solo hay un bean de formulario en nuestra aplicación, llamado dynaFormulaire y de tipo derivado de DynaActionForm. Se utilizará en las siguientes situaciones:
- contener los datos necesarios para mostrar la vista n.º 1
- recuperar los valores del formulario de la vista n.º 1 cuando el usuario lo valide (submit)
- contener los datos necesarios para mostrar la vista n.º 2
La estructura del bean dynaFormulaire está íntimamente ligada al formulario de la vista n.º 1. Analicémoslo:
![]() |
N.º | Tipo HTML | Función |
<input name="opt" type="radio" value="sí"> <input name="opt" type="radio" value="no"> | grupo de botones de radio vinculados entre sí (mismo nombre) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | grupos de casillas de verificación independientes (no tienen el mismo nombre) | |
<input type="text " name="champSaisie" > | un campo de entrada | |
<input type="password" name="mdp"> | un campo de contraseña | |
<textarea name="boiteSaisie">...</textarea> | un campo de entrada de varias líneas | |
<select name="combo" size="1">..</select> | un cuadro combinado | |
<select name="listeSimple" size="3">..</select> | una lista de selección única | |
<select name="listeMultiple" size="3" multiple>..</select> | una lista de selección múltiple | |
<input type="button" value="Borrar" onclick='effacerListe("listeSimple")'> | botón que permite deseleccionar los elementos seleccionados en listeSimple (7) | |
<input type="button" value="Borrar" onclick='effacerListe("listeMultiple")'> | botón que permite deseleccionar los elementos seleccionados en listeMultiple (8) | |
<input type="submit" value="Enviar"> | botón submit del formulario | |
<input type="hidden" name="secret" value="..."> | un campo oculto |
Distinguamos varios casos:
- el objeto dynaFormulaire se utiliza para contener los valores del formulario HTML anterior, que se enviará mediante el botón [Envoyer]. Por lo tanto, debe tener los mismos campos que el formulario HTML. El tipo de campo viene determinado por la siguiente regla:
- si el campo HTML solo proporciona un valor, entonces el campo de dynaFormulaire será de tipo java.lang.String
- si el campo HTML proporciona varios valores, entonces el campo dynaFormulaire será de tipo java.lang.String[]
En el formulario HTML anterior, solo el campo listeMultiple puede estar asociado a varios valores (los seleccionados por el usuario). Por lo tanto, una primera definición del objeto dynaFormulaire sería la siguiente:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<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="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
</form-bean>
¿Cómo se rellenará dynaFormulaire con los valores del formulario HTML enviados por el cliente web?
el campo opt recibirá el valor «sí» si se ha marcado el campo HTML <input type="radio" name="opt" value="sí">, el valor «no» si se ha marcado el campo <input type="radio" name="opt" value="no">. | |
el campo chk1 recibirá el valor «on» si se ha marcado el campo HTML <input name="chk1" type="radio" value="1">, y nada en caso contrario. En este último caso, el campo chk1 conservará su valor anterior. | |
ídem | |
ídem | |
El campo champSaisie recibirá el texto introducido por el usuario en el campo HTML <input type="text" name="champSaisie">. Este texto puede ser, en su caso, la cadena vacía. | |
El campo mdp recibirá el texto introducido por el usuario en el campo HTML <input type="password" name="mdp">. Este texto puede ser, en su caso, una cadena vacía. | |
El campo boiteSaisie recibirá el texto introducido por el usuario en el campo HTML <textarea name="boiteSaisie">...</textarea>. Este texto forma una única cadena de caracteres, compuesta por las líneas escritas por el usuario y separadas entre sí por la secuencia de caracteres «\r\n». El texto obtenido puede ser, en su caso, la cadena vacía. | |
El campo combo recibirá el valor option seleccionado por el usuario en el campo HTML <select name="combo" size="1">..</select>. La opción option seleccionada es la que aparece en el cuadro combinado. Si el option HTML seleccionado es del tipo <option value="XX">YY</option>, el campo desplegable recibirá el valor «XX». Si la selección option HTML es del tipo <option>YY</option>, el campo desplegable recibirá el valor «YY». | |
el campo listeSimple recibirá el valor option seleccionado por el usuario en el campo HTML <select name="listeSimple" size="..">..</select> si hay alguno. Si no hay ninguno, el campo listeSimple no recibirá ningún valor y mantendrá su valor anterior. El valor asignado realmente al campo listeSimple sigue las reglas indicadas para el combo. | |
el campo listeMultiple de tipo String[] recibirá las opciones seleccionadas por el usuario en el campo HTML <select name="listeMultiple" size=".." multiple>..</select> si las hay. Si no las hay, la matriz listeMultiple no recibirá ningún valor y su contenido permanecerá sin cambios. Los valores asignados realmente a la tabla listeMultiple siguen las reglas indicadas para el combo. | |
el campo «secret» recibirá el valor XX del campo HTML <input type="hidden" name="secret" value="XX">. Este texto puede ser, en su caso, la cadena vacía. |
- El objeto dynaFormulaire se utiliza para proporcionar el contenido inicial de la vista n.º 1. Los valores de los campos anteriores se utilizarán para los siguientes fines:
deberá tener el valor «sí» o «no» para que el navegador sepa qué botón de opción marcar | |
si chk1 tiene el valor «on», la casilla de verificación estará marcada; de lo contrario, no lo estará | |
Lo mismo | |
Lo mismo | |
el valor del campo se mostrará en el campo de entrada champSaisie | |
el valor del campo se mostrará en el campo de entrada mdp | |
el valor del campo se mostrará en el campo de entrada boiteSaisie | |
El valor de este campo indica qué elemento del menú desplegable debe seleccionarse al mostrar el formulario | |
Lo mismo | |
Los valores de la tabla listeMultiple indican qué elementos de la lista múltiple deben seleccionarse al visualizar el formulario | |
el valor del campo se asignará al atributo «value» del campo secreto HTML. |
La vista n.º 1 necesita más información:
- la lista de valores que se mostrarán en la lista desplegable
- la lista de valores que se mostrarán en la lista listeSimple
- la lista de valores que se deben mostrar en la lista listeMultiple
Hay varias formas de proporcionar esta información a la vista. Por ejemplo, unas tablas incluidas en la consulta pasada a la vista servirían para ello. Aquí, colocamos estas tablas en el bean dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
El formulario dynaFormulaire se inicializará mediante la acción /init, que llamará a un objeto derivado de Action denominado InitFormulaireAction. Este objeto se encargará de crear las tres tablas necesarias para mostrar las tres listas y de colocarlas en el bean dynaFormulaire. El archivo de configuración asigna a este bean un ámbito igual al de la sesión. Esto implica que el controlador Struts colocará este bean en la sesión. De este modo, no será necesario regenerarlo entre dos ciclos de solicitud-respuesta. Por lo tanto, la acción /init solo se llamará una vez.
- El objeto dynaFormulaire también se utiliza para proporcionar el contenido de la vista n.º 2. Esta se limita a mostrar los valores.
6.3.5. Las acciones de la aplicación
Las acciones son gestionadas por objetos de tipo Action o derivados. La configuración de las acciones se realiza dentro de las etiquetas <action-mappings>:
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
Cabe señalar que no siempre hay un formulario asociado a una acción. Este es el caso, arriba, de la acción /affiche. Antes de detallar cada acción, recordemos el funcionamiento del par acción-formulario asociado dentro de una etiqueta <action>:
- una acción comienza con una solicitud de un cliente web y termina con el envío de una página de respuesta. Este es el ciclo de solicitud-respuesta del cliente-servidor web. La solicitud es recibida por el controlador Struts de tipo ActionServlet o derivado. Este mismo controlador es el que envía la respuesta.
- Se crea el bean del formulario de tipo ActionForm o derivado si aún no existe. El controlador comprueba si puede encontrar un objeto con el nombre name en el ámbito indicado por scope. Si es así, lo utiliza. Si no, lo crea y lo coloca en el ámbito indicado por scope, asociado al atributo indicado por name.
En el ejemplo de la acción /init, por ejemplo, el controlador realizará un request.getSession().getAttribute("dynaFormulaire") para saber si dynaFormulaire ya se ha creado o no. Si no es así, lo creará y lo incluirá en la sesión mediante una instrucción del tipo request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- El controlador también buscará un objeto Action del tipo indicado por el atributo type. Si no lo encuentra, lo creará; de lo contrario, lo utilizará.
- Se llamará al método reset del bean de formulario. Este, salvo en el momento de su creación inicial, se recicla. Por lo tanto, contiene datos que quizá se desee «limpiar». Esto se hará en el método reset del bean ActionForm o de un derivado del mismo.
- Si la acción es el destino de un formulario enviado, los valores del formulario que se encuentran en la solicitud del cliente se copian en los campos del mismo nombre del bean de formulario. Cabe señalar que el método reset se ha llamado antes de esta copia.
- Si la configuración especifica el atributo validate="true", se llamará al método validate del bean formulario. Este debe entonces verificar los datos del bean. Esta verificación suele tener lugar únicamente cuando el formulario acaba de recibir nuevos datos a través de un formulario enviado y se desea comprobar la validez de dichos datos. Este método devuelve al controlador una posible lista de errores en un objeto ActionErrors.
- Si el objeto ActionErrors no está vacío, el controlador muestra la vista especificada por el atributo input de la acción.
- Si no se solicita la validación de los datos o si esta se ha realizado correctamente, el controlador ejecuta el método execute del objeto de tipo Action o derivado asociado a la acción en curso. Es en este método donde se procesa la solicitud del cliente web. El método execute devuelve un objeto ActionForward indexado por claves de tipo cadena de caracteres. Estas claves son las declaradas por las etiquetas forward de la acción configurada. En nuestro ejemplo, la acción /init tiene una sola etiqueta forward. Asocia la clave «afficherFormulaire» a la vista formulaire.jsp.
- El controlador muestra la vista a la que está asociada la clave recibida. Esta vista puede ser, de hecho, una acción, en cuyo caso se repite el proceso anterior.
La acción /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- La acción /init se produce normalmente una vez durante el primer ciclo de solicitud-respuesta cuando el usuario solicita el URL http://localhost:8080/formulario2/init.do
- se crea o recicla el objeto dynaFormulaire. Se recupera (reciclaje) o se coloca (creación) en la sesión según lo indique el atributo scope.
- Se llama a su método reset. ¿Qué debe hacer? Normalmente, se restablecen los campos del objeto ActionForm a sus valores por defecto. Sin embargo, en este caso no lo haremos, ya que el objeto dynaFormulaire se coloca en la sesión (scope="session"). Por lo tanto, los campos de dynaFormulaire deben conservar sus valores. ¿Cuáles son estos valores en el momento de la creación inicial del objeto dynaFormulaire? Hay dos casos:
- el campo tiene un valor inicial indicado en el archivo de configuración:
En este caso, el controlador Struts creará este campo con este valor inicial.
- el campo no tiene un valor inicial por configuración: se aplican las reglas de inicialización de Java. En general, los campos numéricos tendrán el valor cero, las cadenas de caracteres tendrán como valor la cadena vacía y los demás objetos tendrán el valor null.
Veamos la configuración inicial de dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<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="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Los valores iniciales de los campos de dynaFormulaire tras su creación serán los siguientes:
Campo | Valor inicial |
«no» | |
cadena vacía | |
cadena vacía | |
cadena vacía | |
cadena vacía | |
cadena vacía | |
cadena vacía | |
matriz de cadenas vacías | |
"xxx" | |
matriz de cadenas vacías |
- Podríamos imaginar que el método reset de dynaFormulaire asigna valores a las tres tablas que deben alimentar las tres listas de la vista formulaire.jsp. Esto sería posible aquí, ya que los datos de estas tres tablas se generan de forma arbitraria. Sin embargo, lo más habitual es que estos datos procedan del modelo de la aplicación, el M de MVC. Aquí adoptaremos una posición intermedia, para no complicar el ejemplo, haciendo que estos valores sean generados por la acción InitFormulaireAction, es decir, por el C de MVC.
- No es obligatorio escribir un método reset en dynaFormulaire, ya que la clase ActionForm de la que deriva tiene un método de este tipo que no hace nada (sin inicializaciones).
- Una vez llamado el método reset de dynaFormulaire, el controlador comprueba el atributo validate de la acción. En este caso, tiene el valor «false». El método validate de dynaFormulaire no se llamará.
- Se crea el objeto InitFormulaireAction o se recicla si ya existía, y se ejecuta su método execute. Es este método el que asignará valores arbitrarios a las tres matrices de dynaFormulaire: valeursCombo, valeursListeSimple y valeursListeMultiple. El método devuelve un ActionForward con la clave «afficherFormulaire».
- El controlador muestra la vista /vues/formulaire.jsp, que se ha asociado a la clave «afficherFormulaire» mediante una etiqueta forward de la acción /init.
La acción /confirmation
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- La acción /confirmation se produce cuando el usuario pulsa el botón [Envoyer] de la vista n.º 1. A continuación, el navegador «envía» al controlador Struts el formulario rellenado por el usuario.
- El objeto dynaFormulaire se toma de la sesión
- y se invoca su método reset. Una vez invocado, el controlador Struts copiará los valores de los campos del formulario enviado por el cliente en los campos del mismo nombre de dynaFormulaire. Repasemos la lista de campos de este último y veamos cómo se realiza esta copia:
Campo | Código HTML asociado | Valor del campo tras la copia de los valores del formulario |
<input type="radio" name="opt" value="sí">Sí <input type="radio" name="opt" value="no" checked="checked">No | - «sí» o «no» según el botón de radio seleccionado | |
<input type="checkbox" name="chk1" value="on"> | - «on» si se ha marcado la casilla chk1 - mantiene su valor anterior si no se ha marcado la casilla chk1 | |
<input type="checkbox" name="chk2" value="on"> | - «on» si se ha marcado la casilla chk2 - mantiene su valor anterior si la casilla chk2 no se ha marcado | |
<input type="checkbox" name="chk2" value="on"> | - «on» si se ha marcado la casilla chk3 - mantiene su valor anterior si la casilla chk3 no se ha marcado | |
<input type="text" name="champSaisie" value=""> | - valor introducido por el usuario en champSaisie | |
<input type="password" name="mdp" value=""> | - valor introducido por el usuario en mdp | |
<textarea name="boiteSaisie"></textarea> | - valor introducido por el usuario en boiteSaisie | |
<select name="combo">...</select> | - valor seleccionado por el usuario en combo | |
<select name="listeSimple" size="3">...</select> | - valor seleccionado por el usuario en listeSimple | |
<select name="listeMultiple" multiple="multiple" size="5"> | - matriz de cadenas que contiene los valores seleccionados por el usuario en listeMultiple | |
<input type="hidden" name="secret" value="xxx"> | - «xxx». |
Tenemos un problema con los campos que no reciben necesariamente un valor en la solicitud enviada por el navegador. Es el caso de las casillas de verificación chk1 a chk3 y de las dos listas listeSimple y listeMultiple. En este caso, estos campos conservan su valor anterior, el adquirido durante el ciclo de solicitud-respuesta anterior.
Analicemos, por ejemplo, la casilla de selección chk1 y supongamos que, en el ciclo de solicitud-respuesta anterior, el usuario había marcado esta casilla. El navegador habría enviado entonces en la cadena de parámetros de su solicitud la información chk1="on". El desarrollador asignó, por tanto, el valor «on» al campo chk1 de dynaFormulaire. Supongamos ahora que, en el ciclo actual, el usuario no marca la casilla chk1. En este caso, en la cadena de parámetros de la nueva solicitud, el navegador no envía algo como chk1="off", sino que no envía nada. Por lo tanto, el campo chk1 de dynaFormulaire mantendrá su valor «on» y, por lo tanto, tendrá un valor que no refleja el del formulario validado por el usuario. Utilizaremos el método reset de dynaFormulaire para resolver este problema. En este método pondremos los tres campos chk1, chk2 y chk3 en «off». En nuestro ejemplo de chk1, si el usuario:
- marca la casilla chk1. Entonces, el navegador envía la información chk1="on" y el campo chk1 de dynaFormulaire pasará a «on».
- no marque la casilla chk1. En ese caso, el navegador no envía ningún valor para el campo chk1, que mantendrá su valor anterior «off». En ambos casos, el valor registrado en el campo chk1 de dynaFormulaire es correcto.
El problema es similar para las dos listas listeSimple y listeMultiple. Si no se ha seleccionado ningún option en estas listas, no aparecerán en los parámetros de la consulta y, por lo tanto, conservarán sus valores anteriores. En el método reset de dynaFormulaire, reiniciaremos listeSimple con una cadena vacía y listeMultiple con una matriz de cadenas de longitud 0.
- Una vez llamado el método reset de dynaFormulaire, el controlador copia en los campos de dynaFormulaire la información que se le ha enviado en la solicitud del cliente
- Se crea o recicla un objeto ForwardAction y se invoca su método execute. ForwardAction es una clase predefinida que devuelve un objeto ActionForward que apunta a la vista definida por el atributo «parameter» de la acción, en este caso /vues/confirmation.jsp.
- El controlador envía esta vista. El ciclo ha finalizado.
La acción /muestra
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- La acción /affiche se activa al hacer clic en el enlace [Retour vers le formulaire] de la vista n.º 2.
- Aquí no hay ningún formulario asociado a la acción. Por lo tanto, se pasa inmediatamente a la ejecución del método execute de un objeto ForwardAction, que devolverá un objeto ActionForward que apunta a la vista /vues/formulaire.jsp.
6.3.6. El archivo de mensajes de la aplicación
La tercera sección del archivo struts-config.xml es la del archivo de mensajes:
El archivo ApplicationResources.properties se encuentra en WEB-INF/classes. Estará vacío. Aunque esté vacío, debe declararse en el archivo de configuración; de lo contrario, la biblioteca de etiquetas struts-bean, que veremos más adelante, generará un error. Esta biblioteca es utilizada por la vista confirmation.jsp.
6.4. El código de las vistas
6.4.1. La vista formulaire.jsp
Recordemos que esta vista se muestra en dos casos:
- al llamar a la acción /init durante el primer ciclo de solicitud-respuesta
- al llamar a la acción /affiche en los ciclos siguientes
El código de la vista formulaire.jsp es el siguiente:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>formulaire</title>
</head>
<body background='<html:rewrite page="/images/standard.jpg"/>'>
<h3>Formulaire Struts</h3>
<hr>
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<table border="0">
<tr>
<td>bouton radio</td>
<td>
<html:radio name="dynaFormulaire" property="opt" value="oui">Oui</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="non">Non</html:radio>
</td>
</tr>
<tr>
<td>Cases à cocher</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>Champ de saisie</td>
<td>
<html:text name="dynaFormulaire" property="champSaisie" />
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<html:password name="dynaFormulaire" property="mdp" />
</td>
</tr>
<tr>
<td>Boîte de saisie multilignes</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="valeursCombo"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection unique</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
</td>
</tr>
</table>
<td>
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection multiple</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" 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="valeursListeMultiple"/>
</html:select>
</td>
</tr>
</table>
<html:hidden name="dynaFormulaire" property="secret"/>
<br>
<hr>
<html:submit>Envoyer</html:submit>
</html:form>
</body>
</html>
Esta página JSP utiliza etiquetas procedentes de la biblioteca struts-html. Recordemos que para utilizar una biblioteca de etiquetas, es necesario:
- declararla en el archivo web.xml de la aplicación con una etiqueta <tag-lib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- colocar el código de esta biblioteca en algún lugar del árbol de la aplicación, aquí WEB-INF/struts-html.tld
- Declare el uso de esta biblioteca al principio de las páginas JSP que la utilizan:
La vista formulaire.jsp utiliza etiquetas que explicamos a continuación:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
La etiqueta html:rewrite permite prescindir del nombre de la aplicación en URL. Tiene un atributo:
Así, en el ejemplo anterior, si decidimos llamar a la aplicación «formulario3», no es necesario reescribir el código del atributo background. La etiqueta html:rewrite generará el nuevo código HTML background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
La etiqueta html:form permite generar la etiqueta HTML form. Tiene varios atributos:
Se observa que, por defecto, el código HTML generado utiliza el método POST. En este mismo código HTML, el URL de la acción se ha reescrito para que vaya precedido del nombre de la aplicación y seguido de .do. |
<html:radio name="dynaFormulaire" property="opt" value="sí">Sí</html:radio> | |||||||
La etiqueta html:radio sirve para generar la etiqueta HTML <input type="radio" ...>. Admite varios atributos:
El texto entre la etiqueta de inicio y la de fin es el texto que se mostrará junto al botón de radio. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
La etiqueta html:checkbox sirve para generar la etiqueta HTML <input type="checkbox" ...>. Admite varios atributos:
El texto entre la etiqueta de inicio y la de fin es el texto que se mostrará junto a la casilla de verificación. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |||||||
La etiqueta html:text sirve para generar la etiqueta HTML <input type="text" ...>. Admite varios atributos:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
La etiqueta html:password sirve para generar la etiqueta HTML <input type="password" ...>. Admite varios atributos: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
La etiqueta html:textarea sirve para generar la etiqueta HTML <textarea>...</textarea>. Admite varios atributos:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
La etiqueta html:select sirve para generar la etiqueta HTML <select>...</select>. Admite varios atributos:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |||||
La etiqueta html:options sirve para generar las etiquetas HTML <option>...</option> dentro de una etiqueta HTML <select>. Hay varias formas de especificar cómo encontrar los valores de relleno del select. Aquí hemos utilizado los atributos name y property :
|
Las otras dos listas se generan de forma análoga a la anterior:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
En el ejemplo anterior, se especifica un atributo size distinto de 1 para obtener una lista en lugar de un cuadro combinado.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
En el ejemplo anterior, se especifica el atributo multiple="true" para obtener una lista de selección múltiple.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
La etiqueta html:hidden sirve para generar la etiqueta HTML <input type="hidden" ...>.
|
Para comprender bien la relación entre la vista formulaire.jsp y el bean dynaFormulaire que la representa en memoria, hay que recordar que el bean dynaFormulaire se utiliza tanto para lectura como para escritura:
![]() |
La solicitud se produce cuando el usuario hace clic en el botón [Envoyer] del formulario. El navegador «envía» entonces el formulario HTML a la acción /confirmation. Ya hemos explicado lo que ocurre entonces y, en particular, que los campos de dynaFormulaire recibirán los valores de los campos del mismo nombre del formulario HTML.
¿Qué ocurre cuando el controlador solicita la visualización de la vista formulaire.jsp en respuesta a una solicitud? Repasemos las etiquetas una por una:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
genera el código HTML |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
genera el código HTML |
<html:radio name="dynaFormulaire" property="opt" value="sí">Sí</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">No</html:radio> | |
Si el campo opt de dynaFormulaire es «sí», genera el código HTML |
<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> | |
Si los campos chk1 y chk3 de dynaFormulaire tienen el valor «on» y el campo chk2 tiene el valor «off», genera el código HTML |
<html:text name="dynaFormulaire" property="champSaisie" /> | |
si el campo champSaisie tiene el valor «esto es una prueba», genera el código HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
si el campo mdp es «azerty», genera el código HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
si el campo mdp es «azerty», genera el código HTML |
<html:contraseña name="dynaFormulaire" propiedad="mdp" /> | |
si el campo mdp es «azerty», genera el código HTML |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |
si el campo combo tiene el valor «combo2», genera el código HTML |
<html:select name="dynaFormulaire" property="listeSimple" size="3"> <html:options name="dynaFormulaire" property="valeursListeSimple"/> </html:select> | |
si el campo listeSimple tiene el valor «simple1», genera el código HTML |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="valeursListeMultiple"/> </html:select> | |
si el campo listeMultiple es la matriz {"multiple0","multiple2"}, genera el código HTML |
<html:hidden name="dynaFormulaire" property="secret"/> | |
si el campo secreto tiene el valor «xxx», genera el código HTML |
<html:submit>Enviar</html:submit> | |
genera el código HTML |
Lo último que hay que explicar es el código javascript incluido en la página JSP y vinculado a los dos botones [Effacer] que deseleccionan los elementos seleccionados en las listas listeSimple y listeMultiple:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
La etiqueta
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
genera el siguiente código HTML:
Para comprender el código Javascript relacionado con los botones [Effacer], recordemos cómo se designan los diferentes elementos de un documento web dentro de un código Javascript que utiliza dicho documento:
Dato | Significado |
designa la totalidad del documento web | |
designa la colección de formularios definidos en el documento | |
designa el formulario n.º i del documento | |
designa el formulario <form> que tiene el atributo name igual a «nomFormulaire» | |
designa el formulario <form> que tiene el atributo name igual a «nomFormulaire» | |
designa la colección de elementos miembros del formulario designado por la expresión [formulaire]. Esta colección incluye todas las etiquetas <input>, <textarea>, <select> del formulario designado. | |
designa el elemento n.º i de [formulaire] | |
designa el elemento de [formulaire] que tiene el atributo name igual a nomComposant | |
designa el elemento de [formulaire] que tiene el atributo name igual a nomComposant | |
designa el valor del componente [composant] del formulario [formulaire] cuando el código HTML de este puede tener un atributo value (<input>, <textarea>) | |
designa el índice del option seleccionado en una lista. Se utiliza en lectura y escritura. Establecer esta propiedad en -1 deselecciona todos los elementos de la lista. | |
designa la matriz de opciones asociadas a una etiqueta <select> | |
designa el option n.º i de la etiqueta <select> indicada | |
booleano que indica si el n.º i de la etiqueta [select] indicada está seleccionado (true) o no. Se puede utilizar en lectura y escritura |
Volvamos al código javascript de los dos botones:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Al hacer clic en el botón, se ejecuta el código asociado al atributo «onclick». En este caso, se trata de un código en línea. Lo más habitual es escribir onclick="función(...)", donde función es una función definida dentro de una etiqueta <script language="javascript">...</script>. ¿Qué hace el código anterior? Comentemos el código del primer botón:
designa el documento web en el que se encuentra el botón | |
designa el formulario en el que se encuentra el botón | |
designa el componente listeSimple del formulario | |
indica el índice del option seleccionado en listeSimple. Establecer esta propiedad en -1 deselecciona todos los option. |
6.4.2. La vista confirmation.jsp
Recordemos que esta vista se muestra al finalizar la acción/confirmación c.a.d, después de que el cliente web haya enviado el formulario contenido en la vista formulaire.jsp. Su único objetivo es mostrar los valores introducidos por el usuario. Su código es el siguiente:
<%@ 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 des valeurs saisies</h3>
<hr/>
<table border="1">
<tr>
<td>Bouton radio</td>
<td><bean:write name="dynaFormulaire" scope="session" property="opt"/></td>
</tr>
<tr>
<td>Case à cocher chk1</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk1"/></td>
</tr>
<tr>
<td>Case à cocher chk2</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk2"/></td>
</tr>
<tr>
<td>Case à cocher chk3</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk3"/></td>
</tr>
<tr>
<td>Champ de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="champSaisie"/></td>
</tr>
<tr>
<td>Mot de passe</td>
<td><bean:write name="dynaFormulaire" scope="session" property="mdp"/></td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="boiteSaisie"/></td>
</tr>
<tr>
<td>combo</td>
<td><bean:write name="dynaFormulaire" scope="session" property="combo"/></td>
</tr>
<tr>
<td>liste simple</td>
<td><bean:write name="dynaFormulaire" scope="session" property="listeSimple"/></td>
</tr>
<logic:iterate id="choix" indexId="index" name="dynaFormulaire" property="listeMultiple">
<tr>
<td>liste multiple[<bean:write name="index"/>]</td>
<td><bean:write name="choix"/></td>
</tr>
</logic:iterate>
</table>
<br>
<html:link page="/affiche.do">
Retour au formulaire
</html:link>
</body>
</html>
Aquí introducimos dos nuevas bibliotecas de etiquetas: struts-bean y struts-logic. La biblioteca struts-bean permite acceder a objetos situados en la solicitud, la sesión o el contexto de la aplicación. La biblioteca struts-logic permite introducir lógica de ejecución mediante etiquetas. Estas dos bibliotecas no son en absoluto imprescindibles. Como hemos visto, una página JSP puede:
- recuperar objetos de la solicitud (request.getAttribute(...)), la sesión (session.getAttribute(...)) o el contexto de la aplicación
- incluir partes dinámicas en el código HTML mediante variables <%= variable %>
- contener código Java <% código Java %>
La inclusión de código Java en las páginas JSP molesta a todos aquellos que desean una separación estricta entre la lógica de la aplicación (código Java) y la presentación (uso de etiquetas). Por eso se han creado bibliotecas de etiquetas para ellos.
Procederemos como en la vista formulaire.jsp y explicaremos cada una de las etiquetas presentes en el código de confirmation.jsp si aún no se han encontrado en la vista formulaire.jsp. En primer lugar, observemos que la página comienza declarando las tres bibliotecas de etiquetas que va a utilizar:
<%@ 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" %>
Recordemos también que estas tres bibliotecas deben declararse en el archivo web.xml de la aplicación. A continuación, comentamos las etiquetas del documento formulaire.jsp:
escribe un valor en el flujo HTML actual. La etiqueta bean:write admite los siguientes atributos: name: nombre del objeto que se va a utilizar scope: ámbito (solicitud, sesión, contexto) en el que buscar este objeto property: campo del objeto designado por name cuya propiedad se debe escribir. Este campo puede ser un objeto de cualquier tipo. Se utilizará el método toString del objeto. Aquí se escribe el valor del campo opt de dynaFormulaire. Se obtendrá «sí» si el usuario ha marcado el botón de opción con el atributo value="sí", o «no» si ha marcado el botón de opción con el atributo value="no" |
escribe el valor del campo chk1 de dynaFormulaire. Se obtendrá «on» si el usuario ha marcado la casilla, o «off» en caso contrario. Lo mismo ocurre con chk2 y chk3. |
escribe el valor del campo champSaisie de dynaFormulaire, es decir, el texto introducido por el usuario en ese campo. Lo mismo ocurre con la contraseña, boiteSaisie. |
escribe el valor del campo combinado de dynaFormulaire. Tendremos el atributo value del elemento <option> seleccionado por el usuario. |
escribe el valor del campo listeSimple de dynaFormulaire. Se obtendrá el atributo value del elemento <option> seleccionado por el usuario, si lo hubiera. De lo contrario, se obtendrá la cadena vacía. |
Aquí introducimos etiquetas de lógica. Se trata de una lista de selección múltiple. El valor del campo listeMultiple del objeto dynaFormulaire es una matriz de String. En Java, escribiríamos un bucle. La etiqueta logic:iterate nos permite realizar este mismo bucle sin escribir código Java. La etiqueta logic:iterate tiene en el ejemplo los siguientes atributos: name="dynaFormulaire": nombre del objeto que se va a utilizar property="listeMultiple": nombre de la propiedad que, en el objeto indicado por name, contiene la colección que se recorrerá en el bucle. En este caso, dicha colección es la matriz de valores seleccionados en listeMultiple. Esta matriz puede estar vacía. id="selección": identificador que designa el elemento actual de la matriz en cada vuelta del bucle. En la primera iteración, «selección» representará listeMultiple[0]; en la segunda, listeMultiple[1], y así sucesivamente. indexID="index": identificador que designa el índice del elemento actual de la matriz en cada iteración del bucle. En la primera iteración, index tendrá el valor 0, en la segunda el valor 1 y así sucesivamente. El código HTML contenido entre las etiquetas <logic:iterate ...> y </logic:iterate> se repite para cada elemento de la colección designada por el par (name,property). La parte dinámica de este código es la siguiente:
De lo dicho anteriormente, en la iteración n.º i (i>=0), el código HTML generado es equivalente al siguiente código: |
genera un enlace relativo al contexto de la aplicación, lo que evita tener que conocerlo. El código HTML generado por esta etiqueta es el siguiente: |
6.5. Las clases Java
El archivo de configuración struts-config.xml hace referencia a dos clases Java:
<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"
>
La clase DynaFormulaire es la clase que contendrá los valores de la vista n.º 1 formulaire.jsp. La clase InitFormulaireAction es la clase que procesará los valores del formulario enviado mediante el botón [Envoyer] de formulaire.jsp.
6.5.1. La clase DynaFormulaire
Para contener los valores de un formulario, basta con un objeto de tipo DynaActionForm, salvo que sea necesario redefinir alguno de los métodos reset o validate de esta clase. En este caso, no es necesario redefinir el método validate, ya que no se realiza ninguna validación de datos. Sin embargo, el método reset sí debe redefinirse. De hecho, los campos del objeto DynaFormulaire recibirán sus valores del formulario enviado por el cliente web. Ahora bien, algunos campos pueden no recibir ningún valor si no están presentes en la solicitud. Esto ocurre en los siguientes casos:
- una casilla de selección que el usuario no ha marcado
- una lista con más de un elemento o no se ha seleccionado ningún option
En los formularios que contengan este tipo de componente, el método reset debe
- asignar el valor «off» al campo asociado a la casilla de verificación
- asignar la cadena vacía al campo asociado a una lista de selección única
- asignar una matriz de cadenas de caracteres de tamaño nulo al campo asociado a una lista de selección múltiple
De este modo, si estos campos no reciben ningún valor de la consulta, conservan el valor asignado por reset, valor que corresponde al estado del componente en el formulario validado por el usuario (casilla sin marcar, lista sin ningún elemento seleccionado).
El código de la clase DynaFormulaire, clase derivada de DynaActionForm, es el siguiente:
package istia.st.struts.formulaire;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class DynaFormulaire extends DynaActionForm {
public void reset(ActionMapping mapping, HttpServletRequest request){
// restablecimiento de las casillas de verificación: valor desactivado
set("chk1","off");
set("chk2","off");
set("chk2","off");
// restablecimiento de listeSimple - cadena vacía
set("listeSimple","");
// restablecimiento de listeMultiple - matriz vacía
set("listeMultiple",new String[]{});
}
}
6.5.2. La clase InitFormulaireAction
La clase InitFormulaireAction está, en el archivo struts-config.xml, asociada a la acción /init:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
La acción /init solo se utiliza una vez durante la construcción inicial del objeto DynaFormulaire. Su objetivo es proporcionar contenido a las tres listas del formulario combinado, listeSimple, listeMultiple. Este contenido se proporciona en forma de tres tablas, propiedades del objeto dynaFormulaire:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
Una vez que las tablas valeursCombo, valeursListeSimple y valeursListeMultiple hayan sido inicializadas por InitFormulaireAction, ya no será necesario volver a inicializarlas. De hecho, el objeto dynaFormulaire se coloca en la sesión y, por lo tanto, conserva su valor a lo largo de los ciclos de solicitud-respuesta. Por eso, la acción /init solo se ejecuta una vez. El código de InitFormulaireAction es el siguiente:
package istia.st.struts.formulaire;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class InitFormulaireAction
extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// prepara el formulario para su visualización
// se introduce la información necesaria para el formulario en su bean
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// se devuelve el control
return mapping.findForward("afficherFormulaire");
} //execute
// lista de valores del combo
private String[] getValeurs(int taille, String label) {
String[] valeurs = new String[taille];
for (int i = 0; i < taille; i++) {
valeurs[i] = label + i;
}
return valeurs;
}
}
- La clase deriva de la clase Action. Es obligatorio.
- El controlador Struts utiliza un objeto Action a través de su método execute. Por lo tanto, es este el que hay que redefinir. Este método recibe los siguientes parámetros:
- ActionMapping mapping: un objeto que representa la configuración de la aplicación en Struts-config.xml
- ActionForm form: el formulario asociado a la acción, si hay alguno definido en la configuración de la acción (atributo name de la acción).
- HttpServletRequest request: la solicitud del cliente
- HttpServletResponse: la respuesta al cliente
- la clase InitFormulaireAction debe inicializar el formulario dynaFormulaire. Este llega al método execute en forma del parámetro ActionForm form. Recordemos que dynaFormulaire es de tipo DynaFormulaire, clase derivada de la clase DynaActionForm, a su vez derivada de la clase ActionForm.
- En el método execute, se asignan valores a los tres campos valeursCombo, valeursListeSimple y valeursListeMultiple mediante el método set de la clase DynaActionForm. Estos valores son matrices arbitrarias por motivos de simplicidad. Cabe señalar que el método set asigna un valor a un campo existente. No puede utilizarse para crear nuevos campos. Por este motivo, es necesario definir los tres campos valeursCombo, valeursListeSimple y valeursListeMultiple en la definición del objeto dynaFormulaire en struts-config.xml.
- El método `execute` finaliza devolviendo al controlador la clave de la vista que se debe mostrar como respuesta al cliente. En este caso, se trata de la clave `afficherFormulaire`, que en el archivo `struts-config.xml` se ha asociado a la vista `/vues/formulaire.jsp`.
6.6. Implementación
La estructura de la aplicación es la siguiente:
![]() | ![]() |
![]() | ![]() |


Recordemos que el archivo ApplicationResources.properties anterior es necesario para la biblioteca de etiquetas struts-bean. Sabemos que este archivo contiene los mensajes de la aplicación. Estos son accesibles para la biblioteca struts-bean. En este caso, nuestra aplicación no define ningún mensaje. Por lo tanto, el archivo ApplicationResources.properties existe, pero está vacío.
6.7. Conclusión
En esta lección hemos detallado cómo gestionar los diferentes componentes de un formulario HTML. Ahora podemos utilizar formularios complejos en nuestras aplicaciones Struts.






