You are on page 1of 28

Tópicos Especiais em Informática I: Desenvolvimento de Aplicações

Web
Prof. M.Sc Fabiano Costa Teixeira

U N I D A D E 4
4 Considerações Iniciais
Até agora as unidades de ensino apresentaram o desenvolvimento de páginas HTML
estáticas. Nessa unidade serão apresentados alguns exemplos de como realizar a geração das
páginas de forma dinâmica utilizando tecnologias Java.

São apresentados os servlets e Java Server Pages. Recomenda-se que os exemplos sejam
executados (o código fonte encontra-se no ambiente para download) para que seja verificado o
comportamento da aplicação.

Uma vez que esse material apresenta alguns conceitos básicos e exemplos, é importante que
a bibliografia seja estudada para que o conhecimento seja ampliado.

4.1 Páginas Dinâmicas

Conforme dito em unidades anteriores, a Web se caracteriza como um sistema distribuído


que faz uso de uma rede de computadores (Internet, por exemplo) como meio de comunicação.
Desta forma, hiperdocumentos são armazenados em um servidor Web, como o Apache, para que
possam ser entregues às aplicações clientes utilizadas pelos usuários para ter acesso ao conteúdo.
Essas aplicações clientes são os navegadores como o Firefox, Internet Explorer, Ópera, entre outros.
Quando a página Web é recebida, o documento HTML (Hiper Text Markup Language) é
processado, o conteúdo formatado e posteriormente apresentado ao usuário.
Em um número bastante grande de casos, as páginas Web apresentam conteúdos
informativos que são apresentados da mesma forma para todos os usuários que as solicitam. Essas
páginas são denominadas estáticas e não exigem nenhum processamento adicional do servidor além
daquele necessário para enviá-la ao usuário. O código abaixo ilustra um exemplo de documento
estático que quando enviado ao cliente é apresentado no navegador conforme ilustrado pela figura
1.
<html>
<body>
<H1>Puc Minas</H1>
</body>
</html>

Figura 1: Apresentação da página estática


Esse tipo de documento é suficiente para casos onde todos os usuários recebem a mesma
informação. No entanto, algumas vezes a apresentação da página é alterada em função de dados
fornecidos pelo usuário. Como exemplo, uma página onde existam duas listas, sendo a primeira
responsável pelos estados da federação e a segunda pelas cidades. Quando o usuário seleciona o
estado desejado, a lista de cidades deve ser carregada com aqueles pertencentes ao país indicado.
Por meio da utilização de scripts que são executados dentro do próprio navegador do cliente
é possível conseguir algo neste sentido. O código apresentado abaixo possui trechos de código
JavaScript que carregam a lista de estados em função do país selecionado.
<html>
<header>
<script type="text/javascript">
function carregaCidades(){
document.getElementById("cidade").options.length = 0;
if(document.getElementById("estado").value=="MG"){
var op = document.createElement('option');
op.text="Belo Horizonte";
op.value="BH";
document.getElementById("cidade").add(op);
op = document.createElement('option');
op.text="Juiz de Fora";
op.value="JF";
document.getElementById("cidade").add(op);
op = document.createElement('option');
op.text="Poços de Caldas";
op.value="PC";
document.getElementById("cidade").add(op);

}else{
var op = document.createElement('option');
op.text="Campinas";
op.value="CA";
document.getElementById("cidade").add(op);
op = document.createElement('option');
op.text="Ribeirão Preto";
op.value="RP";
document.getElementById("cidade").add(op);
op = document.createElement('option');
op.text="São Paulo";
op.value="SP";
document.getElementById("cidade").add(op);
}
}
</script>
</header>
<body>
<Font size="10">Localização</font>
<br><br>
Estado
<select id="estado" onblur="carregaCidades()">
<option value="MG">Minas Gerais</option>
<option value="SP" SELECTED>São Paulo</option>
</select>
<br><br>
Cidade
<select id="cidade">
<option value="CA">Campinas</option>
<option value="RP" selected>Ribeirão Preto</option>
<option value="SP" selected>São Paulo</option>
</select>
</body>
</html>

O código apresentado acima implementa o comportamento citado anteriormente para o caso


dos estados e das cidades. Quando o usuário deixa esse campo, a lista de cidades é automaticamente
carregada em função do estado selecionado. No entanto, embora a apresentação da página seja
alterada em função das informações fornecidas, esse comportamento não é gerenciado pelo
servidor, mas sim pelo código executado pelo próprio navegador do usuário. Sendo assim, todas as
requisições realizadas por diversos usuários diferentes recebem o mesmo documento HTML, sendo
este estático.
Uma vez que o documento é estático, se novas cidades ou estados forem inseridos, é preciso
que haja a intervenção humana para alterar o conteúdo da página. Para que tal procedimento de
alteração manual do código possa ser ignorado, é preciso que exista um SGBD (Sistema de
Gerenciamento de Banco de Dados) como, por exemplo, o MySql onde os dados possam ser
cadastrados e apresentados na página.
Figura 2: Apresentação da página onde a lista de cidades é montada de acordo com o estado selecionado

