1. Generalidades
O PDF do documento está disponível |AQUI|.
1.1. Objetivos
Propomos aqui explorar um método de desenvolvimento chamado STRUTS. O Jakarta Struts é um projeto da Apache Software Foundation (www.apache.org) que tem como objetivo fornecer uma estrutura padrão para o desenvolvimento de aplicativos web em Java, respeitando a arquitetura conhecida como MVC (Modelo-Visão-Controlador).
1.2. O modelo MVC
O modelo MVC busca separar as camadas de apresentação, processamento e acesso aos dados. Uma aplicação web que siga esse modelo será arquitetada da seguinte forma:
![]() |
Essa arquitetura é chamada de arquitetura de três camadas ou de três níveis:
- a interface do usuário é o V (a visão)
- a lógica de aplicação é o C (o controlador)
- as fontes de dados são o M (Modelo)
A interface do usuário costuma ser um navegador da web, mas também pode ser um aplicativo independente que, por meio da rede, envia solicitações HTTP ao serviço web e formata os resultados que este lhe retorna. A lógica de aplicação é constituída por scripts que processam as solicitações do usuário. A fonte de dados costuma ser um banco de dados, mas também pode ser simples arquivos de texto, um diretório LDAP, um serviço web remoto, etc. É recomendável que o desenvolvedor mantenha uma grande independência entre essas três entidades, de modo que, se uma delas mudar, as outras duas não precisem mudar, ou apenas minimamente.
Quando se busca aplicar esse modelo com servlets e páginas JSP, obtém-se a seguinte arquitetura:
![]() |
No bloco [Logique Applicative], distinguem-se
- o servlet, que é a porta de entrada da aplicação, também chamado de controlador
- o bloco [Classes métier], que reúne as classes Java necessárias para a lógica da aplicação;
- o bloco [Classes d'accès aux données], que reúne as classes Java necessárias para obter os dados necessários ao servlet, geralmente dados persistentes (BD, arquivos, serviço WEB, ...)
- o bloco de páginas JSP, que constitui as visualizações da aplicação.
1.3. Uma abordagem de desenvolvimento MVC utilizando servlets e páginas JSP
Definimos uma abordagem para o desenvolvimento de aplicativos web em Java que segue o modelo MVC anterior. Apresentamos aqui um resumo dessa abordagem.
- Começaremos definindo todas as visualizações da aplicação. Estas são as páginas da Web apresentadas ao usuário. Portanto, nos colocaremos na perspectiva do usuário para projetar as visualizações. Distinguem-se três tipos de visualizações:
- o formulário de preenchimento, que tem como objetivo obter informações do usuário. Ele geralmente possui um botão para enviar as informações inseridas ao servidor.
- a página de resposta, que serve apenas para fornecer informações ao usuário. Ela costuma conter um link que permite ao usuário prosseguir na aplicação com outra página.
- a página mista: o servlet enviou ao cliente uma página contendo informações que ele mesmo gerou. Essa mesma página servirá ao cliente para fornecer outras informações ao servlet.
- Cada visualização dará origem a uma página JSP. Para cada uma delas:
- definiremos a aparência da página
- determinaremos quais são as partes dinâmicas da mesma:
- as informações destinadas ao usuário, que deverão ser fornecidas pela servlet como parâmetros à visualização JSP
- os dados inseridos que deverão ser transmitidos ao servlet para processamento. Esses dados deverão fazer parte de um formulário HTML.
- É possível esquematizar as entradas e saídas de cada visualização
![]() |
- as entradas são os dados que o servlet deverá fornecer à página JSP, seja na solicitação (request) ou na sessão (session).
- As saídas são os dados que a página JSP deverá fornecer ao servlet. Elas fazem parte de um formulário HTML, e o servlet as recuperará por meio de uma operação do tipo request.getparameter(...).
- Escreveremos o código Java/JSP de cada visualização. Na maioria das vezes, ele terá o seguinte formato:
<%@ page ... %> // importações de classes mais comuns
<%!
// variáveis de instância da página JSP (=globais)
// necessário apenas se a página JSP tiver métodos que compartilhem variáveis (raro)
...
%>
<%
// recuperação dos dados enviados pelo servlet
// seja na solicitação (request) ou na sessão (session)
...
%>
<html>
...
// aqui, buscaremos minimizar o código Java
</html>
- Agora podemos passar aos primeiros testes. O método de implantação explicado a seguir é específico do servidor Tomcat:
- o contexto da aplicação deve ser criado no arquivo server.xml do Tomcat. Podemos começar testando esse contexto. Seja C esse contexto e DC a pasta associada a ele. Criaremos um arquivo estático test.html, que será colocado na pasta DC. Após iniciar o Tomcat, acessaremos com um navegador a página URL http://localhost:8080/DC/test.html.
- Cada página JSP pode ser testada. Se uma página JSP for chamada de formulaire.jsp, acessaremos com um navegador a página URL http://localhost:8080/DC/formulaire.jsp. A página JSP espera receber valores do servlet que a chama. Como aqui a chamamos diretamente, ela não receberá os parâmetros esperados. Para que os testes sejam possíveis mesmo assim, vamos inicializar nós mesmos, na página JSP, os parâmetros esperados usando constantes. Esses primeiros testes permitem verificar se as páginas JSP estão sintaticamente corretas.
- Em seguida, escrevemos o código do servlet. Este possui dois métodos bem distintos:
- o método init, que serve para:
- recuperar os parâmetros de configuração da aplicação no arquivo web.xml da mesma
- criar, se necessário, instâncias de classes de negócios que serão utilizadas posteriormente
- gerenciar uma eventual lista de erros de inicialização que será retornada aos futuros usuários da aplicação. Esse gerenciamento de erros pode incluir o envio de um e-mail ao administrador da aplicação para alertá-lo sobre uma falha
- o método doGet ou doPost, dependendo da forma como o servlet recebe seus parâmetros dos clientes. Se o servlet gerenciar vários formulários, é recomendável que cada um deles envie uma informação que o identifique de forma única. Isso pode ser feito por meio de um atributo oculto no formulário do tipo <input type="hidden" name="action" value="...">. O servlet pode começar lendo o valor desse parâmetro e, em seguida, delegar o processamento da solicitação a um método interno privado responsável por tratar esse tipo de solicitação.
- Deve-se evitar ao máximo colocar código de negócio no servlet. Ele não foi feito para isso. O servlet é uma espécie de chefe de equipe (controlador) que recebe solicitações de seus clientes (clientes da web) e as encaminha para que sejam executadas pelas pessoas mais adequadas (as classes de negócio). Ao escrever o servlet, deve-se definir a interface das classes de negócio a serem criadas (construtores, métodos). Isso se essas classes de negócio precisarem ser criadas. Se elas já existirem, o servlet deve se adaptar à interface existente.
- O código do servlet será compilado.
- Escreveremos a estrutura básica das classes de negócio necessárias para a servlet. Por exemplo, se a servlet utiliza um objeto do tipo proxyArticles e essa classe deve ter um método getCodes que retorne uma lista (ArrayList) de cadeias de caracteres, pode-se, em um primeiro momento, limitar-se a escrever:
public ArrayList getCodes(){
String[] codes= {"code1","code2","code3"};
ArrayList aCodes=new ArrayList();
for(int i=0;i<codes.length;i++){
aCodes.add(codes[i]);
}
return aCodes;
}
- Agora podemos passar para os testes do servlet.
- O arquivo de configuração web.xml do aplicativo deve ser criado. Ele deve conter todas as informações exigidas pelo método init do servlet (<init-param>). Além disso, define-se o URL por meio do qual o servlet principal será acessado (<servlet-mapping>).
- Todas as classes necessárias (servlet, classes de negócio) são colocadas em WEB-INF/classes.
- Todas as bibliotecas de classes (.jar) necessárias são colocadas em WEB-INF/lib. Essas bibliotecas podem conter classes de negócio, drivers JDBC, etc.
- As visualizações JSP são colocadas na raiz do aplicativo ou em uma pasta própria. O mesmo procedimento se aplica aos demais recursos (HTML, imagens, áudio, vídeos, etc.)
- Feito isso, o aplicativo é testado e os primeiros erros são corrigidos. Ao final dessa fase, a arquitetura do aplicativo está operacional. Essa fase de teste pode ser complicada, já que não há ferramentas de depuração disponíveis no Tomcat. Para isso, seria necessário que o próprio Tomcat estivesse integrado a uma ferramenta de desenvolvimento (JBuilder Developer, Sun One Studio, etc.). É possível utilizar as instruções System.out.println("...."), que exibem mensagens na janela do Tomcat. A primeira coisa a verificar é se o método init está recuperando corretamente todos os dados provenientes do arquivo web.xml. Para isso, pode-se exibir o valor desses dados na janela do Tomcat. Da mesma forma, deve-se verificar se os métodos doGet e doPost recuperam corretamente os parâmetros dos diferentes formulários HTML do aplicativo.
Escrevem-se as classes de negócio necessárias ao servlet. Trata-se, em geral, do desenvolvimento clássico de uma classe Java, na maioria das vezes independente de qualquer aplicação web. Ela será testada inicialmente fora desse ambiente, por exemplo, com uma aplicação de console. Quando uma classe de negócio for escrita, é possível integrá-la à arquitetura de implantação da aplicação web e testar sua integração correta nela. Proceder-se-á dessa forma para cada classe de negócio.
1.4. A abordagem de desenvolvimento STRUTS
Os criadores da metodologia STRUTS buscaram definir um método de desenvolvimento padrão que respeitasse a arquitetura MVC para aplicativos web escritos em Java. Há dois aspectos no projeto STRUTS:
- o método de desenvolvimento. Veremos que ele é bastante semelhante ao descrito acima para servlets e páginas JSP
- as ferramentas que nos permitem aplicar esse método de desenvolvimento. Trata-se de bibliotecas de classes Java disponíveis no site da Fundação Apache (www.apache.org).
1.4.1. O método de desenvolvimento
A arquitetura MVC utilizada pelo STRUTS é a seguinte:
![]() |
- O controlador é o núcleo da aplicação. Todas as solicitações do cliente passam por ele. Trata-se de um servlet genérico fornecido pelo STRUTS. Em alguns casos, pode ser necessário derivá-la. Para casos simples, isso não é necessário. Essa servlet genérica obtém as informações de que necessita em um arquivo geralmente chamado struts-config.xml.
- Se a solicitação do cliente contiver parâmetros de formulário, estes são colocados em um objeto Bean. Uma classe é considerada do tipo bean se seguir as regras de construção que veremos mais adiante. Os objetos bean assim criados ao longo do tempo são armazenados na sessão ou na solicitação do cliente. Esse ponto é configurável. Eles não precisam ser recriados se já tiverem sido criados.
- No arquivo de configuração struts-config.html, a cada URL que deve ser processada por programa (não correspondendo, portanto, a uma visualização JSP que poderia ser solicitada diretamente) são associadas determinadas informações:
- o nome da classe do tipo Action responsável por processar a solicitação. Novamente, o objeto Action instanciado pode ser mantido na sessão ou na solicitação.
- se a URL solicitada for configurada (caso do envio de um formulário ao controlador), o nome do bean responsável por armazenar as informações do formulário é indicado.
- Com essas informações fornecidas por seu arquivo de configuração, ao receber uma solicitação de URL de um cliente, o controlador é capaz de determinar se há um bean a ser criado e qual. Uma vez instanciado, o bean pode verificar se os dados que armazenou, provenientes do formulário, são válidos ou não. Um método do bean chamado `validate` é chamado automaticamente pelo controlador. O bean é criado pelo desenvolvedor. Este, portanto, insere no método `validate` o código que verifica a validade dos dados do formulário. Se os dados forem inválidos, o controlador não seguirá adiante. Ele passará o controle para uma visualização cujo nome encontrará em seu arquivo de configuração. A troca de dados está, então, concluída. Observe-se que o desenvolvedor pode solicitar que a validade do formulário não seja verificada. Ele também faz isso no arquivo struts-config.html. Nesse caso, o controlador não chama o método `validate` do bean.
- Se os dados do bean estiverem corretos, ou se não houver verificação, ou se não houver bean, o controlador passa o controle para o objeto do tipo Action associado ao URL. Ele faz isso solicitando a execução do método `execute` desse objeto, ao qual transmite a referência do bean que, eventualmente, tenha construído. É aqui que o desenvolvedor realiza o que precisa ser feito: ele poderá, se necessário, chamar classes de negócio ou classes de acesso a dados. Ao final do processamento, o objeto `Action` retorna ao controlador o nome da visualização que deve ser enviada como resposta ao cliente.
- O controlador envia essa resposta. A interação com o cliente está concluída.
Começa a se delinear a metodologia de desenvolvimento STRUTS:
- a definição das visualizações. Distingue-se entre as visualizações que são formulários e as demais.
- cada vista de formulário gera uma definição no arquivo struts-config.xml. Nele, definem-se as seguintes informações:
- o nome da classe Bean que conterá os dados do formulário, bem como a indicação de que os dados devem ou não ser validados. Se precisarem ser validados e forem inválidos, deve-se indicar a visualização a ser enviada como resposta ao cliente nesse caso.
- o nome da classe Action responsável pelo processamento do formulário.
- o nome de todas as visualizações que podem ser enviadas ao cliente após o processamento da solicitação. A classe Action selecionará uma delas de acordo com o resultado do processamento.
- cada visualização corresponde a uma página JSP. Veremos que nas visualizações — especialmente nas visualizações de formulários —, às vezes se utiliza uma biblioteca de tags específicas do Struts.
- cada vista de formulário gera uma definição no arquivo struts-config.xml. Nele, definem-se as seguintes informações:
- A criação das classes JavaBean correspondentes às visualizações de formulários
- a criação das classes Action responsáveis pelo processamento dos formulários
- a criação de eventuais classes de domínio ou de acesso aos dados
1.4.2. As ferramentas de desenvolvimento STRUTS
O projeto STRUTS é um dos projetos da Apache Software Foundation. Vários desses projetos estão agrupados sob o nome Jakarta e estão disponíveis no URL http://jakarta.apache.org:

Recomenda-se a leitura desta página. Muitos projetos são de interesse para desenvolvedores Java. Se clicarmos no link “Struts” acima, chegaremos à página inicial do projeto:

Nesse caso também, é recomendável ler a página inicial. Para baixar as bibliotecas Java do Struts, seguimos o link “Binaries” acima:

Para o ambiente Windows, usaremos o link 1.1.zip e 1.1.tar.gz para o ambiente Unix (novembro de 2003). Depois de descompactar o arquivo 1.1.zip, obtemos a seguinte estrutura de diretórios:

Nessa estrutura de diretórios, encontram-se as bibliotecas das classes Java necessárias para o desenvolvimento STRUTS. Elas estão em arquivos .jar ou .war, que são semelhantes aos arquivos .zip. É possível abri-los com os mesmos utilitários. A maioria das bibliotecas necessárias está na pasta lib acima:

Além das bibliotecas de classes .jar, há arquivos .dtd (Document Type Definition) que contêm regras de validade para arquivos XML. Um arquivo XML pode, em seu conteúdo, fazer referência a um arquivo desse tipo, como o DTD. O programa (chamado analisador) que analisa o conteúdo do arquivo XML utilizará as regras de validade encontradas no arquivo DTD referenciado para determinar se o arquivo XML está sintaticamente correto. Assim, por exemplo, o arquivo struts-config_1_1.dtd define as regras de construção do arquivo de configuração struts-config.xml para a versão 1.1 do Struts.
Vamos ver agora onde colocar os diferentes elementos da árvore de diretórios do Struts para implantar uma aplicação Struts no servidor Tomcat.
1.5. Implantação de uma aplicação Struts
Uma aplicação Struts é uma aplicação web como qualquer outra. Portanto, ela segue as regras de implantação do contêiner no qual é executada. Aqui, uma aplicação, que chamaremos de strutspersonne, será executada por um servidor Tomcat versão 4.x. No anexo, encontrará o procedimento de implantação para o Tomcat versão 5.x. Seguiremos aqui as regras de implantação do Tomcat 4.x:
- Definimos o contexto “strutspersonne” no arquivo de configuração server.xml do Tomcat:
Feito isso, reiniciamos o Tomcat, se necessário, para que ele reconheça o novo contexto. Podemos verificar a validade do contexto acessando a página URL http://localhost:8080/strutspersonne:

Se não for exibida uma página de erros, significa que o contexto está correto.
- Criamos, na pasta física associada ao contexto strutspersonne, a subpasta WEB-INF.
- Na pasta WEB-INF do aplicativo, definimos o arquivo de configuração web.xml do aplicativo:

<?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>
</web-app>
- A classe do controlador (servlet) do aplicativo é uma classe predefinida do Struts, chamada ActionServlet. Ela está localizada no arquivo struts.jar. Para que o Tomcat possa localizar essa classe, colocaremos o arquivo struts.jar na pasta <tomcat>\common\lib, que é uma das pastas pesquisadas pelo Tomcat ao procurar por classes. Na verdade, colocaremos lá todos os arquivos .jar encontrados na pasta <struts>\lib, onde <struts> é a pasta raiz da árvore de diretórios do Struts.

- Também devemos colocar os arquivos struts-el.jar e jstl.jar, localizados em <struts>\contrib\struts-el\lib:

- Aqui, temos acesso ao servidor web. Nem sempre é assim. Se estivermos implantando uma aplicação web/Java em um contêiner web que não administramos nós mesmos, é preferível que a aplicação traga consigo todas as bibliotecas de que necessita. Elas devem, então, ser colocadas na pasta WEB-INF/lib, que precisa ser criada.
- Indicamos que o controlador precisava de algumas informações que normalmente encontrava em um arquivo struts-config.xml localizado na mesma pasta que o web.xml. Na verdade, o nome desse arquivo é configurável. É o parâmetro config, acima, que define esse nome.
- A tag <servlet-mapping> indica que o controlador será acessado por meio de todos os arquivos URL que terminam com o sufixo .do. Essa associação é exigida pelo Struts. Esses URL serão, em seguida, filtrados pelo controlador, que aceitará apenas os URL declarados em seu arquivo de configuração struts-config.xml
Por enquanto, nosso arquivo web.xml é suficiente.
- Vamos solicitar o URL /main.do ao aplicativo strutspersonne. De acordo com o arquivo web.xml anterior, essa URL será, portanto, transmitida ao servlet org.apache.struts.action. A classe ActionServlet será instanciada e seu método init será chamado. Esse método tenta ler o arquivo de configuração definido pelo parâmetro config. Portanto, esse arquivo deve existir. Criamos o seguinte arquivo struts-config.xml:
<?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="/main.html"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
</struts-config>
Observe que o arquivo DTD de struts-config.xml não é o mesmo que o do arquivo web.xml, o que indica que eles não têm a mesma estrutura. Para cada URL que o controlador deve gerenciar, precisamos definir uma tag <action>. Ela serve para indicar ao controlador o que ele deve fazer quando for solicitado esse URL. Aqui, indicamos os seguintes elementos:
- path="/main": define o nome do URL configurado pela tag <action>. O sufixo .do é implícito.
- type="org.apache.struts.actions.ForwardAction": define o nome da classe Action que deve processar a solicitação. Aqui, utilizamos uma classe Action predefinida no Struts. Ela não realiza nenhuma ação por conta própria e encaminha a solicitação do cliente para a URL indicada no atributo parameter.
- parameter="/main.html": o nome do URL para o qual a solicitação deve ser encaminhada. Aqui, trata-se de um arquivo HTML estático.
Resumindo, quando o usuário solicitar o URL /main.do, ele receberá o URL /main.html.
- O arquivo main.html será o seguinte:
<html>
<head>
<title>Application strutspersonne</title>
</head>
<body>
Application strutspersonne active ....
</body>
</html>
Este arquivo está localizado na pasta da aplicação strutspersonne/vues:

É possível solicitá-lo diretamente pelo URL http://localhost:8080/strutspersonne/main.html:

Nesse caso, o controlador Struts do aplicativo não foi acionado, pois ele só é acionado quando se solicita o URL do tipo *.do. No entanto, aqui solicitamos o URL /vues/main.html.
- O arquivo struts-config.xml criado anteriormente deve ser colocado na mesma pasta WEB-INF que o arquivo web.xml:

- Agora, vamos verificar se o controlador do aplicativo strutspersonne está funcionando corretamente, solicitando o URL /main.do após, se necessário, reiniciar o Tomcat.

Aqui, o controlador Struts entrou em ação, pois solicitamos um URL do tipo *.do. Recebemos, de fato, a página esperada (main.html). Portanto, temos os elementos básicos do funcionamento da nossa aplicação: o contexto strutspersonne, os arquivos de configuração web.xml e struts-config.xml, as bibliotecas Struts.
O que teria acontecido se tivéssemos solicitado um URL do tipo /toto.do? De acordo com o arquivo web.xml da aplicação strutspersonne, o controlador Struts é então chamado para processá-lo. Ele então consulta seu arquivo de configuração struts-config.html e não encontra nenhuma configuração para o URL /toto. O que ele faz então? Vamos tentar:

Recebemos uma página de erros, o que parece normal. Agora podemos começar a escrever uma aplicação.



