
O que é um servlet?
Primeiro, vamos descobrir o que são servlets e por que você ouve falar deles com tanta frequência. A API Java Servlet é uma API padronizada destinada a ser implementada no servidor. Ele interage com os clientes de acordo com um esquema de solicitação-resposta. Um servlet é uma classe que pode receber solicitações de um cliente e retornar respostas para o cliente. Na verdade, os servlets são exatamente os blocos de construção que usamos para criar uma arquitetura cliente-servidor em Java. Você deve se lembrar que já falamos sobre essa arquitetura em outro artigo da série. Não vamos fazer rodeios: vamos escrever algum código imediatamente.O que você precisa para criar um aplicativo da web
Para maior comodidade ao trabalhar com servlets Java, você precisa do IntelliJ IDEA Ultimate Edition. É um produto pago, mas você pode ativar um teste de 30 dias ou usar a versão de acesso antecipado, que é sempre gratuita. Além disso, instale o Apache Tomcat — o servidor do nosso aplicativo. O Tomcat é um contêiner de servlet: ele processa as solicitações recebidas e as passa para nosso aplicativo. Baixe o Tomcat aqui .Vamos criar nossa primeira aplicação web
Se tudo estiver pronto, crie um projeto Maven. Se você não está familiarizado com o Maven, dê uma olhada no artigo anterior . Vamos começar!-
Em pom.xml, adicione uma dependência javax.servlet-api e especifique o pacote WAR:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>servlets</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> </dependencies> </project>
Classe de servlet simples:
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/hello") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter printWriter = resp.getWriter(); printWriter.write("Hello!"); printWriter.close(); } }
-
Para executar o aplicativo, você precisa criar uma configuração do Tomcat:
-
Em seguida, indicamos qual versão do Tomcat usaremos, a URL e a porta para comunicação com o servidor. Você deve ter algo assim:
-
Agora só precisamos especificar o artefato (o projeto montado em um arquivo JAR) que será implantado no contêiner. Você pode clicar no botão Corrigir e selecionar guerra explodida : isso significa que, após a reconstrução do projeto, o artefato será automaticamente colocado no contêiner do servlet.
-
O valor padrão para Application context é servlets_war_exploded . Isso significa que acessamos o aplicativo em: http://localhost:8080/servlets_war_exploded .
Por que iríamos querer algum texto extra? Vamos deletar o que é desnecessário. Agora, o endereço do nosso aplicativo da web é: http://localhost:8080 .
-
Clique OK. Vemos que agora podemos iniciar o aplicativo:
Agora, quando você abrir o aplicativo em seu navegador, deverá receber um erro 404. Isso faz sentido, porque o endereço http://localhost:8080/ precisa de um servlet mapeado para "/", mas nosso único servlet é mapeado para "/hello" .
-
Podemos acessá-lo em http://localhost:8080/hello . Depois de fazer isso, obtemos a resposta esperada — a string "Hello"!
@WebServlet()
anotação. É aqui que vinculamos (ou mapeamos) o servlet a um caminho específico ("/hello"). Essa anotação apareceu apenas no Java Servlet API 3.0, então a Internet tem muitos exemplos onde o mapeamento de servlet acontece por meio de um arquivo XML. Isso não é mais necessário. Para lidar com solicitações GET , substituímos o doGet()
método. Preste atenção nos parâmetros do método: HttpServletRequest
e HttpServletResponse
. O HttpServletRequest
objeto nos fornece todas as informações necessárias sobre a solicitação. No HttpServletResponse
, escrevemos nossa resposta e definimos os cabeçalhos necessários.
Trabalhando com parâmetros e uma sessão
Vamos melhorar nosso servlet para que ele possa processar os parâmetros da requisição e trabalhar com uma sessão:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html");
PrintWriter printWriter = resp.getWriter();
if (username == null) {
printWriter.write("Hello, Anonymous" + "<br>");
} else {
printWriter.write("Hello, " + username + "<br>");
}
printWriter.write("Page was visited " + visitCounter + " times.");
printWriter.close();
}
}
Agora o servlet funciona com uma sessão, aumentando o valor de visitCounter
cada vez que a página é visitada. Caso o visitCounter
atributo ainda não tenha sido criado (na primeira visita à página), o getAttribute()
método retorna null, então precisamos verificar se há null. O mesmo vale para os parâmetros de solicitação. Se o usuário não passar o parâmetro username, então seu valor será nulo. Nesse caso, saudamos o usuário como um visitante anônimo. Para passar um parâmetro em uma solicitação GET, uma string de consulta é usada. Por exemplo, poderíamos usar a seguinte URL: http:// localhost:8080/hello? Nome de usuário=Paul. Você pode ler mais sobre solicitações HTTP no artigo anteriornas séries. Nosso aplicativo atualmente não tem muita lógica, mas é um pouco chato recebermos um erro 404 no caminho raiz. Para corrigir isso, criaremos outro servlet e o mapearemos para a página inicial: @WebServlet("/")
. O objetivo deste servlet é redirecionar as solicitações para o caminho "/hello". Existem duas maneiras de fazer isso: usando "encaminhar" ou "redirecionar". Talvez valha a pena entender a diferença entre eles. Um encaminhamento delega o processamento da solicitação para outro servlet no servidor. O cliente não está envolvido. Para fazer isso, adicione o seguinte código ao método doGet() do novo servlet:
getServletContext().getRequestDispatcher("/hello").forward(req, resp);
Nesse código, acessamos o contexto do servlet, obtemos o despachante de solicitação para o servlet relevante e solicitamos que ele processe uma solicitação específica com os argumentos especificados (req, resp). Um redirecionamento retorna ao cliente o endereço que o cliente deve usar para processar sua solicitação. A maioria dos navegadores navega automaticamente para o URL retornado. Para implementar um redirecionamento, você precisa adicionar este código:
resp.sendRedirect(req.getContextPath() + "/hello");
Chamamos o redirect()
método no HttpServletResponse
parâmetro e passamos o endereço que o cliente precisa usar. Aqui está um detalhe importante: os parâmetros HTTP também devem ser adicionados no final do caminho de redirecionamento completo, o que não é muito conveniente. Em nossa situação, é preferível usar forward
, mas às vezes usar redirect
é melhor. Se você entender a diferença em como eles funcionam, não fará a escolha errada. O código para o novo servlet se parece com isto:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// getServletContext().getRequestDispatcher("/hello").forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/hello");
}
}
GO TO FULL VERSION