A apresentação, em uma página Web, dos dados existentes em um SGBD requer que o
documento HTML a ser enviado ao usuário seja gerado automaticamente no momento que o
servidor recebe a requisição, de maneira que os dados possam ser recuperados do banco de dados e
inseridos no documento. Esses documentos gerados automaticamente resultam nas chamadas
páginas dinâmicas.
Para que uma página dinâmica possa ser gerada, o servidor Web (que nesse caso é um
servidor de aplicações) necessita ser capaz de executar um programa desenvolvido, em função das
regras de negócio existentes, para realizar todo o procedimento de busca de dados e escrita da
página Web. A figura 3 ilustra o processo de requisição, geração e recepção de uma página
dinâmica. Primeiramente o navegador envia a requisição de um documento ao servidor Web que ao
receber invoca (2) a aplicação responsável por aquele tipo de requisição. Essa aplicação envia
requisições (3) e recebe respostas de um SGBD (4). Por fim, o documento HTML é escrito pela
aplicação (5) e enviado para o navegador do usuário (6).
Diversas linguagens e plataformas oferecem suporte para a geração dinâmica de páginas
como, por exemplo, PHP, Dot Net, JEE, etc. Para o navegador, a tecnologia usada do lado do
servidor não é importante, uma vez que o documento recebido como resposta (HTML, por
exemplo) seja suportado por ele.
Figura 3: Arquitetura básica de um servidor de aplicações

4.2 JDBC – Java Database Conectivity

Atualmente é possível encontrar sistemas gerenciadores de bancos de dados desenvolvidos e


distribuídos por diversas empresas. As implementações desses sistemas diferem-se entre si de forma
que a maneira de utilizar o produto varia em função do fabricante.

As aplicações corporativas fazem uso maciço de dados armazenados nos SGBDs. Muitas
vezes, é preciso, por diversos motivos, que a aplicação seja capaz de operar com bancos de dados
diferentes, em função da necessidade do cliente. No entanto, se a forma de escrever código fosse
completamente diferente para utilizar SGBDs diferentes, essa flexibilidade seria inviável.

O JDBC (Java Database Conectivity) é uma forma que a tecnologia Java disponibiliza para
que o acesso a um SGBD possa ser realizado. Para isso, a Sun disponibiliza um conjunto de
interfaces que definem e padronizam as operações necessárias para realizar acessos (escrita e
leitura) em um banco de dados.

Uma vez definidas as interfaces, cada fabricante de SGBD deve implementá-las de acordo
com os requisitos do sistema de banco de dados distribuídos por ele. O resultado dessa
implementação gera um pacote de classes que determina o Driver JDBC que deverá ser utilizado
para acessar um determinado SGBD.

Essa sub-seção será focada na utilização do driver JDBC distribuído pelo MySql para
realizar o acesso ao seu sistema de gerenciamento de banco de dados. Para isso, primeiramente é
preciso realizar o download do driver no site do MySql. Acesse o endereço www.mysql.com,
selecione a opção Downloads=>Connectors=>Connector/J=>5.1=>Source and Binaries(zip). O
seguinte link também pode ser utilizado para realizar diretamente o download do driver:
http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-
5.1.8.zip/from/http://mysql.skynet.be/

Após realizar o download é preciso descompactar o arquivo recebido em uma pasta


qualquer. Repare a existência de um arquivo denominado “mysql-connector-java-5.1.8-bin.jar”.
Esse é o arquivo que contém o driver JDBC e que será utilizado para realizar o acesso ao banco de
dados.

Uma vez com o driver em “mãos” é preciso configurar o ambiente NetBeans para que seja
possível fazer uso das classes existentes. Antes de mais nada é necessário que seja criado o projeto
que será utilizado para esse exemplo. Para isso, no NetBeans, selecione Arquivo=>Novo Projeto.
Conforme ilustrado pela figura 4, selecione a categoria “Java Web” e o projeto “Aplicação Web”.

Figura 4: Seleção do tipo de projeto criado


Ao clicar em “Próximo” aparecerá, conforme a figura 5, a tela para determinar o nome do
projeto e a pasta onde os arquivos deverão ser salvos. Nesse exemplo, o nome do projeto é
“SistemaTeste”.
Figura 5: Definição do nome do projeto e local de armazenamento dos arquivos
O próximo passo é definir o tipo de servidor de aplicações que será utilizado na execução da
aplicação web (figura 6). Será feito uso do GlassFish.

Figura 6: Definição do tipo de servidor de aplicações


A próxima tela permite a seleção dos frameworks que serão utilizados no projeto. Nessa
unidade de ensino não será feito uso de nenhum framework. Dessa forma, basta clicar em
“finalizar” para realizar a criação do projeto.

Quando o projeto for finalizado ele aparecerá na guia “projetos” do NetBeans. Para realizar
a configuração para que esse faça uso do driver JDBC é preciso clicar com o botão direito do mouse
sobre o nome do projeto e selecionar “Propriedades”. Será aberta uma tela, conforme a figura 7,
onde é preciso clicar em “Bibliotecas”.

