Skip to content

2. A aplicação strutspersonne

Implementámos uma aplicação «person» utilizando o método tradicional: servlets e páginas JSP. Propomos agora introduzir o Struts utilizando esta mesma aplicação.

2.1. Como funciona a aplicação

Vamos rever como funciona a aplicação «person» que desenvolvemos. Ela consiste em:

  • um servlet principal. Este lida com toda a lógica da aplicação.
  • três páginas JSP: formulaire.personne.jsp, reponse.personne.jsp e erreurs.personne.jsp

A aplicação funciona da seguinte forma. É acessível através do URL http://localhost:8080/personne/main. Neste URL, é apresentado um formulário fornecido pela página formulaire.personne.jsp:

Image

O utilizador preenche o formulário e clica no botão [Submit]. O botão [Reset] é um botão de reinicialização, o que significa que restaura o documento para o estado em que foi recebido. O botão [Delete] é um botão padrão. O utilizador deve fornecer um nome e uma idade válidos. Se não for esse o caso, é-lhe enviada uma página de erro através da página JSP erreurs.personne.jsp. Aqui estão alguns exemplos:

Intercâmbio n.º 1

pedido
resposta

Se clicar no link [Voltar ao formulário], encontrará o formulário tal como o deixou:

Troca n.º 2

pedido
resposta

Se o utilizador enviar dados válidos, a aplicação envia uma resposta através da página JSP reponse.personne.jsp.

Intercâmbio n.º 1

solicitação
resposta

Se clicar no link [Voltar ao formulário], encontrará o formulário tal como o deixou:

Troca n.º 2

pedido
resposta

2.2. A arquitetura Struts da aplicação

Iremos adotar a seguinte arquitetura Struts:

  • Haverá três vistas
  • O controlador será aquele fornecido pelo Struts
  • FormBean é a classe responsável por armazenar os valores do formulário apresentado pela vista form.person.jsp
  • FormAction é a classe responsável por processar os valores do FormBean e especificar a página de resposta a ser enviada:
    • a vista errors.person.jsp se os dados do formulário estiverem incorretos
    • a vista reponse.personne.jsp, caso contrário

Para o programador, a tarefa consiste em escrever o código:

  • as três vistas
  • o FormBean associado ao formulário
  • a classe FormAction responsável pelo processamento do formulário

2.3. Compilação das classes necessárias para a aplicação Struts

Para compilar as classes necessárias para a nossa aplicação, utilizaremos o JBuilder. O JBuilder funciona com um JDK que não contém as classes necessárias para aplicações Struts. Podemos configurar o JBuilder da seguinte forma:

  • Ferramentas / Configurar JDKs

Image

  • Utilize o botão [Adicionar] para adicionar os ficheiros .jar fornecidos pelo Struts aos arquivos de classes do JBuilder. Se tiver extraído o arquivo do Struts para o seu disco, pode adicionar todos os ficheiros .jar da pasta <struts>/lib ao JBuilder:

Image

Pode adicionar todos os ficheiros .jar acima referidos aos arquivos do JBuilder. Já vimos que o Tomcat também precisa de acesso aos arquivos do Struts. Para o Tomcat 4.x, pode colocar os ficheiros .jar do Struts em <tomcat4>\common\lib. Para o Tomcat 5.x, pode colocá-los em <tomcat5>\shared\lib. Pode então configurar o JBuilder para localizar os ficheiros .jar do Struts no mesmo local que o Tomcat. Foi isso que foi feito na captura de ecrã que mostra os ficheiros .jar do JBuilder mencionados anteriormente. Foram retirados de <tomcat5>\shared\lib.

Portanto, se o JBuilder indicar que não consegue encontrar uma classe Struts durante a compilação de uma classe, verifique duas coisas:

  • a ortografia da classe
  • os ficheiros .jar utilizados pelo JBuilder. Todos os ficheiros .jar do Struts devem estar incluídos.

2.4. As vistas da aplicação strutspersonne

As três vistas da aplicação são as seguintes:

  • form.person.jsp: apresenta o formulário para introduzir o nome e a idade de uma pessoa
  • reponse.personne.jsp: apresenta os valores introduzidos, caso sejam válidos
  • errors.person.jsp: apresenta quaisquer erros

2.4.1. A vista erreurs.personne.jsp

Esta vista, que apresenta uma lista de erros, será definida da seguinte forma:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
        <html:errors/>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

Existem duas novas funcionalidades neste código:

  1. a presença de tags <html:XX/>, que não são tags HTML. É possível criar bibliotecas de tags JSP que são convertidas em código Java quando a página JSP é transformada num servlet.
  2. A página JSP deve declarar as bibliotecas de tags que utiliza. Faz-o aqui com a linha
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

