Escolar Documentos
Profissional Documentos
Cultura Documentos
Servlets Java para Desenvolvimento Web 1 PDF
Servlets Java para Desenvolvimento Web 1 PDF
CAPTULO 5
Servlets
"Vivemos todos sob o mesmo cu, mas nem todos temos o mesmo horizonte."
Konrad Adenauer
Hoje, boa parte do que se acessa na Web (portais, blogs, home bankings etc)
baseado em contedo dinmico. O usurio requisita algo ao servidor que, por sua
vez, processa essa requisio e devolve uma resposta nova para o usurio.
Uma das primeiras ideias para esses "geradores dinmicos" de pginas HTML
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 1/28
12/11/2014 Servlets - Java para Desenvolvimento Web
foi fazer o servidor Web invocar um outro programa externo em cada requisio
para gerar o HTML de resposta. Era o famoso CGI que permitia escrever pequenos
programas para apresentar pginas dinmicas usando, por exemplo, Perl, PHP,
ASP e at C ou C++.
5.2 - SERVLETS
Uma primeira ideia da servlet seria que cada uma delas responsvel por uma
pgina, sendo que ela l dados da requisio do cliente e responde com outros
dados (uma pgina HTML, uma imagem GIF etc). Como no Java tentamos sempre
que possvel trabalhar orientado a objetos, nada mais natural que uma servlet seja
representada como um objeto a partir de uma classe Java.
Cada servlet , portanto, um objeto Java que recebe tais requisies (request) e
produz algo (response), como uma pgina HTML dinamicamente gerada.
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 2/28
12/11/2014 Servlets - Java para Desenvolvimento Web
O comportamento das servlets que vamos ver neste captulo foi definido na
classe HttpServletdo pacote javax.servlet.
A interface Servlet a que define exatamente como uma servlet funciona, mas
no o que vamos utilizar, uma vez que ela possibilita o uso de qualquer protocolo
baseado em requisies e respostas, e no especificamente o HTTP.
Para escrevermos uma servlet, criamos uma classe Java que estenda
HttpServlete sobrescreva um mtodo chamado service. Esse mtodo ser o
responsvel por atender requisies e gerar as respostas adequadas. Sua
assinatura:
// escreve o texto
out.println("<html>");
out.println("<body>");
out.println("Primeira servlet");
out.println("</body>");
out.println("</html>");
}
}
O nico objetivo da servlet acima exibir uma mensagem HTML simples para os
usurios que a requisitarem. Mas note como seria muito fcil escrever outros
cdigos Java mais poderosos para gerar as Strings do HTML baseadas em
informaes dinmicas vindas, por exemplo, de um banco de dados.
Servlet x CGI
Esse captulo est focado na HttpServlet, um tipo que gera aplicaes Web
baseadas no protocolo HTTP, mas vale lembrar que a API no foi criada
somente para este protocolo, podendo ser estendida para outros protocolos
tambm baseados em requisies e respostas.
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 4/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Acabamos de definir uma Servlet, mas como vamos acess-la pelo navegador?
Qual o endereo podemos acessar para fazermos com que ela execute? O container
no tem como saber essas informaes, a no ser que digamos isso para ele. Para
isso, vamos fazer um mapeamento de uma URL especfica para uma servlet atravs
do arquivo web.xml, que fica dentro do WEB-INF.
Uma vez que chamar a servlet pelo pacote e nome da classe acabaria criando
URLs estranhas e complexas, comum mapear, por exemplo, uma servlet como
no exemplo, chamada OiMundopara o nome primeiraServlet:
<servlet>
<servlet-name>primeiraServlet</servlet-name>
<servlet-class>br.com.caelum.servlet.OiMundo</servlet-class>
</servlet>
Em seguida, mapeie nossa servlet para a URL /oi. Perceba que isso acontece
dentro da tag <servlet-mapping>(mapeamento de servlets) e que voc tem que
indicar que est falando daquela servlet que definimos logo acima: passamos o
mesmo servlet-namepara o mapeamento.
<servlet-mapping>
<servlet-name>primeiraServlet</servlet-name>
<url-pattern>/oi</url-pattern>
</servlet-mapping>
Portanto, so necessrios dois passos para mapear uma servlet para uma URL:
http://localhost:8080/fj21-agenda/oi
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 5/28
12/11/2014 Servlets - Java para Desenvolvimento Web
<servlet-mapping>
<servlet-name>primeiraServlet</servlet-name>
<url-pattern>/oi/*</url-pattern>
</servlet-mapping>
Voc ainda pode configurar "extenses" para as suas servlets, por exemplo, o
mapeamento abaixo far com que sua servlet seja chamada por qualquer requisio
que termine com .php:
<servlet-mapping>
<servlet-name>primeiraServlet</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 6/28
12/11/2014 Servlets - Java para Desenvolvimento Web
a. Estenda HttpServlet:
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
queremos apenas que nossa Servlet monte uma pgina HTML simples para
testarmos.Cuidado em tirar a chamada ao super.serviceantes e repare que a
declarao do mtodo j foi feita no passo anterior.
out.println("<html>");
out.println("<head>");
out.println("<title>Primeira Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Oi mundo Servlet!</h1>");
out.println("</body>");
out.println("</html>");
}
2. Abra o arquivo web.xml e mapeie a URL /oi para a servlet OiMundo. Aproveite o
autocompletar do Eclipse e cuidado ao escrever o nome da classe e do pacote.
<servlet>
<servlet-name>servletOiMundo</servlet-name>
<servlet-class>
br.com.caelum.servlet.OiMundo
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletOiMundo</servlet-name>
<url-pattern>/oi</url-pattern>
</servlet-mapping>
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 8/28
12/11/2014 Servlets - Java para Desenvolvimento Web
<url-pattern>oi</url-pattern>
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 9/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Nesse caso, uma exceo acontecer no momento em que o tomcat for inicializado:
<servlet-class>br.caelum.servlet.OiMundo</servlet-class>
<servlet-class>br.com.caelum.servlet</servlet-class>
@WebServlet("/oi")
public class OiServlet3 extends HttpServlet {
...
}
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 10/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Se quisermos que nossa Servlet seja acessado atravs de apenas uma URL,
recomenda-se definir a URL diretamente no atributo valuecomo no exemplo
acima. Mas se precisarmos definir mais de uma URL para acessar a Servlet,
podemos utilizar o atributo urlPatternse passar um vetor de URLs:
bom reforar que, mesmo a Servlet estando anotado com @WebServlet(), ele
deve obrigatoriamente realizar um extends a classe
javax.servlet.http.HttpServlet.
Arquivo web.xml
@WebServlet(
name = "OiServlet3",
urlPatterns = {"/oi"},
initParams = {
@WebInitParam(name = "param1", value = "value1"),
@WebInitParam(name = "param2", value = "value2")}
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 11/28
12/11/2014 Servlets - Java para Desenvolvimento Web
)
public class OiServlet3 {
...
}
// cdigo omitido
private String parametro1;
private String parametro2;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.parametro1 = config.getInitParameter("param1");
this.parametro2 = config.getInitParameter("param2");
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.close();
}
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 12/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Conhea a Alura.
<html>
<body>
<form action="adicionaContato">
Nome: <input type="text" name="nome" /><br />
E-mail: <input type="text" name="email" /><br />
Endereo: <input type="text" name="endereco" /><br />
Data Nascimento: <input type="text" name="dataNascimento" /><br />
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 13/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Repare que indicamos tambm o pattern (formato) com que essa data deveria
chegar para ns, atravs do parmetro passado no construtor de
SimpleDateFormatcom o valor dd/MM/yyyy. Temos que tomar cuidado pois o
mtodo parselana uma exceo do tipo ParseException. Essa exceo indica
que o que foi passado na data no pde ser convertido ao pattern especificado. Com
o objeto do tipo java.util.Dateque foi devolvido, queremos criar um Calendar.
Para isso vamos usar o mtodo setTimeda classe Calendar, que recebe um Date.
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 14/28
12/11/2014 Servlets - Java para Desenvolvimento Web
dataNascimento = Calendar.getInstance();
dataNascimento.setTime(date);
Vamos utilizar tambm o nosso DAO para gravar os contatos no banco de dados.
No final, a nossa Servletficar da seguinte forma:
@WebServlet("/adicionaContato")
public class AdicionaContatoServlet extends HttpServlet {
protected void service(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// salva o contato
ContatoDao dao = new ContatoDao();
dao.adiciona(contato);
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 15/28
12/11/2014 Servlets - Java para Desenvolvimento Web
1. Como vamos precisar gravar contatos, precisaremos das classes para trabalhar
com banco de dados que criamos no captulo de JDBC. Para isso, deixamos
disponvel um arquivo zip contendo as classes necessrias que criamos
anteriormente.
b. Dentro da janela de Import, escolha General -> Archive File e clique em Next:
Em casa
Caso voc esteja fazendo em casa, voc pode usar exatamente as mesmas
classes criadas durante os exerccios do captulo de JDBC. No esquea de
copiar tambm o Driver do MySQL.
2. Temos que criar a pgina que permitir aos usurios cadastrar os contatos
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 16/28
12/11/2014 Servlets - Java para Desenvolvimento Web
d. Esse arquivo HTML dever ter o seguinte contedo (cuidado com o nome dos
inputs):
<html>
<body>
<h1>Adiciona Contatos</h1>
<hr />
<form action="adicionaContato">
Nome: <input type="text" name="nome" /><br />
E-mail: <input type="text" name="email" /><br />
Endereo: <input type="text" name="endereco" /><br />
Data Nascimento:
<input type="text" name="dataNascimento" /><br />
@WebServlet("/adicionaContato")
public class AdicionaContatoServlet extends HttpServlet {
protected void service(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// busca o writer
PrintWriter out = response.getWriter();
// salva o contato
ContatoDao dao = new ContatoDao();
dao.adiciona(contato);
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 18/28
12/11/2014 Servlets - Java para Desenvolvimento Web
<servlet>
<servlet-name>AdicionaContato</servlet-name>
<servlet-class>
br.com.caelum.agenda.servlet.AdicionaContatoServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AdicionaContato</servlet-name>
<url-pattern>/adicionaContato</url-pattern>
</servlet-mapping>
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 19/28
12/11/2014 Servlets - Java para Desenvolvimento Web
Como no tnhamos definido, por padro ento usado o mtodo GET, que
indica que os valores dos parmetros so passados atravs da URL junto dos
nomes dos mesmos, separados por &, como em:
nome=Adriano&email=adriano@caelum.com.br
O que ser que vai acontecer se algum SQL do nosso DAO contiver erro de
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 20/28
12/11/2014 Servlets - Java para Desenvolvimento Web
sintaxe e o comando no puder ser executado? Ser que vai aparecer uma
mensagem agradvel para o usurio?
Para fazermos isso, basta configurarmos nossa aplicao dizendo que, caso
acontea uma Exception, uma pgina de erro dever ser exibida. Essa configurao
feita no web.xml, com a seguinte declarao:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/erro.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
Wrapping em ServletException
Caso acontea uma exceo que seja do tipo checada (no filha de
RuntimeException), tambm teramos que repass-la para container. No
entanto, o mtodo services nos permite lanar ServletExceptione
IOException.
try {
// cdigo que pode lanar SQLException
} catch (SQLException e) {
throw new ServletException(e);
}
<html>
<body>
Um erro ocorreu!
</body>
</html>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/erro.html</location>
</error-page>
2. Vamos criar uma pgina para ser exibida quando o usurio acessar algo
inexistente:
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 22/28
12/11/2014 Servlets - Java para Desenvolvimento Web
<html>
<body>
A pgina acessada no existe.
</body>
</html>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
Toda Servlet deve possuir um construtor sem argumentos para que o container
possa cri-lo. Aps a criao, o servlet container inicializa a Servlet com o mtodo
init(ServletConfig config)e o usa durante todo o seu perodo ativo, at que
vai desativ-lo atravs do mtodo destroy(), para ento liberar o objeto.
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 23/28
12/11/2014 Servlets - Java para Desenvolvimento Web
importante perceber que a sua Servlet ser instanciado uma nica vez pelo
container e esse nico objeto ser usado para atender a todas as requisies de
todos os clientes em threads separadas. Alis, justo isso que traz uma melhoria
em relao aos CGI comuns que disparavam diversos processos.
void destroy();
@WebServlet("/minhaServlet")
public class MinhaServlet extends HttpServlet {
Um exemplo simples para nos auxiliar enxergar isso uma Servlet com uma
varivel para contar a quantidade de requisies:
@WebServlet("/contador")
public class Contador extends HttpServlet {
private int contador = 0; //variavel de instncia
// recebe o writer
PrintWriter out = response.getWriter();
// escreve o texto
out.println("<html>");
out.println("<body>");
out.println("Contador agora : " + contador);
out.println("</body>");
out.println("</html>");
}
}
Sabemos que compartilhar variveis entre mltiplas Threads pode nos trazer
problemas graves de concorrncia. Se duas threads (no caso, duas requisies)
modificarem a mesma varivel ao "mesmo tempo", podemos ter perda de
informaes mesmo em casos simples como o do contador acima.
H duas solues para esse problema. A primeira seria impedir que duas threads
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 25/28
12/11/2014 Servlets - Java para Desenvolvimento Web
acessem ao mesmo tempo o mesmo objeto crtico; para isso, podemos sincronizar
o mtodo service. Mas isso traria muitos problemas de escalabilidade (apenas uma
pessoa por vez poderia requisitar minha pgina). A outra soluo, mais simples,
apenas no compartilhar objetos entre threads.
Quando se fala de Servlets, a boa prtica diz para evitar usar atributos
compartilhados.
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 26/28
12/11/2014 Servlets - Java para Desenvolvimento Web
CAPTULO ANTERIOR:
PRXIMO CAPTULO:
JavaServer Pages
Blog Caelum
Cursos Online
Newsletter
Casa do Cdigo
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 27/28
12/11/2014 Servlets - Java para Desenvolvimento Web
http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servlets 28/28