Figura 7: Configurando as bibliotecas a serem utilizadas


Agora, basta clicar em “Adicionar JAR/pasta” e selecionar o arquivo “mysql-connector-
java-5.1.8-bin.jar”.

4.2.1 Tabela Básica

Para realizar os exemplos a seguir é necessário que seja criada uma tabela no servidor
MySql com o nome de “estados”, conforme figuras 4.
Figura 8: Criação da tabela “estados”

4.2.2 Conexão com o SGBD

Para que uma aplicação possa utilizar um SGBD é preciso estabelecer uma conexão entre os
dois. O primeiro passo para isso é realizar a carga das classes Java que implementam o driver JDBC
a ser utilizado. Essa carga é feita utilizando o método estático forName da classe Class.
Após a carga das classes do driver chega o momento de realizar o estabelecimento da
conexão propriamente dita. A classe DriverManager oferece o método getConnection que é
responsável por todo o trabalho da conexão. Esse método recebe três parâmetros: uma string que
informa o endereço IP do servidor e o nome do Schema do banco de dados a serem conectados, o
usuário e a senha. Abaixo é apresentado um exemplo de código que realiza a conexão a um schema
chamado “tópicos” que está localizado um servidor MySql endereçado com o IP 127.0.0.1. O
usuário é “root” que tem a senha “pw”.
public class exemploJdbc{
public static void main(String args[]){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos“,
"root", “pw");
} catch (Exception ex) {
System.out.println("Erro de conexão: " + ex.getMessage());
}
}
}

PS: o trecho em negrito se refere a uma única linha.

4.2.3 Envio de Instruções SQL ao SGBD

Após a conexão ter sido estabelecida com sucesso chega a hora de começar a manipular os
dados. Para isso, é preciso que a aplicação envie, por meio da comunicação estabelecida, comandos
ao servidor MySql e receba os retornos.
A classe Statement do Java tem a função de permitir o envio de uma instrução SQL para um
servidor. Uma vez que ela utiliza a conexão estabelecida para enviar a instrução, para obter uma
instância dessa classe é preciso realizar uma solicitação ao objeto que representa tal conexão.
Voltando ao exemplo anterior, o código abaixo ilustra o processo de obtenção de uma instância da
classe Statement.
public class exemploJdbc{
public static void main(String args[]){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos“,
"root", “pw");
Statement st = con.createStatement();
} catch (Exception ex) {
System.out.println("Erro de conexão: " + ex.getMessage());
}
}
}

Uma vez que se possui um objeto da classe Statement, é possível enviar uma instrução SQL
para o servidor. No entanto, as instruções variam em relação ao seu propósito e por conseqüência o
tipo de dado retornado também. Quando se envia uma instrução de consulta (select) é retornado o
conjunto de registros selecionados do banco. Se a instrução for de alteração de dados (isso inclui:
inserção, remoção e alteração propriamente dita) o retorno é apenas o número de registros da tabela
que foram afetados pela instrução.
A classe Statement oferece dois métodos para o envio de instruções ao SGBD:
• executeUpdate: Permite o envio de uma instrução SQL para atualização do banco de
dados e retorna o número de registros afetados.
• executeQuery: Permite o envio de uma instrução SQL para o servidor e recebe um
objeto contendo os registros selecionados pela instrução.
O código abaixo ilustra um exemplo de como realizar a inserção de um registro na tabela de
estados.
public class exemploJdbc{
public static void main(String args[]){
try {
int num = 0;
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos“,
"root", “pw");
Statement st = con.createStatement();
num = st.executeUpdate(“insert into estados (sigla,nome) values (‘MG’,
‘Minas Gerais’)”);
} catch (Exception ex) {
System.out.println("Erro de conexão: " + ex.getMessage());
}
}
}

4.2.4 Processamento dos Dados Retornados