Esta linha fornece duas informações:

  • uri: a localização do ficheiro que define as regras de utilização da biblioteca. O ficheiro struts-html.tld está incluído na distribuição do Struts. No exemplo acima, encontra-se na pasta WEB-INF.
  • prefix: o identificador utilizado no código para prefixar as tags da biblioteca. Isto evita conflitos de nomenclatura que poderiam surgir ao utilizar várias bibliotecas de tags simultaneamente. É possível encontrar duas tags com o mesmo nome em duas bibliotecas diferentes. Ao atribuir a cada biblioteca um prefixo diferente, elimina-se qualquer ambiguidade.
  • A tag <html:errors> exibe a lista de erros que o controlador Struts lhe envia.
  • A tag <html:link> gera um link que aponta para /C/page, onde
    • C é o contexto da aplicação
    • page é o URL especificado no atributo page da tag

A

    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>

irá gerar o seguinte código HTML:

<a href="/C/formulaire.do">Retour au formulaire</a>

onde C é o contexto da aplicação

2.4.2. Testar a visualização errors.person.jsp

  • O ficheiro errors.person.jsp está localizado na pasta views da aplicação strutspersonne:

Image

  • O ficheiro struts-html.tld é retirado da distribuição Struts (<struts>/lib) e colocado em WEB-INF:

Image

  • O ficheiro struts-config.xml é modificado da seguinte forma:
<?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>
    <action-mappings>
      <action
          path="/main"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
    </action-mappings>
</struts-config>

Criamos uma nova URL /errors no ficheiro de configuração para ser tratada pelo controlador Struts. A URL /errors.do será redirecionada para a vista /views/errors.person.jsp. O ficheiro struts-config.xml é colocado na pasta WEB-INF.

  • Reiniciamos o Tomcat para que o novo ficheiro struts-config.xml seja tido em conta e, em seguida, solicitamos a URL http://localhost:8080/strutspersonne/erreurs.do:

Image

A tag <html:errors/> não produziu nada. Isto é normal; a ForwardAction não gerou a lista de erros esperada pela tag. No entanto, a resposta acima mostra que a nossa vista JSP está, pelo menos, sintaticamente correta; caso contrário, teríamos recebido uma página de erro. Vamos verificar o código HTML recebido pelo navegador (Ver/Fonte):

<html>
    <head>
      <title>Personne - erreurs</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>        
    <a href="/strutspersonne/formulaire.do">Retour au formulaire</a>    
  </body>
</html>

Repare no link gerado pela tag <html:link>. O contexto /strutspersonne foi automaticamente incluído no link. Isto permite que a aplicação seja movida de um contexto para outro (por exemplo, ao mudar de máquina) sem ter de alterar os links gerados pela tag <html:link>.

2.4.3. A vista reponse.personne.jsp

Esta vista, que confirma os valores introduzidos no formulário, é a seguinte:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<%
    // on récupère les données nom, age
  //String nom=(String)request.getAttribute("nom");
  String nom="jean";

  //String age=(String)request.getAttribute("age"); 
  String age="24"; 
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td><%= nom %>
      </tr>
        <tr>
          <td>Age</td>
        <td><%= age %>
      </tr>
    </table>      
    <br>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

A página apresenta duas informações, [name] e [age], que lhe serão passadas pelo controlador no objeto de pedido predefinido. Aqui, estamos a realizar um teste em que o controlador não terá a oportunidade de definir os valores de [name] e [age]. Por isso, inicializamos estas duas informações com valores arbitrários. Além disso, também aqui o link de retorno ao formulário é gerado por uma tag <html:link>.

2.4.4. Testar a vista reponse.personne.jsp

  • O ficheiro reponse.personne.jsp está localizado na pasta views da aplicação strutspersonne:

Image

  • O ficheiro struts-config.xml é modificado da seguinte forma:
<?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>
    <action-mappings>
      <action
          path="/main"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/reponse"
          parameter="/vues/reponse.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
    </action-mappings>
</struts-config>

Criamos uma nova URL /reponse no ficheiro de configuração para ser tratada pelo controlador Struts. A URL /reponse.do será redirecionada para a vista /vues/reponse.personne.jsp. O ficheiro struts-config.xml é colocado na pasta WEB-INF.

  • Reiniciamos o Tomcat para que o novo ficheiro struts-config.xml seja tido em conta e, em seguida, solicitamos a URL http://localhost:8080/strutspersonne/erreurs.do:

Image

Obtemos exatamente o que esperávamos.

2.4.5. A vista formulaire.personne.jsp

Esta vista apresenta o formulário para introduzir o nome e a idade do utilizador. O seu código JSP é o seguinte:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>
        <h2>Personne - formulaire</h2>
      <hr>
      <html:form action="/main" name="frmPersonne" type="istia.st.struts.personne.FormulaireBean">
          <table>
            <tr>
              <td>Nom</td>
            <td><html:text property="nom" size="20"/></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><html:text property="age" size="3"/></td>
          </tr>
            <tr>
        </table>
        <table>
            <tr>
              <td><html:submit value="Envoyer"/></td>
            <td><html:reset value="Rétablir"/></td>
            <td><html:button property="btnEffacer" value="Effacer" onclick="effacer()"/></td>
          </tr>
        </table>
      </html:form>
    </center>
  </body>
