Skip to content

6. Exemplo 05 – O Formulário de Entrada

Vamos apresentar o conceito de um formulário de entrada utilizando um exemplo simples.

6.1. O projeto NetBeans

Em [1], o projeto:

  • as visualizações [Saisie.jsp], [Confirmation.jsp]
  • o ficheiro de configuração [struts.xml]
  • o ficheiro de mensagens [messages.properties]
  • a ação [Confirm.java]

Em [2], a página de entrada

6.2. Configuração

O ficheiro [struts.xml] é o seguinte:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
  <!-- internationalization -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- default package -->
  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Saisir</param>
        <param name="namespace">/actions</param>
      </result>
    </action>
  </package>
  <!-- equity package -->
  <package name="actions" namespace="/actions" extends="struts-default">
    <action name="Saisir">
      <result name="success">/vues/Saisie.jsp</result>
    </action>
    <action name="Confirmer" class="actions.Confirmer">
      <result name="success">/vues/Confirmation.jsp</result>
    </action>  
  </package>
</struts>
  • Linha 20: o pacote de ação para a URL /actions/Action.
  • linhas 21–23: definem a ação [Enter]. Nenhuma classe está associada a ela. A resposta é sempre a vista [/views/Enter.jsp]
  • Linhas 24–26: definem a ação [Confirm]. A classe [actions.Confirm] está associada a ela. A resposta é sempre a vista [/views/Confirmation.jsp]

6.3. A ação [Confirmar]

O seu código é o seguinte:


package actions;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Confirmer extends ActionSupport{
 
  // model
  private String nom;
 
  // getters and setters
 
  public String getNom() {
    return nom;
  }
 
  public void setNom(String nom) {
    this.nom = nom;
  }
 
}

A classe tem apenas um campo, o da linha 8, com os seus métodos get/set.

6.4. O ficheiro de mensagens

O conteúdo de [messages.properties] é o seguinte:


saisie.texte=Formulaire de saisie
saisie.titre1=Saisie
saisie.titre2=Saisie
saisie.libelle=Tapez votre nom
saisie.valider=Valider
confirm.titre1=Confirmation
confirm.titre2=Confirmation
confirm.texte=Bonjour
confirm.retour=Retour au formulaire de saisie

Estas chaves de mensagem são utilizadas nas vistas [Entry.jsp] e [Confirmation.jsp].

6.5. As vistas

6.5.1. A vista [Entry.jsp]

Visualmente, tem este aspeto:

O seu código-fonte é o seguinte:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="saisie.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="saisie.titre2"/></h1>
    <s:form action="Confirmer">
      <s:textfield key="saisie.libelle" name="nom"/>
      <s:submit key="saisie.valider" action="Confirmer"/>
    </s:form>
  </body>
</html>
  • Linha 7: Apresenta a mensagem para a chave «saisie.titre1» (Entrada) [1].
  • linha 10: exibe a mensagem para a chave "saisie.titre2" (Entrada) [2].
  • Linhas 11, 14: A tag <s:form> define um formulário HTML. Todas as entradas deste formulário serão enviadas para o servidor web. Dizemos que são enviadas via POST porque a operação HTTP envolvida no envio destes dados para o servidor é chamada POST. Os dados são enviados sob a forma de uma cadeia de caracteres: param1=valor1&param2=valor2&... Já nos deparámos com esta cadeia de caracteres na Secção 3.5 do Exemplo 02. Em ambos os casos, a cadeia de parâmetros é processada da mesma forma pelo Struts 2. Os valores dos parâmetros são injetados na ação executada, em campos com os mesmos nomes que os parâmetros. Para quem são enviados os dados postados? Por predefinição, para a ação que exibiu o formulário, neste caso a ação Saisir [5]. Também pode utilizar o atributo action para especificar outra ação, neste caso a ação [Confirmer].
  • Linha 12: A tag <s:textfield ...> exibe o campo de entrada [3]. O seu atributo key especifica a chave para o rótulo a ser exibido à esquerda do campo de entrada. O rótulo é, portanto, procurado no ficheiro [messages.properties]. O atributo name é o nome do parâmetro que será enviado. O valor associado a este parâmetro será o texto introduzido no campo de entrada.
  • Linha 13: A tag <s:submit ...> exibe o botão [4]. O seu atributo key especifica a chave para o rótulo a ser exibido no botão. O rótulo é, portanto, recuperado do ficheiro [messages.properties]. Um botão de envio aciona o envio do formulário para uma ação. Mencionámos anteriormente que esta era a ação [Confirm] devido ao atributo action da tag <s:form>. O atributo action da tag <s:submit> permite-lhe especificar uma ação diferente, se desejar. Aqui, definimos a ação como [Confirm]. O botão tem um nome de parâmetro padrão: action:action_name, neste caso action:Confirm. O valor associado a este parâmetro é o rótulo do botão. Em última análise, a cadeia de caracteres do parâmetro enviada para a ação [Confirm] quando o utilizador clica no botão [Validate] será:

?name=xx&action:Confirm=Validate.

onde xx é o texto introduzido pelo utilizador no campo de entrada.

6.5.2. A vista [Confirmation.jsp]

Visualmente, tem este aspeto:

Introduzimos um nome e enviamos a página de entrada. Em seguida, recebemos a resposta [1], que é a vista [Confirmation.jsp]. O URL apresentado em [2] é o da ação [Confirm]. No exemplo acima, foi enviada a seguinte cadeia de caracteres:

name=bernard&action:Confirm=Validate

O parâmetro action:Confirm permite que o Struts 2 encaminhe o pedido para a ação correta, neste caso a ação [Confirm]. O valor do parâmetro name será então injetado no campo name da ação [Confirm].

O código-fonte da ação [Confirmation.jsp] é o seguinte:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="confirm.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="confirm.titre2"/></h1>
    <s:text name="confirm.texte"/>&nbsp;
    <s:property value="nom"/> !
    <br/><br/>
    <a href="<s:url action="Saisir"/>"><s:text name="confirm.retour"/></a>
  </body>
</html>
  • linha 7: exibe o rótulo da tecla confirm.title1 encontrado no ficheiro de mensagens [1]
  • linha 10: exibe o rótulo da chave confirm.title2 encontrado no ficheiro de mensagens [3]
  • linha 12: exibe a propriedade «name» da ação [Confirm] que foi executada.
  • linha 14: cria um link para a ação [Enter]. A tag <s:url>, que já vimos anteriormente, será gerada a partir do URL do navegador [2]. O caminho será o de [2] http://localhost:8084/exemple-05/actions e a ação será a do atributo action, neste caso Enter. A URL do link será, portanto, http://localhost:8084/exemple-05/actions/Saisir.action. O texto do link será o rótulo associado à chave confirm.retour [4].

6.6. Os testes

Eis duas solicitações:

Em [1], introduza um nome e envie. Em [2], a página de confirmação.

Em [3], seguimos o link de volta ao formulário. Em [4], o resultado. Tudo foi explicado, exceto a transição de [3] para [4]. Por que não vemos o nome que introduzimos em [4]?

O link em [3] é um link para o URL [http://localhost:8084/exemple-05/actions/Saisir.action]. A ação [Submit] é, portanto, executada. Vejamos a sua configuração em [struts.xml]:


<package name="actions" namespace="/actions" extends="struts-default">
    <action name="Saisir">
      <result name="success">/vues/Saisie.jsp</result>
    </action>
    <action name="Confirmer" class="actions.Confirmer">
      <result name="success">/vues/Confirmation.jsp</result>
    </action>  
</package>

A ação [Enter] não está associada a nenhuma ação. Por isso, a vista [Entry.jsp] é apresentada imediatamente. Vejamos o código desta vista:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="saisie.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="saisie.titre2"/></h1>
    <s:form>
      <s:textfield key="saisie.libelle" name="nom"/>
      <s:submit key="saisie.valider" action="Confirmer"/>
    </s:form>
  </body>
</html>

Na linha 12, o campo de entrada é apresentado. O seu conteúdo é inicializado com a propriedade name. Recorde o que foi mencionado anteriormente sobre o funcionamento da tag <s:property>:

A tag <s:property name="property"> permite-lhe escrever o valor de uma propriedade de um objeto chamado ActionContext. Este objeto contém:

  1. as propriedades da classe associada à ação que foi executada.
  2. os atributos do pedido atual, indicados como <s:property name="#request['key']">
  3. os atributos da sessão do utilizador, indicados como <s:property name="#session['key']">
  4. os atributos da própria aplicação, indicados como <s:property name="#application['key']">
  5. os parâmetros enviados pelo navegador do cliente, indicados como <s:property name="#parameters['key']">
  6. A notação <s:property name="#attr['key']"> exibe o valor de um objeto procurado na página, na solicitação, na sessão e na aplicação, nessa ordem.

Estamos aqui no caso 1. A ação [Enter] não tem nenhuma classe associada. A propriedade name, portanto, não existe. Uma string vazia é então exibida no campo de entrada.

Para exibir em [4] o nome que foi introduzido em [1], utilizaremos a sessão do utilizador.