Quando uma instrução de consulta é enviada ao SGBD o retorno dos dados é realizado pelo
JDBC utilizando um objeto da classe ResultSet. Esse objeto realiza a abstração de uma tabela de
dados e permite que seja realizada uma navegação pelos registros selecionados pela instrução SQL.
É interessante pensar nessa navegação como um “ponteiro” que identifica o registro atual que está
sendo processado. No momento que o objeto da classe ResultSet é criado esse “ponteiro” está
“apontando” para um registro nulo, localizado antes do primeiro existente.
Para realizar a navegação básica nos registros, quatro métodos são de suma importância:
• first: Posiciona o ponteiro no primeiro registro.
• previous: Posiciona o ponteiro no registro anterior.
• next: Posiciona o ponteiro no próximo registro.
• last: Posiciona o ponteiro no último registro.
Esses métodos retornam uma variável booleana que determina se após a execução do
método o ponteiro ficou em um registro válido. Imagine que o ponteiro está localizado no último
registro de uma tabela, se o método next for invocado ele apontará para uma posição nula,
retornando o valor false.
A classe ResultSet oferece métodos que realizam a recuperação dos campos existentes no
registro indicados pelo ponteiro. Para cada tipo de dado existente no banco existe um método
correspondente nessa classe. Como parâmetro para esse método é possível informar o nome do
campo ou sua posição no registro retornado (há uma sobrecarga de métodos). Exemplos de métodos
para retorno de parâmetros são: getString, getInt, etc.
O código abaixo ilustra um exemplo de acesso à tabela de estados. Os dados são
recuperados e apresentados na tela (considerando uma aplicação JSE).
public class exemploJdbc{
public static void main(String args[]){
try {
String sigla, nome;
int num = 0;
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos“,
"root", “pw");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(“select * from estados”);
while(rs.next()){
sigla = rs.getString(“sigla”);
nome = rs.getString(“nome”);
System.out.println(“Sigla: “ + sigla + “ Nome: “ + nome);
}
} catch (Exception ex) {
System.out.println("Erro de conexão: " + ex.getMessage());
}
}
}

4.2.5 Preparação de SQL

No desenvolvimento de aplicações é comum que as SQLs sejam compostas utilizando dados


variáveis. No exemplo citado anteriormente, a inserção do estado no banco de dados é declarado de
forma estática, isso faz com que toda vez os mesmos valores para os campos sigla e nome sejam
utilizados.

De maneira a permitir que a SQL seja criada de forma dinâmica, em função de valores
variáveis, o JDBC disponibiliza uma classe denominada PreparedStatement. Com essa classe o
programador define a estrutura básica da SQL e determina o local onde as variáveis serão inseridas
por meio do sinal de interrogação (?).
Após a preparação da SQL é possível definir qual o valor que deve ser inserido no local de
cada ponto de interrogação existente. Para isso, há um método para cada tipo de dado (setInt,
setString, etc). Uma vez que o método define o tipo de dado utilizado, automaticamente a API faz o
gerenciamento da formatação dos dados variáveis como, por exemplo, colocá-los entre aspas
quando o tipo for String.

public class exemploJdbc{


public static void main(String args[]){
try {
int num = 0;
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos“,
"root", “teste");
PreparedStatement ps = con.prepareStatement(“insert into estados
(sigla,nome) values (?, ?)”);
ps.setString(1, “MG”);
ps.setString(2, “Minas Gerais”);
ps.executeUpdate();
} catch (Exception ex) {
System.out.println("Erro de conexão: " + ex.getMessage());
}
}
}

Note que no método setString (ou para qualquer outro tipo de dado) são informados dois
parâmetros. O primeiro indica qual é o ponto de interrogação que deverá ser substituído pelo valor
do segundo parâmetro.

4.3 JEE – Java Enterprise Edition

O JEE (Java Enterprise Edition) é uma plataforma desenvolvida e mantida pela Sun
Microsystems que dá suporte ao desenvolvimento de sistemas corporativos voltados para Web.
Sendo assim, a plataforma oferece mecanismos para o desenvolvimento de aplicações que serão
hospedadas e executadas em um servidor como, por exemplo, o GlassFish.
Para que a implementação, implantação e execução das aplicações JEE possam ser
realizadas de uma maneira mais ágil e amigável, é bastante interessante a utilização de uma IDE
(Integrated Development Environment). Essa ferramenta provê a abstração de diversas rotinas que
são necessárias durante o processo de desenvolvimento de uma aplicação.
Nos exemplos apresentados neste capítulo, será feito uso de uma IDE chamada NetBeans, o
qual pode ser copiado livremente por meio do site: www.netbeans.org. No momento do download é
bastante importante que seja selecionada a distribuição denominada “Web & Java EE”, pois essa já
inclui os pacotes necessários para o desenvolvimento e um servidor GlassFish embutido.
Visto que o NetBeans é desenvolvido utilizando a linguagem Java, é necessário que exista o
ambiente de execução apropriado para essa plataforma. Sendo assim, previamente é preciso realizar
a instalação do ambiente de desenvolvimento e execução do JSE (Java Standard Edition). O
download pode ser realizado por meio do endereço http://java.sun.com/javase/downloads/index.jsp.

4.3.1 Servlets

Conforme citado anteriormente, para que uma página Web possa ser gerada dinamicamente
é preciso que haja uma aplicação, a ser executada no servidor, que será a responsável pela geração
do documento HTML. A plataforma J2EE oferece os Servlets como uma alternativa para esse
requisito.
Um servlet é uma classe Java que é instanciada e executada pelo servidor de aplicações de
maneira que quando uma requisição de uma página Web é recebida, o servidor invoca a instância
dessa classe para que ela realize a geração do documento HTML (veja a animação “Funcionamento
Básico do Servlet”). Quando um Servlet é executado, sua “saída padrão” é a página HTML que
deverá ser retornada ao navegador web que realizou a requisição HTTP. Voltando à figura 3, o
servlet é a parte da arquitetura que está denominada como “Aplicação”.
Para realizar a criação de um novo Servlet, seleciona-se a opção “Arquivo” da barra de
menus e em seguida a opção “Novo Arquivo”. Será aberta uma janela conforme ilustrado na figura
9, onde se deve selecionar a categoria Web e o tipo de arquivo Servlet.
Figura 9: Seleção do tipo de arquivo a ser criado
Ao clicar no botão “Próximo” será aberta a janela solicitando o nome do Servlet a ser criado
e o pacote Java onde sua classe será inserida. No exemplo dado, conforme figura 10, foi utilizado o
nome “CadastroEstado” para a classe que será inserida no pacote “Cadastro”.