</html>

Vemos a biblioteca de tags struts-html.tld a ser utilizada na visualização de erros. Surgem novas tags:

html:form
é utilizada tanto para gerar a tag HTML <form> como para fornecer informações ao controlador que irá processar este formulário:
action
URL para a qual os valores do formulário serão enviados
nome
nome do formulário HTML. Este é também o nome do bean que armazenará os valores do formulário
tipo
Nome da classe que deve ser instanciada para obter o bean de armazenamento do formulário
Note que o método utilizado para enviar parâmetros do formulário (GET/POST) para o controlador não está especificado. Isto pode ser feito utilizando o atributo method. Se este atributo estiver em falta, o método POST é utilizado por predefinição.
html:text
Utilizado para gerar a tag <input type="text" value="...">:
propriedade
nome do campo no bean do formulário que será associado ao campo de entrada. Quando o formulário é enviado para o servidor (cliente -> servidor), o campo do bean assume o valor do campo de entrada. Quando o formulário é apresentado (servidor -> cliente), o valor contido no campo do bean é apresentado no campo de entrada.
html:submit
é utilizado para gerar a tag HTML <input type="submit"...>
html:reset
é utilizado para gerar a tag HTML <input type="reset"...>
html:button
é utilizado para gerar a tag HTML <input type="button"...>

2.4.6. O bean associado ao formulário formulaire.personne.jsp

  • Com o Struts, cada formulário deve estar associado a um bean responsável por armazenar os valores do formulário e mantê-los na sessão atual. Um bean é uma classe Java que deve seguir uma sintaxe específica. O bean associado a um formulário deve estender a classe ActionForm definida na biblioteca Struts:
public class FormulaireBean extends ActionForm {
  • Os nomes dos atributos do bean devem corresponder aos campos do formulário (atributos de propriedade das tags <html:text> do formulário). Com base no código do formulário anterior, o bean deve, portanto, ter dois campos denominados name e age.
  • Para cada campo XX no formulário, o bean deve definir dois métodos:
    • public void setXX(Type value): para atribuir um valor ao atributo XX
    • public getXX(Value type): para recuperar o valor do campo XX

O bean associado ao formulário anterior poderia ser o seguinte:

package istia.st.struts.personne;

import org.apache.struts.action.ActionForm;

public class FormulaireBean extends ActionForm {
   // name
  private String nom = null;
  public String getNom() {
    return nom;
  }
  public void setNom(String nom) {
    this.nom = nom;
  }

   // age
  private String age = null;
  public String getAge() {
    return age;
  }
  public void setAge(String age) {
    this.age = age;
  }
}

Vamos compilar esta classe utilizando o JBuilder.

2.4.7. Testar a vista formulaire.personne.jsp

O ficheiro formulaire.personne.jsp está localizado na pasta views da aplicação strutspersonne:

Image

  • O ficheiro struts-config.xml é modificado da seguinte forma:
<?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>
    <action-mappings>
      <action
          path="/main"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/reponse"
          parameter="/vues/reponse.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
    </action-mappings>
</struts-config>

No ficheiro de configuração, criamos um novo URL /form para ser tratado pelo controlador Struts. O URL /form.do será redirecionado para a vista /views/form.person.jsp. O ficheiro struts-config.xml é colocado na pasta WEB-INF.

  • Colocamos a classe FormulaireBean em WEB-INF/classes:

Image

  • Reiniciamos o Tomcat para que o novo ficheiro struts-config.xml seja tido em conta e, em seguida, acedemos à URL http://localhost:8080/strutspersonne/formulaire.do:

Image

O formulário é apresentado corretamente. Podemos ficar curiosos para ver como as tags <html:XX> espalhadas pelo código JSP do formulário foram «traduzidas»:

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>

        <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" method="post" action="/strutspersonne/main.do">
          <table>
            <tr>
              <td>Nom</td>
            <td><input type="text" name="nom" size="20" value=""></td>
          </tr>

          <tr>
              <td>Age</td>
            <td><input type="text" name="age" size="3" value=""></td>
          </tr>
            <tr>
        </table>
        <table>
            <tr>

              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" name="btnEffacer" value="Effacer" onclick="effacer()"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>

No formulário resultante, os botões [Reset] e [Clear] funcionam. O botão [Submit] redireciona para o URL /strutspersonne/main.do. De acordo com o ficheiro web.xml da aplicação, o controlador Struts irá tratar disso. De acordo com o ficheiro struts-config.html, o controlador deve redirecionar o pedido para a vista /vues/main.html. Vamos experimentar:

Image

Tudo funciona como esperado. Ainda precisamos de processar efetivamente os valores do formulário, ou seja, escrever a classe Action que irá receber os dados do formulário num objeto FormBean.