6. Formulários HTML
Até agora, utilizámos um único formulário contendo apenas dois campos de entrada. Aqui, propomos criar e processar um formulário utilizando componentes gráficos padrão (botões de opção, caixas de seleção, campos de entrada, caixas combinadas, listas).
6.1. As vistas da aplicação
A aplicação terá apenas duas vistas. A primeira apresenta um formulário em branco:
VISTA 1 - formulário

Esta primeira vista, denominada form.jsp, permitir-nos-á implementar várias tags da biblioteca struts-html. O utilizador preenche o formulário:

O botão [Submit] confirma os valores introduzidos. Esta será a segunda vista:

Esta segunda vista permite-nos utilizar duas outras bibliotecas de tags: struts-bean e struts-logic. A ligação [Voltar ao formulário] permite-nos regressar ao formulário tal como o preenchemos. Somos então redirecionados para a primeira vista.
6.2. A arquitetura da aplicação
![]() |
- O formulário (vista 1) será representado por um objeto Struts dinâmico chamado dynaFormulaire, uma subclasse de DynaActionForm. Será apresentado pela vista form.jsp.
- A ação Struts InitFormulaireAction será responsável por recuperar os dados necessários para exibir o formulário
- O formulário preenchido será processado por uma ForwardAction, que simplesmente redirecionará a solicitação para a segunda vista, confirmation.jsp. Esta vista será responsável por exibir os valores do formulário.
6.3. Configuração da aplicação
6.3.1. O ficheiro server.xml
O contexto da aplicação será denominado /formulaire2. Por conseguinte, adicionaremos a seguinte linha ao ficheiro server.xml do Tomcat:
Depois de fazer isto, poderá ser necessário reiniciar o Tomcat para que reconheça o novo contexto. Podemos verificar se está válido solicitando o URL http://localhost:8080/formulaire2:

6.3.2. O ficheiro web.xml
O ficheiro de configuração web.xml da aplicação terá o seguinte conteúdo:
<?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>
Em comparação com os ficheiros de configuração web.xml que já vimos, estamos a fazer algumas alterações:
- Apresentamos duas novas bibliotecas de tags: struts-bean e struts-logic. Estas serão utilizadas na vista confirmation.jsp. Por outro lado, a vista formulaire.jsp utilizará a biblioteca struts-html.
6.3.3. O ficheiro struts-config.xml
O ficheiro struts-config.xml terá o seguinte conteúdo:
<?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>
Contém três secções principais:
- a declaração de formulários na secção <form-beans>
- a declaração de ações na secção <action-mappings>
- a declaração do ficheiro de recursos em <message-resources>
6.3.4. Os objetos de formulário da aplicação (beans)
Os objetos utilizados para representar os formulários HTML da aplicação são do tipo ActionForm ou de um tipo derivado (DynaActionForm, DynaValidatorForm, etc.). São chamados de beans porque a sua construção segue as regras dos JavaBeans. Existe apenas um bean de formulário na nossa aplicação, chamado dynaFormulaire e derivado de DynaActionForm. Será utilizado nas seguintes situações:
- para conter os dados necessários para exibir a vista n.º 1
- para recuperar os valores do formulário na vista n.º 1 quando o utilizador o enviar
- para conter os dados necessários para exibir a vista #2
A estrutura do bean dynaFormulaire está intimamente ligada ao formulário na vista #1. Vamos examiná-la:
![]() |
N.º | Tipo de HTML | Função |
<input name="opt" type="radio" value="yes"> <input name="opt" type="radio" value="no"> | grupo de botões de opção interligados (mesmo nome) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | grupos de caixas de seleção (não é o mesmo nome) | |
<input type="text" name="inputField"> | um campo de texto | |
<input type="password" name="password"> | um campo de palavra-passe | |
<textarea name="inputBox">...</textarea> | um campo de entrada com várias linhas | |
<select name="combo" size="1">..</select> | um menu suspenso | |
<select name="simpleList" size="3">..</select> | uma lista de seleção única | |
<select name="listeMultiple" size="3" multiple>..</select> | uma lista de seleção múltipla | |
<input type="button" value="Limpar" onclick='clearList("singleList")'> | botão para desmarcar os itens selecionados na simpleList (7) | |
<input type="button" value="Limpar" onclick='clearList("multipleList")'> | botão para desmarcar os itens selecionados na multipleList (8) | |
<input type="submit" value="Enviar"> | botão de envio do formulário | |
<input type="hidden" name="secret" value="..."> | um campo oculto |
Vamos considerar vários casos:
- O objeto dynaFormulaire é utilizado para armazenar os valores do formulário HTML acima, que serão enviados através do botão [Submit]. Por conseguinte, deve ter os mesmos campos que o formulário HTML. O tipo de campo é determinado pela seguinte regra:
- se o campo HTML fornecer apenas um valor, então o campo dynaFormulaire será do tipo java.lang.String
- se o campo HTML fornecer vários valores, então o campo dynaFormulaire será do tipo java.lang.String[]
No formulário HTML acima, apenas o campo listeMultiple pode ser associado a vários valores (os selecionados pelo utilizador). Por conseguinte, uma definição inicial do objeto **dynaFormulaire** seria a seguinte:
<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>
Como é que o dynaFormulaire será preenchido com os valores do formulário HTML enviados pelo cliente web?
O campo opt receberá o valor "yes" se o campo HTML <input type="radio" name="opt" value="yes"> tiver sido selecionado, e o valor "no" se o campo <input type="radio" name="opt" value="no"> tiver sido selecionado. | |
O campo chk1 receberá o valor "on" se o campo HTML <input name="chk1" type="radio" value="1"> tiver sido selecionado; caso contrário, não receberá nada. Neste último caso, o campo chk1 manterá o seu valor anterior. | |
o mesmo | |
igual | |
O campo `champSaisie` receberá o texto introduzido pelo utilizador no campo HTML `<input type="text" name="champSaisie">`. Este texto pode ser uma cadeia vazia. | |
O campo mdp receberá o texto introduzido pelo utilizador no campo HTML <input type="password" name="mdp">. Este texto pode ser uma cadeia vazia. | |
O campo inputBox receberá o texto introduzido pelo utilizador no campo HTML <textarea name="inputBox">...</textarea>. Este texto forma uma única cadeia, composta pelas linhas digitadas pelo utilizador, separadas umas das outras pela sequência de caracteres "\r\n". O texto resultante pode, opcionalmente, ser uma cadeia vazia. | |
O campo combo receberá a opção selecionada pelo utilizador no campo HTML <select name="combo" size="1">..</select>. A opção selecionada é aquela que aparece na caixa de combinação. Se a opção HTML selecionada for do tipo <option value="XX">YY</option>, o campo combo receberá o valor "XX". Se a opção HTML selecionada for do tipo <option>YY</option>, o campo combo receberá o valor "YY". | |
O campo simpleList receberá a opção selecionada pelo utilizador no campo HTML <select name="simpleList" size="..">..</select> se houver alguma. Se não houver nenhuma, o campo simpleList não receberá nenhum valor e manterá o seu valor anterior. O valor efetivamente atribuído ao campo simpleList segue as regras especificadas para a caixa de combinação. | |
O campo listeMultiple, do tipo String[], receberá as opções selecionadas pelo utilizador no campo HTML <select name="listeMultiple" size=".." multiple>..</select>, caso existam. Se não houver nenhuma, a matriz listeMultiple não receberá nenhum valor e o seu conteúdo permanecerá inalterado. Os valores efetivamente atribuídos à matriz listeMultiple seguem as regras especificadas para a caixa combinada. | |
O campo secret receberá o valor XX do campo HTML <input type="hidden" name="secret" value="XX">. Este texto pode, opcionalmente, ser uma cadeia de caracteres vazia. |
- O objeto dynaFormulaire é utilizado para fornecer o conteúdo inicial da vista n.º 1. Os valores dos campos anteriores serão utilizados para os seguintes fins:
deve ter o valor «sim» ou «não» para que o navegador saiba qual o botão de opção a selecionar | |
Se chk1 tiver o valor "on", a caixa de seleção será marcada; caso contrário, não será marcada | |
o mesmo | |
igual | |
o valor do campo será exibido no campo de entrada fieldInput | |
o valor do campo será exibido no campo de entrada mdp | |
o valor do campo será exibido na caixa de entrada inputBox | |
O valor deste campo indica qual o item da caixa de combinação que deve ser selecionado quando o formulário for apresentado | |
same | |
Os valores na matriz multipleList indicam quais os itens da lista múltipla que devem ser selecionados quando o formulário é apresentado | |
O valor do campo será atribuído ao atributo value do campo HTML secret. |
A visualização n.º 1 requer informações adicionais:
- a lista de valores a apresentar na lista suspensa
- a lista de valores a apresentar na lista `listeSimple`
- a lista de valores a apresentar na multipleList
Existem várias formas de fornecer esta informação à vista. Por exemplo, os arrays colocados no pedido passado para a vista funcionariam. Aqui, colocamos esses arrays no 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>
O formulário dynaFormulaire será inicializado pela ação /init, que chamará um objeto derivado de Action chamado InitFormulaireAction. Este objeto será responsável por criar as três matrizes necessárias para exibir as três listas e colocá-las no bean dynaFormulaire. O ficheiro de configuração define o âmbito deste bean como sessão. Como resultado, o controlador Struts colocará este bean na sessão. Não será, portanto, necessário regenerá-lo entre os ciclos de pedido-resposta. Consequentemente, a ação /init será chamada apenas uma vez.
- O objeto dynaFormulaire também é utilizado para preencher a vista n.º 2. Esta vista limita-se a apresentar os valores.
6.3.5. Ações da aplicação
As ações são tratadas por objetos do tipo Action ou tipos derivados. A configuração das ações é feita dentro das tags <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>
Note que nem sempre existe um formulário associado a uma ação. É o caso, acima, da ação /affiche. Antes de detalhar cada ação, vamos rever como o par ação-formulário funciona dentro de uma tag <action>:
- Uma ação começa com um pedido de um cliente web e termina com o envio de uma página de resposta. Este é o ciclo de pedido-resposta cliente-servidor da web. O pedido é recebido pelo controlador Struts do tipo ActionServlet ou por uma classe derivada. Este controlador também envia a resposta.
- O bean de formulário do tipo ActionForm ou de uma classe derivada é criado, caso ainda não exista. O controlador verifica se consegue encontrar um objeto com o nome name no âmbito especificado por scope. Se sim, utiliza-o. Se não, cria-o e coloca-o no âmbito especificado por scope, associado ao atributo especificado por name.
No exemplo da ação /init, por exemplo, o controlador chamará request.getSession().getAttribute("dynaFormulaire") para determinar se dynaFormulaire já foi criado ou não. Caso contrário, irá criá-lo e adicioná-lo à sessão utilizando uma instrução como request.getSession().setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- O controlador também procurará um objeto Action do tipo especificado pelo atributo type. Se não encontrar nenhum, ele o cria; caso contrário, ele o utiliza.
- O método reset do bean do formulário será chamado. Este bean, exceto durante a sua criação inicial, é reutilizado. Por isso, contém dados que poderá querer «limpar». Isto é feito no método reset do bean ActionForm ou de uma classe derivada.
- Se a ação for o destino de um formulário enviado, os valores do formulário encontrados na solicitação do cliente são copiados para os campos com o mesmo nome no bean do formulário. Note que o método reset foi chamado antes desta cópia.
- Se a configuração especificar o atributo validate="true", o método validate do bean do formulário será chamado. Este método deve então validar os dados no bean. Esta validação ocorre normalmente apenas quando o formulário acaba de receber novos dados através de um formulário enviado e se pretende verificar a validade desses dados. Este método devolve qualquer lista de erros ao controlador num objeto ActionErrors.
- Se o objeto ActionErrors não estiver vazio, o controlador exibe a vista especificada pelo atributo input da ação.
- Se a validação de dados não for necessária ou se tiver sido bem-sucedida, o controlador chama o método `execute` do objeto `Action` (ou de uma classe derivada) associado à ação atual. É dentro deste método que o pedido do cliente web é processado. O método `execute` devolve um objeto `ActionForward` indexado por chaves de cadeia de caracteres. Estas chaves são as declaradas pelas tags `forward` da ação configurada. No nosso exemplo, a ação `/init` tem uma única tag `forward`. Ela associa a chave "displayForm" à vista `form.jsp`.
- O controlador apresenta a vista associada à chave recebida. Esta vista pode, na verdade, ser uma ação, caso em que o processo anterior é repetido.
A ação /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- A ação /init ocorre normalmente uma vez durante o primeiro ciclo de pedido-resposta, quando o utilizador solicita o URL http://localhost:8080/formulaire2/init.do
- O objeto dynaForm é criado ou reciclado. É recuperado (reciclagem) ou inserido (criação) na sessão, conforme especificado pelo atributo scope.
- O seu método reset é chamado. O que deve ele fazer? Normalmente, os campos do objeto ActionForm são repostos para os valores padrão. No entanto, neste caso, não o faremos, porque o objeto dynaFormulaire é colocado na sessão (scope="session"). Os campos do dynaFormulaire devem, portanto, manter os seus valores. Quais são esses valores durante a criação inicial do objeto dynaFormulaire? Existem dois casos:
- o campo tem um valor inicial especificado no ficheiro de configuração:
Neste caso, o controlador Struts criará este campo com este valor inicial.
- Se o campo não tiver um valor inicial especificado na configuração: aplicam-se as regras de inicialização do Java. Geralmente, os campos numéricos terão o valor zero, as cadeias de caracteres terão a cadeia vazia e outros objetos terão o valor nulo.
Vejamos a configuração inicial do 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>
Os valores iniciais dos campos do dynaFormulaire após a criação serão os seguintes:
Campo | Valor inicial |
"não" | |
cadeia vazia | |
cadeia vazia | |
cadeia de caracteres vazia | |
cadeia vazia | |
cadeia vazia | |
cadeia vazia | |
matriz de cadeias vazias | |
"xxx" | |
matriz de cadeias de caracteres vazias |
- Pode-se imaginar que o método reset do dynaFormulaire atribua valores às três matrizes que preenchem as três listas na vista formulaire.jsp. Isso seria possível aqui porque os dados nessas três matrizes são gerados arbitrariamente. No entanto, o cenário mais comum é que estes dados provenham do modelo da aplicação, o M em MVC. Aqui, vamos optar por um meio-termo — para manter o exemplo simples — fazendo com que estes valores sejam gerados pela ação InitFormulaireAction, ou seja, pelo C em MVC.
- Não há necessidade de escrever um método reset no dynaFormulaire, uma vez que a classe ActionForm da qual deriva já possui um método desse tipo que não faz nada (sem inicializações).
- Assim que o método reset do dynaFormulaire é chamado, o controlador verifica o atributo validate da ação. Aqui, este tem o valor «false». O método validate do dynaFormulaire não será chamado.
- O objeto InitFormulaireAction é criado ou reutilizado, caso já existisse, e o seu método execute é chamado. Este método atribui valores arbitrários às três matrizes do dynaFormulaire: valeursCombo, valeursListeSimple e valeursListeMultiple. O método retorna um ActionForward com a chave "afficherFormulaire".
- O controlador apresenta a vista /vues/formulaire.jsp, que foi associada à chave «afficherFormulaire» através de uma tag forward da ação /init.
A ação /confirmation
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- A ação /confirmation ocorre quando o utilizador clica no botão [Submit] na vista n.º 1. O navegador, então, "envia" o formulário preenchido pelo utilizador para o controlador Struts.
- O objeto dynaFormulaire é recuperado da sessão
- o seu método reset é chamado. Assim que for chamado, o controlador Struts irá copiar os valores dos campos do formulário enviados pelo cliente para os campos com o mesmo nome no dynaFormulaire. Vamos rever a lista de campos no dynaFormulaire e ver como funciona esta cópia:
Campo | Código HTML associado | Valor do campo após a cópia dos valores do formulário |
<input type="radio" name="opt" value="yes">Sim <input type="radio" name="opt" value="no" checked="checked">Não | - «sim» ou «não», dependendo do botão de opção selecionado | |
<input type="checkbox" name="chk1" value="on"> | - "on" se a caixa de seleção chk1 tiver sido marcada - mantém o seu valor anterior se a caixa de seleção chk1 não tiver sido marcada | |
<input type="checkbox" name="chk2" value="on"> | - "on" se a caixa de seleção chk2 tiver sido marcada - mantém o seu valor anterior se a caixa de seleção chk2 não tiver sido marcada | |
<input type="checkbox" name="chk2" value="on"> | - "on" se a caixa de seleção chk3 tiver sido marcada - mantém o seu valor anterior se a caixa de seleção chk3 não tiver sido marcada | |
<input type="text" name="inputField" value=""> | - valor introduzido pelo utilizador no inputField | |
<input type="password" name="password" value=""> | - valor introduzido pelo utilizador no campo password | |
<textarea name="inputBox"></textarea> | - valor introduzido pelo utilizador na caixa de texto | |
<select name="combo">...</select> | - valor selecionado pelo utilizador na lista suspensa | |
<select name="simpleList" size="3">...</select> | - valor selecionado pelo utilizador na simpleList | |
<select name="listeMultiple" multiple="multiple" size="5"> | - matriz de cadeias de caracteres contendo os valores selecionados pelo utilizador em multipleList | |
<input type="hidden" name="secret" value="xxx"> | - "xxx". |
Encontramos um problema com campos que não recebem necessariamente um valor na solicitação enviada pelo navegador. Isto aplica-se às caixas de seleção chk1 a chk3 e às duas listas listeSimple e listeMultiple. Neste caso, estes campos mantêm os seus valores anteriores — aqueles obtidos durante o ciclo anterior de solicitação-resposta.
Consideremos, por exemplo, a caixa de seleção chk1 e suponhamos que, no ciclo anterior de pedido-resposta, o utilizador tenha marcado essa caixa. O navegador enviou então a informação chk1="on" na cadeia de parâmetros do seu pedido. O construtor atribuiu, assim, o valor "on" ao campo chk1 do dynaFormulaire. Suponhamos agora que, no ciclo atual, o utilizador não marque a caixa de seleção chk1. Neste caso, na cadeia de parâmetros da nova solicitação, o navegador não envia algo como chk1="off", mas sim nada. Como resultado, o campo chk1 no dynaFormulaire manterá o seu valor "on" e, assim, terá um valor que não reflete o do formulário validado pelo utilizador. Vamos utilizar o método reset do dynaFormulaire para resolver este problema. Neste método, vamos definir os três campos chk1, chk2 e chk3 como "off". No nosso exemplo chk1, ou o utilizador:
- marca a caixa de seleção chk1. Neste caso, o navegador envia a informação chk1="on" e o campo chk1 no dynaFormulaire muda para "on"
- não marca a caixa de seleção chk1. Nesse caso, o navegador não envia um valor para o campo chk1, que manterá o seu valor anterior "off". Em ambos os casos, o valor armazenado no campo chk1 do dynaFormulaire está correto.
O problema é semelhante tanto para as listas simpleList como para as multiList. Se nenhuma opção tiver sido selecionada nessas listas, elas não estarão presentes nos parâmetros da solicitação e, portanto, manterão os seus valores anteriores. No método reset do dynaFormulaire, iremos reiniciar a simpleList com uma string vazia e a multiList com uma matriz de strings de comprimento 0.
- Assim que o método reset do dynaFormulaire é chamado, o controlador copia as informações que lhe foram enviadas na solicitação do cliente de volta para os campos do dynaFormulaire
- É criado ou reutilizado um objeto ForwardAction, e o seu método execute é chamado. ForwardAction é uma classe predefinida que retorna um objeto ActionForward apontando para a vista definida pelo atributo “parameter” da ação, neste caso /vues/confirmation.jsp.
- O controlador envia esta vista. O ciclo está completo.
O /display
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- A ação /display é acionada ao clicar no link [Voltar ao formulário] na vista n.º 2.
- Aqui, não existe nenhum formulário associado à ação. Por isso, passamos diretamente à execução do método `execute` de um objeto `ForwardAction`, que irá devolver um objeto `ActionForward` a apontar para a vista `/vues/formulaire.jsp`.
6.3.6. O ficheiro de mensagens da aplicação
A terceira secção do ficheiro struts-config.xml é o ficheiro de mensagens:
O ficheiro ApplicationResources.properties está localizado em WEB-INF/classes. Estará vazio. Apesar de estar vazio, deve ser declarado no ficheiro de configuração; caso contrário, a biblioteca de tags struts-bean, que discutiremos mais adiante, irá gerar um erro. Esta biblioteca é utilizada pela vista confirmation.jsp.
6.4. O código da vista
6.4.1. A vista formulaire.jsp
Lembre-se de que esta vista é apresentada em dois casos:
- quando a ação /init é chamada durante o primeiro ciclo de pedido-resposta
- quando a ação /affiche é chamada durante os ciclos subsequentes
O código da vista formulaire.jsp é o seguinte:
<%@ 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 tags da biblioteca struts-html. Lembre-se de que, para utilizar uma biblioteca de tags, deve:
- declará-la no ficheiro web.xml da aplicação utilizando uma tag <tag-lib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- Coloque o código desta biblioteca em algum local na árvore de diretórios da aplicação, neste caso WEB-INF/struts-html.tld
- Declare a utilização desta biblioteca no início das páginas JSP que a utilizam:
A vista formulaire.jsp utiliza tags que iremos explicar a seguir:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
A tag html:rewrite permite omitir o nome da aplicação dos URLs. Possui um atributo:
Assim, no exemplo acima, se decidir nomear a aplicação «form3», o código para o atributo background não precisa de ser reescrito. A tag `html:rewrite` irá gerar o novo código HTML background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
A tag html:form gera a tag de formulário HTML. Possui vários atributos:
Podemos ver que, por predefinição, o código HTML gerado utiliza o método POST. Neste mesmo código HTML, o URL da ação foi reescrito para incluir o nome da aplicação como prefixo e .do como sufixo. |
<html:radio name="dynaFormulaire" property="opt" value="yes">Sim</html:radio> | |||||||
A tag html:radio é utilizada para gerar a tag HTML <input type="radio" ...>. Suporta vários atributos:
O texto entre as tags de início e fim é o texto que será exibido ao lado do botão de opção. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
A tag html:checkbox é utilizada para gerar a tag HTML <input type="checkbox" ...>. Suporta vários atributos:
O texto entre as tags de início e fim é o texto que será exibido ao lado da caixa de seleção. |
<html:text name="dynaFormulaire" property="inputField" /> | |||||||
A tag html:text é utilizada para gerar a tag HTML <input type="text" ...>. Suporta vários atributos:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
A tag html:password é utilizada para gerar a tag HTML <input type="password" ...>. Suporta vários atributos: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
A tag HTML:textarea é utilizada para gerar a tag HTML <textarea>...</textarea>. Suporta vários atributos:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
A tag HTML:select é utilizada para gerar a tag HTML <select>...</select>. Suporta vários atributos:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |||||
A tag HTML:options é utilizada para gerar as tags HTML <option>...</option> dentro de uma tag HTML <select>. Existem várias formas de especificar como encontrar os valores para preencher o elemento select. Aqui, utilizámos os atributos name e property:
|
As outras duas listas são geradas de forma semelhante à anterior:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
Acima, especificamos um atributo size diferente de 1 para criar uma lista em vez de uma caixa combinada.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
Acima, especificamos o atributo multiple="true" para criar uma lista com várias seleções.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
A tag html:hidden é utilizada para gerar a tag HTML <input type="hidden" ...>.
|
Para compreender plenamente a relação entre a vista «formulaire.jsp» e o bean «dynaFormulaire» que a representa na memória, é importante ter em conta que o bean «dynaFormulaire» é utilizado tanto para a leitura como para a gravação:
![]() |
A solicitação ocorre quando o utilizador clica no botão [Submit] no formulário. O navegador, então, «envia» o formulário HTML para a ação /confirmation. Já explicámos o que acontece a seguir e, em particular, que os campos dynaFormulaire receberão os valores dos campos com o mesmo nome no formulário HTML.
O que acontece quando o controlador solicita que a página formulaire.jsp seja apresentada em resposta a um pedido? Vamos analisar as tags uma a uma:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
gera o código HTML |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
gera o código HTML |
<html:radio name="dynaFormulaire" property="opt" value="yes">Sim</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">Não</html:radio> | |
Se o campo opt de dynaFormulaire for "sim", gere o código HTML |
<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> | |
Se os campos chk1 e chk3 de dynaFormulaire estiverem "ativados" e o campo chk2 estiver "desativado", gere o código HTML |
<html:text name="dynaFormulaire" property="inputField" /> | |
se o campo de entrada estiver definido como "isto é um teste", gerar o código HTML |
<html:password name="dynaFormulaire" property="password" /> | |
Se o campo da palavra-passe for «azerty», gere o código HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
Se o campo "mdp" for "azerty", gere o código HTML |
<html:password name="dynaFormulaire" property="mdp" /> | |
Se o campo "mdp" for "azerty", gere o código HTML |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="comboValues"/> </html:select> | |
se o campo combo for "combo2", gera o código HTML |
<html:select name="dynaFormulaire" property="simpleList" size="3"> <html:options name="dynaFormulaire" property="simpleListValues"/> </html:select> | |
se o campo simpleList for "simple1", gera o código HTML |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="multipleListValues"/> </html:select> | |
Se o campo listeMultiple for a matriz {"multiple0", "multiple2"}, gera o código HTML |
<html:hidden name="dynaFormulaire" property="secret"/> | |
se o campo secreto tiver o valor "xxx", gerar o código HTML |
<html:submit>Enviar</html:submit> | |
gera o código HTML |
A última coisa a explicar é o código JavaScript incluído na página JSP e associado aos dois botões [Limpar] que desmarcam os itens selecionados nas listas simpleList e multipleList:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
A tag
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
gera o seguinte código HTML:
Para compreender o código JavaScript associado aos botões [Limpar], vamos rever como os vários elementos de um documento web são referenciados no código JavaScript que utiliza esse documento:
Dados | Significado |
refere-se a todo o documento web | |
refere-se ao conjunto de formulários definidos no documento | |
refere-se ao formulário número i no documento | |
refere-se ao formulário <form> com o atributo name definido como "formName" | |
refere-se ao formulário <form> cujo atributo name é igual a "formName" | |
refere-se à coleção de elementos pertencentes ao formulário designado pela expressão [form]. Esta coleção inclui todas as tags <input>, <textarea> e <select> no formulário designado. | |
refere-se ao elemento número i de [form] | |
refere-se ao elemento em [form] cujo atributo name é igual a componentName | |
refere-se ao elemento no [form] cujo atributo name é igual a componentName | |
refere-se ao valor do componente [component] do formulário [form] quando o seu código HTML pode ter um atributo value (<input>, <textarea>) | |
refere-se ao índice da opção selecionada numa lista. Pode ser utilizado tanto para leitura como para escrita. Definir esta propriedade como -1 desmarca todos os itens da lista. | |
refere-se à matriz de opções associadas a uma tag <select> | |
refere-se à opção número i da tag <select> especificada | |
Um valor booleano que indica se a opção n.º i do elemento [select] especificado está selecionada (true) ou não. Pode ser utilizado tanto para leitura como para escrita |
Vamos rever o código JavaScript para os dois botões:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
Quando o botão é clicado, o código associado ao atributo «onclick» é executado. Aqui, trata-se de código inline. Na maioria das vezes, escrevemos onclick="function(...)", em que function é uma função definida dentro de uma tag <script language="javascript">...</script>. O que faz o código acima? Vamos analisar o código do primeiro botão:
refere-se ao documento web no qual o botão está localizado | |
refere-se ao formulário no qual o botão está localizado | |
refere-se ao componente simpleList do formulário | |
refere-se ao índice da opção selecionada em listeSimple. Definir esta propriedade como -1 desmarca todas as opções. |
6.4.2. A vista confirmation.jsp
Recorde-se que esta vista é apresentada após a ação /confirmation, ou seja, após o formulário contido na vista formulaire.jsp ter sido enviado pelo cliente web. O seu único objetivo é apresentar os valores introduzidos pelo utilizador. O seu código é o seguinte:
<%@ 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>
Aqui apresentamos duas novas bibliotecas de tags: struts-bean e struts-logic. A biblioteca struts-bean fornece acesso a objetos no contexto da solicitação, da sessão ou da aplicação. A biblioteca struts-logic permite implementar lógica de execução utilizando tags. Nenhuma destas bibliotecas é estritamente necessária. Como vimos, uma página JSP pode:
- recuperar objetos da solicitação (request.getAttribute(...)), da sessão (session.getAttribute(...)) ou do contexto da aplicação
- incluir elementos dinâmicos no código HTML utilizando variáveis <%= variável %>
- conter código Java <% código Java %>
A inclusão de código Java nas páginas JSP incomoda aqueles que preferem uma separação estrita entre a lógica da aplicação (código Java) e a apresentação (uso de tags). É por isso que foram criadas bibliotecas de tags para eles.
Vamos proceder da mesma forma que fizemos na vista «formulaire.jsp» e explicar cada uma das tags presentes no código «confirmation.jsp», caso ainda não tenham sido abordadas na vista «formulaire.jsp». Em primeiro lugar, note-se que a página começa por declarar as três bibliotecas de tags que irá 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" %>
Note também que estas três bibliotecas devem ser declaradas no ficheiro web.xml da aplicação. Vamos agora comentar as tags no documento formulaire.jsp:
escreve um valor no fluxo HTML atual. A tag bean:write suporta os seguintes atributos: name: nome do objeto a utilizar scope: âmbito (request, session, context) no qual procurar este objeto property: campo do objeto designado pelo nome cuja propriedade deve ser gravada. Este campo pode ser um objeto de qualquer tipo. Será utilizado o método toString do objeto. Aqui, é gravado o valor do campo opt no dynaFormulaire. O resultado será «yes» se o utilizador tiver marcado o botão de opção com o atributo value="yes", ou «no» se tiver marcado o botão de opção com o atributo value="no" |
escreve o valor do campo chk1 no dynaFormulaire. O resultado será «on» se o utilizador tiver marcado a caixa, ou «off» caso contrário. O mesmo se aplica a chk2 e chk3. |
escreve o valor do campo champSaisie em dynaFormulaire, ou seja, o texto digitado pelo utilizador nesse campo. O mesmo se aplica a mdp e boiteSaisie. |
escreve o valor do campo combo em dynaFormulaire. Este será o atributo value do elemento <option> selecionado pelo utilizador. |
grava o valor do campo simpleList no dynaForm. Este valor corresponderá ao atributo «value» do elemento <option> selecionado pelo utilizador, caso tenha sido selecionado algum. Caso contrário, será uma cadeia de caracteres vazia. |
Aqui, apresentamos as tags de lógica. Estamos a lidar com uma lista de escolha múltipla. O valor do campo listeMultiple do objeto dynaFormulaire é uma matriz de Strings. Em Java, escreveríamos um loop. A tag logic:iterate permite-nos executar este mesmo loop sem escrever código Java. Neste exemplo, a tag logic:iterate tem os seguintes atributos: name="dynaFormulaire": nome do objeto a utilizar property="listeMultiple": nome da propriedade no objeto especificado por name que contém a coleção a ser iterada no loop. Aqui, esta coleção é a matriz de valores selecionados em listeMultiple. Esta matriz pode estar vazia. id="choix": identificador que designa o elemento atual da matriz em cada iteração. Durante a primeira iteração, choix representará listeMultiple[0], durante a segunda listeMultiple[1], e assim por diante. indexID="index": identificador que designa o índice do elemento atual da matriz em cada iteração do ciclo. Durante a primeira iteração, index terá o valor 0; durante a segunda, o valor 1; e assim por diante. O código HTML contido entre as tags <logic:iterate ...> e </logic:iterate> é repetido para cada elemento da coleção designada pelo par (nome, propriedade). A parte dinâmica deste código é a seguinte:
Com base no que foi dito anteriormente, na iteração número i (i>=0), o código HTML gerado é equivalente ao seguinte: |
gera um link relativo ao contexto da aplicação, o que elimina a necessidade de conhecer o contexto. O código HTML gerado por esta tag é o seguinte: |
6.5. As classes Java
O ficheiro de configuração struts-config.xml faz referência a duas classes 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"
>
A classe DynaFormulaire é a classe que irá conter os valores da vista n.º 1, formulaire.jsp. A classe InitFormulaireAction é a classe que irá processar os valores do formulário enviados através do botão [Submit] em formulaire.jsp.
6.5.1. A classe DynaFormulaire
Para armazenar os valores de um formulário, basta um objeto do tipo DynaActionForm, a menos que seja necessário substituir um dos métodos reset ou validate desta classe. Aqui, o método validate não precisa de ser reescrito, uma vez que não é realizada qualquer validação de dados. No entanto, o método reset precisa de ser reescrito. Isto porque os campos do objeto DynaFormulaire receberão os seus valores do formulário enviado pelo cliente web. No entanto, alguns campos podem não receber um valor se não estiverem presentes na solicitação. Isto ocorre nos seguintes casos:
- uma caixa de seleção que não tenha sido marcada pelo utilizador
- uma lista com mais de uma opção, em que nenhuma foi selecionada
Para formulários que contenham este tipo de componente, o método reset deve
- definir o valor «off» para o campo associado à caixa de seleção
- definir a string vazia no campo associado a uma lista de seleção única
- atribuir uma matriz vazia de cadeias de caracteres ao campo associado a uma lista de seleção múltipla
Assim, se estes campos não receberem um valor da consulta, mantêm o valor atribuído pela redefinição, que corresponde ao estado do componente no formulário validado pelo utilizador (caixa de seleção desmarcada, lista sem itens selecionados).
O código para a classe DynaFormulaire, uma subclasse de DynaActionForm, é o seguinte:
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){
// reset checkboxes - value off
set("chk1","off");
set("chk2","off");
set("chk2","off");
// reset listeSimple - empty string
set("listeSimple","");
// reset listeMultiple - empty table
set("listeMultiple",new String[]{});
}
}
6.5.2. A classe InitFormAction
A classe InitFormAction está associada à ação /init no ficheiro struts-config.xml:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
A ação /init é utilizada apenas uma vez durante a construção inicial do objeto DynaForm. O seu objetivo é fornecer conteúdo para as três listas combinadas do formulário: simpleList, multipleList e dropdownList. Este conteúdo é fornecido na forma de três matrizes, que são propriedades do objeto dynaForm:
<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>
Depois de as matrizes valuesCombo, valuesSingleList e valuesMultipleList terem sido inicializadas pelo InitFormAction, já não precisam de ser inicializadas. Isto deve-se ao facto de o objeto dynaForm ser colocado na sessão e, por isso, manter o seu valor ao longo dos ciclos de pedido-resposta. É por isso que a ação /init é executada apenas uma vez. O código para o InitFormAction é o seguinte:
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 {
// prepares the form to be displayed
// we put the information needed for the form in its bean
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
// we give back
return mapping.findForward("afficherFormulaire");
} //execute
// list of combo values
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;
}
}
- A classe estende a classe Action. Isto é obrigatório.
- O controlador Struts utiliza um objeto Action através do seu método execute. Este é, portanto, o método que deve ser redefinido. Este método recebe os seguintes parâmetros:
- ActionMapping mapping: um objeto que representa a configuração da aplicação no struts-config.xml
- ActionForm form: o formulário associado à ação, caso esteja definido na configuração da ação (atributo name da ação).
- HttpServletRequest request: o pedido do cliente
- HttpServletResponse: a resposta ao cliente
- A classe InitFormulaireAction deve inicializar o formulário dynaFormulaire. Este é passado para o método execute como o parâmetro de formulário ActionForm. Recorde-se que dynaFormulaire é do tipo DynaFormulaire, uma classe derivada da classe DynaActionForm, que por sua vez é derivada da classe ActionForm.
- No método execute, são atribuídos valores aos três campos valeursCombo, valeursListeSimple e valeursListeMultiple utilizando o método set da classe DynaActionForm. Estes valores são matrizes arbitrárias por uma questão de simplicidade. Note-se que o método set atribui um valor a um campo existente. Não pode ser utilizado para criar novos campos. É por isso que é necessário definir os três campos valeursCombo, valeursListeSimple e valeursListeMultiple na definição do objeto dynaFormulaire no struts-config.xml.
- O método execute termina devolvendo a chave da vista a ser apresentada ao controlador como resposta ao cliente. Aqui, trata-se da chave afficherFormulaire, que no ficheiro struts-config.xml foi associada à vista /vues/formulaire.jsp.
6.6. Implantação
A estrutura do diretório da aplicação é a seguinte:
![]() | ![]() |
![]() | ![]() |


Note que o ficheiro ApplicationResources.properties acima é exigido pela biblioteca de tags struts-bean. Sabemos que este ficheiro contém as mensagens da aplicação. Estas estão acessíveis à biblioteca struts-bean. Neste caso, a nossa aplicação não define quaisquer mensagens. Por conseguinte, o ficheiro ApplicationResources.properties existe, mas está vazio.
6.7. Conclusão
Nesta lição, detalhámos como gerir os vários componentes de um formulário HTML. Agora podemos utilizar formulários complexos nas nossas aplicações Struts.