Figura 10: Definição do nome do servlet e pacote


Quando uma requisição de uma página chega ao servidor de aplicações, quando necessário,
este realiza a invocação de uma aplicação, que neste caso é o servlet. Sendo assim, é preciso que
seja realizado um relacionamento entre o endereço informado na URL e o servlet a ser invocado
pelo servidor. Esse relacionamento é informado na janela apresentada no momento final da criação
deste componente, conforme ilustrado pela figura 11. O campo “Nome do Servlet” define qual é o
servlet a ser invocado quando o conteúdo do campo “Padrão de URL” for localizado no endereço da
página requisitada.

Figura 11: Definição da URL que invocará o servlet


Ao solicitar a finalização da criação do Servlet por meio do botão “Finalizar” o código da
classe é apresentado para que a implementação possa ser realizada. O método processRequest é
automaticamente invocado pelo servidor de aplicações quando o servlet é requisitado. Sendo assim,
ele deve conter o código que se deseja que seja executado. Esse código normalmente possui as
regras de negócio que definem o comportamento da aplicação e como o documento HTML de
resposta deve ser gerado.
Para que o desenvolvedor tenha controle sobre o que deverá conter esse documento HTML
que será enviado ao navegador do usuário, existe um objeto denominado out que foi instanciado por
meio da classe PrintWriter. Quando o método println desse objeto é invocado, o texto passado
como argumento para esse parâmetro é inserido no documento HTML a ser retornado ao usuário.
No caso desse exemplo, será confeccionada uma página que será responsável por realizar o
cadastro de um estado. Dessa forma, primeiramente o servlet será codificado para apenas apresentar
um documento HTML contendo o título da página. O código abaixo ilustra esse exemplo:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<TITLE>Topicos Especiais em Informatica</TITLE>");
out.println("</HEAD>");
out.println("<BODY style='font-family:Verdana'>");
out.println("Cadastro de Estados");
out.println("</BODY>");
out.println("</HTML>");
} finally {
out.close();
}
}

Após salvar, faça um teste executando a aplicação. Para isso, basta clicar no botão “Executar
Main Project”, conforme ilustrado na figura 12.

Figura 12: Execução da aplicação


A execução do “Main Project” implica que será realizada a invocação da página principal do
projeto (índex.jsp). No entanto, o que se deseja fazer nesse momento é invocar o servlet
CadastroEstado. Sendo assim, quando o navegador web for aberto é preciso informar a URL que
realiza o mapeamento para esse servlet. Veja o exemplo da figura 13.

Figura 13: Invocação do servlet criado


Repare que ao solicitar a página o que é retornado é o documento HTML gerado pelo servlet
executado.
Agora, deseja-se criar o formulário que irá permitir que o usuário cadastre um novo estado
no sistema. Para isso, será escrito o código Java no servlet conforme o exemplo abaixo.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<HTML>");
out.println("<TITLE>Topicos Especiais em Informatica</TITLE>");
out.println("</HEAD>");
out.println("<BODY style='font-family:Verdana'>");
out.println("<H1>Cadastro de Estados</H1><BR>");
out.println("<FORM action='CadastroEstado' method='get'>");
out.println("Sigla:<BR>");
out.println("<INPUT type='text' name='sigla' size='2' maxlength='2'><BR><BR>");
out.println("Nome:<BR>");
out.println("<INPUT type='text' name='nome' size='45' maxlength='45'><BR><BR>");
out.println("<INPUT type='submit' value='Cadastrar'>");
out.println("</FORM>");
out.println("</BODY>");
out.println("</HTML>");
} finally {
out.close();
}
}

Note que foi criado um formulário conforme visto na unidade de ensino sobre HTML. No
entanto, é importante verificar o conteúdo do atributo “action” do formulário. Esse atributo indica
que quando o formulário for submetido ele deve invocar a URL relativa “/CadastroEstado”. É dito
relativa porque a URL a ser requisitada é composta pelo endereço do servidor onde a página atual
foi requisitada mais o identificador do servlet.
Sendo dessa forma, é fácil verificar que o formulário irá invocar o mesmo servlet que gerou
o HTML ao qual ele pertence. Ao executar essa página agora, se forem digitados nos campos sigla e
nome os valores “MG” e “Minas Gerais”, respectivamente, pode-se notar que os dados do
formulário são enviados como parâmetros na URL. Veja figura 14.
Figura 14: URL utilizada na requisição HTTP quando o formulário é submetido
No entanto, o formulário é reapresentado com os campos em branco. Por que? Porque o
servlet foi executado novamente e ele gera o formulário com os campos vazios. Nesse ponto, torna-
se interessante realizar o tratamento dos parâmetros recebidos. Com isso, o formulário poderia ser
gerado novamente com os valores digitados anteriormente pelo usuário.
O objeto request possui um método chamado getParameter que retorna um determinado
parâmetro. Dessa forma, são criadas duas variáveis do tipo String chamadas sigla e nome, as quais
serão responsáveis por armazenar os valores digitados pelo usuário. Uma vez que esses dados são
conhecidos, pode-se alterar a geração do formulário para que os campos sejam apresentados ao
usuário com os valores digitados. Veja o código abaixo e teste-o.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String sigla, nome;
sigla = request.getParameter("sigla");
if(sigla==null)
sigla="";
nome = request.getParameter("nome");
if(nome==null)
nome="";
out.println("<HTML>");
out.println("<TITLE>Topicos Especiais em Informatica</TITLE>");
out.println("</HEAD>");
out.println("<BODY style='font-family:Verdana'>");
out.println("<H1>Cadastro de Estados</H1><BR>");
out.println("<FORM action='CadastroEstado' method='get'>");
out.println("Sigla:<BR>");
out.println("<INPUT type='text' name='sigla' size='2' maxlength='2'
value='" + sigla + "'><BR><BR>");
out.println("Nome:<BR>");
out.println("<INPUT type='text' name='nome' size='45' maxlength='45'
value='" + nome + "'><BR><BR>");
out.println("<INPUT type='submit' value='Cadastrar'>");
out.println("</FORM>");
out.println("</BODY>");
out.println("</HTML>");
} finally {
out.close();
}
}

Agora que os parâmetros já estão sendo processados, é preciso partir para a última parte
dessa aplicação: salvar os dados no SGBD. Para isso, é preciso realizar os procedimentos descritos
na parte onde foi dito sobre o JDBC. Isso inclui importar as bibliotecas do JDBC, fazer a carga do
driver e implementar o código que realizará o acesso ao banco de dados.
O código abaixo ilustra todo esse processo. É importante notar que ao realizar a
manipulação dos dados no SGBD a aplicação ainda não sabe se o usuário está inserindo ou
atualizando um cadastro. Sendo assim, primeiramente o aplicativo tenta realizar uma alteração, se
não existir registro para a chave primária informada a inserção é realizada.

package Cadastro;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;

/**
*
* @author FabianoC
*/
public class CadastroEstado extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String sigla, nome;
sigla = request.getParameter("sigla");
if(sigla==null)
sigla="";
nome = request.getParameter("nome");
if(nome==null)
nome="";
//Conexão com o banco de dados
if(!nome.equals("")){
//Existe um parâmetro. Realiza a atualização do BD
Class.forName("com.mysql.jdbc.Driver");
Connection con =
DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos", "root", "pw");
PreparedStatement ps = con.prepareStatement("update estados set
nome=? where sigla=?");
ps.setString(1, nome);
ps.setString(2, sigla);
int numReg = ps.executeUpdate();
if(numReg == 0){
//Não há o registro no banco...realiza a inclusão
ps = con.prepareStatement("insert into estados (sigla, nome)
values (?,?)");
ps.setString(1, sigla);
ps.setString(2, nome);
ps.executeUpdate();
}
con.close();
}
out.println("<HTML>");
out.println("<TITLE>Topicos Especiais em Informatica</TITLE>");
out.println("</HEAD>");
out.println("<BODY style='font-family:Verdana'>");
out.println("<H1>Cadastro de Estados</H1><BR>");
out.println("<FORM action='CadastroEstado' method='get'>");
out.println("Sigla:<BR>");
out.println("<INPUT type='text' name='sigla' size='2' maxlength='2' value='" + sigla +
"'><BR><BR>");
out.println("Nome:<BR>");
out.println("<INPUT type='text' name='nome' size='45' maxlength='45' value='" + nome +
"'><BR><BR>");
out.println("<INPUT type='submit' value='Cadastrar'>");
out.println("</FORM>");
out.println("</BODY>");
out.println("</HTML>");
}catch(Exception e){
out.println("Erro: " + e.getMessage());
} finally {
out.close();
}
}
...
}

Atenção: Não esqueça de alterar o usuário e senha do banco para aqueles que foram
configurados no seu servidor MySql.

4.3.2 Gerenciamento de Sessão do Usuário

Em uma aplicação web é muito comum que seja necessário que páginas (ou servlets, no caso
desse exemplo) compartilhem informações entre si. Muitas vezes, determinadas informações devem
permanecer disponíveis enquanto o usuário utiliza o sistema.

Para isso, é disponibilizado o conceito de sessão de usuário que permite que dados de um
determinado usuário permaneçam no servidor entre diversas conexões HTTP. Como exemplo disso,
imagine um sistema web que possua diversas páginas diferentes e no início é preciso que o usuário
se identifique por meio de um processo de login. Dessa forma, as informações sobre o usuário que
foram informadas nessa tela devem estar disponíveis para todas as páginas que forem acessadas
pelo usuário.

Voltando ao exemplo utilizado nessa unidade de ensino, suponha que seja necessário inserir
uma página que obrigue o usuário informar seu nome. Se o nome é informado corretamente é feito
um redirecionamento para o cadastro de estados, caso contrário é apresentada uma mensagem
dizendo da obrigatoriedade da informação.

Uma vez que o nome foi informado é preciso armazená-lo na sessão do usuário para que
esse dado seja utilizado pelas demais páginas da aplicação. Para isso, a classe HttpServletRequest
oferece o método getSession, o qual retorna um objeto da classe HTTPSession que é responsável
por gerenciar a sessão do usuário. Essa classe HTTPSession possui vários métodos para o
gerenciamento de sessões. No entanto, é importante destacar alguns deles:

• setAttribute: Permite que um objeto Java seja armazenado na sessão. Esse objeto é
associado a um nome.

• getAttribute: Realiza a recuperação de um objeto Java armazenado na sessão.


• invalidate: Invalida a sessão, removendo todos os objetos nela armazenados.

O servlet do exemplo abaixo é chamado de Entrada. Ele realiza a solicitação do nome do


usuário, o armazena na sessão e redireciona a página para o cadastro de estados por meio do método
sendRedirect na classe HTTP ServletResponse.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");

PrintWriter out = response.getWriter();

try {

request.getSession().invalidate();

String nome;

out.println("<html>");

out.println("<head>");

out.println("<title>Seja bem vindo</title>");

out.println("</head>");

out.println("<body style='font-family:Verdana'>");

nome = request.getParameter("nome");

if(nome!= null)

//Usuário clicou em "Entrar"...

if(nome.equals(""))

//Usuário deixou nome em branco...

out.println("<H2 style='color:red'>Nome inválido</H2><BR>");

else{

//Armazena nome na sessão...

request.getSession().setAttribute("nomeUsuario", nome);

response.sendRedirect("CadastroEstado");

out.println("Digite seu nome: ");

out.println("<FORM action='Entrada' method='GET'");

out.println("<INPUT type='text' name='nome' size='20' maxLength='20'>");

out.println("<INPUT type='submit' value='Entrar'>");

out.println("</FORM>");

out.println("</body>");

out.println("</html>");
} finally {

out.close();

Figura 15: Tela de entrada do sistema


Repare que foi feito um teste para verificar se o nome do usuário foi informado. Se não foi
informado a página é gerada com uma mensagem de erro, conforme figura 15. Caso tenha sido
informado, o nome do usuário é armazenado na sessão e a página é redirecionada para o cadastro de
estados que tem o código alterado apresentado abaixo. No cadastro de estados analise o trecho
destacado e veja que é feita uma busca pelo nome do usuário “logado”. Caso não exista essa
informação, quer dizer que o usuário não passou pela tela de login e por isso é feito um
redirecionamento para essa página. Caso contrário, o nome é apresentado conforme apresentado
pela figura 16.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String sigla, nome;
sigla = request.getParameter("sigla");
if(sigla==null)
sigla="";
nome = request.getParameter("nome");
if(nome==null)
nome="";
//Conexão com o banco de dados
if(!nome.equals("")){
//Existe um parâmetro. Realiza a atualização do BD
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos", "root", "pw");
PreparedStatement ps = con.prepareStatement("update estados set nome=? where sigla=?");
ps.setString(1, nome);
ps.setString(2, sigla);
int numReg = ps.executeUpdate();
if(numReg == 0){
//Não há o registro no banco...realiza a inclusão
ps = con.prepareStatement("insert into estados (sigla, nome) values (?,?)");
ps.setString(1, sigla);
ps.setString(2, nome);
ps.executeUpdate();
}
con.close();
}
String usuario = (String)request.getSession().getAttribute("nomeUsuario");
if(usuario==null)
response.sendRedirect("Entrada");
out.println("<HTML>");
out.println("<TITLE>Topicos Especiais em Informatica</TITLE>");
out.println("</HEAD>");
out.println("<BODY style='font-family:Verdana'>");
out.println("<H1>Cadastro de Estados</H1>");
out.println("Usuário logado: " + usuario + "<BR><BR>");
out.println("<FORM action='CadastroEstado' method='get'>");
out.println("Sigla:<BR>");
out.println("<INPUT type='text' name='sigla' size='2' maxlength='2' value='" + sigla +
"'><BR><BR>");
out.println("Nome:<BR>");
out.println("<INPUT type='text' name='nome' size='45' maxlength='45' value='" + nome +
"'><BR><BR>");
out.println("<INPUT type='submit' value='Cadastrar'>");
out.println("</FORM>");
out.println("</BODY>");
out.println("</HTML>");
}catch(Exception e){
out.println("Erro: " + e.getMessage());
} finally {
out.close();
}
}
Figura 16: Tela de cadastro informando o usuário armazenado na sessão

4.3.3 JSP - Java Server Pages

A utilização dos servlets fornece ao desenvolvedor os mecanismos necessários para o


desenvolvimento de uma aplicação Web que realiza a geração dinâmica de páginas. No entanto, a
manipulação de elementos estáticos como marcações HTML, scripts, entre outros, muitas vezes
pode tornar exaustivo o trabalho do desenvolvedor.
De maneira a facilitar o trabalho da codificação da aplicação Web e manter a flexibilidade, o
JSP (Java Server Pages) permite a mesclagem entre código Java e HTML. No entanto, quando uma
página JSP é desenvolvida e implantada a plataforma realiza o processamento de seu código
gerando um servlet que implementa um código Java com uma semântica idêntica àquela existente
no documento original.
Para que o código Java possa ser distinguido do código HTML existente na página JSP, é
necessário que ele seja circundado pelas marcações <% e %>. Como exemplo, o documento JSP
abaixo (EntradaSistema.jsp) que apresenta uma página de entrada no sistema igual aquela
desenvolvida utilizando servlets.

<%@page contentType="text/html" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Seja bem vindo</title>
</head>
<body style='font-family:Verdana'>
<%
String nome = request.getParameter("nome");
if(nome!= null)
//Usuário clicou em "Entrar"...
if(nome.equals(""))
//Usuário deixou nome em branco...
out.println("<H2 style='color:red'>Nome inválido</H2><BR>");
else{
//Armazena nome na sessão...
request.getSession().setAttribute("nomeUsuario", nome);
response.sendRedirect("CadastroEstado");
}
%>
Digite seu nome:
<FORM action="EntradaSistema.jsp" method="GET">
<INPUT type='text' name='nome' size='20' maxLength='20'>
<INPUT type='submit' value='Entrar'>
</FORM>
</body>
</html>

Observe que as tags HTML são inseridas normalmente, o que indica que elas deverão ser
enviadas dessa forma para o navegador. O código Java é executado e a instrução out.println
adiciona de forma dinâmica novos elementos ao hiperdocumento.
O próximo exemplo (EntradaSistema.jsp) apresenta uma página web igual aquela
apresentada pelo servlet CadastroEstado. É interessante notar que a utilização do JSP agiliza de
forma significativa a produção no desenvolvimento de aplicações.
No servlet, para inserir o valor de uma variável no documento HTML pode-se usar a
concatenação da parte estática do elemento e a variável. Repare o exemplo da propriedade value do
elemento do formulário responsável por receber a sigla do estado.
No JSP, como é possível escrever o texto HTML diretamente no documento desenvolvido, é
permitido que o valor de uma variável seja acrescentado de maneira bastante simples, utilizando <
%=variável%>. Dessa forma, no momento da geração do documento hipertexto a ser enviado ao
navegador o valor da variável é recuperado e inserido automaticamente.

<%@page contentType="text/html" pageEncoding="UTF-8"%>


<%@page import="java.sql.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%
String sigla, nome, usuario;
sigla = request.getParameter("sigla");
if(sigla==null)
sigla="";
nome = request.getParameter("nome");
if(nome==null)
nome="";
if(!nome.equals("")){
//Existe um parâmetro. Realiza a atualização do BD
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1/topicos", "root", "pw");
PreparedStatement ps = con.prepareStatement("update estados set nome=? where sigla=?");
ps.setString(1, nome);
ps.setString(2, sigla);
int numReg = ps.executeUpdate();
if(numReg == 0){
//Não há o registro no banco...realiza a inclusão
ps = con.prepareStatement("insert into estados (sigla, nome) values (?,?)");
ps.setString(1, sigla);
ps.setString(2, nome);
ps.executeUpdate();
}
con.close();
}
usuario = (String)request.getSession().getAttribute("nomeUsuario");
if(usuario==null)
response.sendRedirect("EntradaSistema.jsp");
%>
<HTML>
<HEAD>
<TITLE>Topicos Especiais em Informatica</TITLE>
</HEAD>
<BODY style='font-family:Verdana'>
<H1>Cadastro de Estados</H1>
Usuário logado: <%=usuario%><BR><BR>
<FORM action='CadastroEstado.jsp' method='get'>
Sigla:<BR>
<INPUT type='text' name='sigla' size='2' maxlength='2' value='<%=sigla%>'><BR><BR>
Nome:<BR>
<INPUT type='text' name='nome' size='45' maxlength='45' value='<%=nome%>'><BR><BR>
<INPUT type='submit' value='Cadastrar'>
</FORM>
</BODY>
</HTML>

4.4 Considerações Finais

Nessa unidade de ensino foram apresentados alguns exemplos que demonstram a utilização
de tecnologias Java na implementação de aplicações web. Foi visto como implementar uma
aplicação simples utilizando servlets e JSP.

You might also like