


Algumas capacidades dos servlets torna esta tecnologia particularmente interessante:
Geração dinâmica de páginas HTML: Os servlets podem ser instalados em servidores web para processar informações transmitidas via HTTP a partir, por exemplo de formulários HTML. As aplicações podem incluir acesso a banco de dados ou comunicação com outros servlets.
Balanceamento de carga entre servidores: Para entender como utilizar servlets para fazer balanceamento de carga, considere a infra estrutura de um provedor de serviços via internet composta de cinco servidores, dos quais, quatro são capazes de executarem as mesmas aplicações. O servidor restante, seria responsável por monitorar a cargas dos demais e receber o acesso inicial de cada cliente às aplicações e em seguida, redirecionar os pedidos de acesso para um dos quatro servidores de aplicação, conforme a ocupação de cada um no momento em que o cliente tenta estabelecer uma conexão. Assim, o cliente passa a trocar informações somente com o servidor que foi alvo do redirecionemento.
Modularização do código: Um servlet pode executar outro servlet, mesmo que remotamente, desta forma é possível executá-los em corrente. Esta característica possibilita modularização dos aplicativos, criando servlets com funções específicas. Suponha que para acessar um conjunto de aplicativos, o cliente deva ser autenticado. Neste caso, uma configuração possível seria de criar um serlvlet responsável apenas pela tarefa de autenticação. Uma vez autenticado, este servlet redirecionaria o cliente para outro servlet, não necessariamente instalado no mesmo servidor, que executaria o aplicativo. A vantagem deste tipo de arquitetura, é que se por alguma razão for necessário modificar o procedimento de autenticação, por exemplo pela mudança do banco de dados de usuários, não será necessário reescrever toda a aplicação, e sim apenas o servlet responsável pela autenticação.
CGIs são programas que podem ser escritos em diversas linguagens, como PERL ou C, e que se comunicam com servidores Web através de uma interface padronizada conhecida como CGI, Commom Gateway Interfacce. Esses aplicativos são chamados genericamente de CGIs.
Cada vez que um CGI é executado, é necessário carregá-lo na memória e iniciar um processo que será extinto com término da execução do aplicativo. Como são processos distintos, existe uma grande dificuldade no compartilhamento de recursos do sistema, por exemplo conexão a banco de dados, e na troca de informações entre os processos executados simultaneamente.
O servlet é carregado uma única vez na memória, e permanece lá até seja necessário modificá-lo. Normalmente é necessário reiniciar o servidor toda vez que um servlet sofre alguma modificação, no entanto, atualmente alguns sistemas que executam servlets são capazes de recarregá-los sem a necessidade da reinicialização do servidor. Como o servlets permanecem carregados na memória, é mais fácil desenvolver aplicações que exijam persistência os entre conexões sucessivas de um mesmo cliente.
Uma vez inicializado, o servlet estará apto a lidar com centenas de acessos simultaneamente disparando para cada acesso um novo thread. Os threads de um mesmo aplicativo, utilizam um espaço de endereçamento de memória comum a todos, isto permite que eles compartilhem dados e recursos do sistema. Ou seja, todos os threads de um servlet podem fazer uso de uma única conexão que foi estabelecida com um banco de dados no momento de inicialização do servlet. Esta conexão permanecerá aberta até que o servlet seja desativado, saia da memória, ou seja ser recarregado.
Como os CGIs são executados em processos distintos para cada acesso do usuário, esta persistência de estado é mais difícil de ser feita, pois ao final do processamento do CGI, seus dados são apagados da memória. Algumas alternativas seriam: utilizar arquivos temporários para armazenar o estado de cada cliente, mapeamento de memória compartilhada entre CGIs. No entanto, isto onera ainda mais a performance pois exige operações explícitas de escrita e leitura em arquivos e acesso direto a memória, o que reduz a portabilidade entre sistemas operacionais, mesmo no caso de CGIs desenvolvidos em linguagens interpretadas.
Servlets são escritos em Java, uma linguagem projetada para ser independente de plataforma. Desta forma, é possível escrever um servlet para um servidor UNIX, que poderá ser instalado em um Window NT, sem a necessidade de rescrevermos o código, ou recompilá-lo.
A orientação a objetos, característica do Java, favorece a modularização dos aplicativos o que os tornam mais escaláveis. Retomando o exemplo acima de autenticação de clientes, imagine um estrutura montada em três camadas. Uma primeira, chamada gateway, executa um servlet responsável por autenticar os usuários e redirecionar os acessos para a segunda camada. Esta composta por servidores que executam servlets que contem a lógica da aplicação propriamente dita. Finalmente a terceira, seria formada por servidores de banco de dados. Considerando que o processo de autenticação e bem mais leve que a aplicação, um único gateway seria capaz de atender a vários servidores de aplicação. Se em um determinado momento for detectado que os servidores de aplicação estão sobrecarregados, bastaria acrescentarmos mais um servidor a segunda camada, e informarmos o do gateway que existe mais um servidor capaz se receber o redirecionamento de acessos de clientes autenticados.
| Servlets | CGI's | |
|---|---|---|
| Independência de plataforma | Os servlets podem rodar em qualquer plataforma sem serem reescritos ou até mesmo compilados novamente. | Os Scripts PERL, por serem interpretados, também possuem esta funcionalidade mas são muito lentos. As aplicações CGI que necessitam de alta performance são escritas em C. |
| Desempenho | Os servlets são carregados apenas uma vez e para cada nova requisição o servlet gera um novo thread. O método init() do servlet, assim como nas applets, ocorre apenas na primeira vez que a classe é carregada. É geralmente no método init() que, por exemplo, estabelecemos uma conexão ao Banco de Dados. Cada uma das threads geradas pode usar a mesma conexão aberta no método init(). Este tipo de tratamento aumenta em muito o tempo de performance do servlet, já que você faz a conexão ao BD apenas uma vez e todos as outras requisições usam esta conexão. | Um novo programa CGI é carregado para cada requisição ao servidor. Isto quer dizer que se você tiver 10 requisições simultâneas, você tem 10 programas iguais na memória. |
| Extensibilidade | Com Java você pode criar aplicações muito mais modulares, tirar todo o proveito da orientação a objetos e utilizar o grande número de APIs disponíveis pela Javasoft e terceiros. | Com CGI's é possível atender a um requisito de extensibilidade também. Porém o overhead gerado para que esta funcionalidade seja implementada, torna sua execução muito lenta. |
Resumo comparativo entre Servlets e CGI's
javax.servlet.javax.servlet.
Pacote javax.servlet
javax.servlet.http. Nesta
figura, as classes/interfaces que estão em amarelo são pertencentes ao
pacote javax.servlet.
Pacote javax.servlet.http
init(),
service() e destroy(). O ciclo de vida de um
servlet inicia com o container chamando o método init(),
passando pelo método service() e termina com o container
chamando o método destroy().init() a partir da instância criada.service()
a partir de sua instância.destroy() a partir
da instância ainda ativa.
Ciclo de vida de um servlet
init( ServletConfig
config). init() para inicializar objetos, abrir conexões com Banco de Dados, abrir uma conexão de
rede, etc..UnavailableException.destroy(). destroy() para fazer a desconexão do banco de dados, fechar uma conexão de rede, fechar arquivos abertos, etc.1. importar os pacotes:
javax.servletejavax.servlet.http:import javax. servlet.*; import javax. servlet. http.*;2. Um Servlet normalmente é uma classe que estende javax. servlet.http.HttpServlet, portanto:
public class MeuServlet extends HttpServlet{ ...}3. Implementar os métodos:
doGet(...) : Para tratar requisições GET; doPost(...) : Para tratar requisições POST; service(...): Para tratar tanto requisições GET como POST
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
...
String nome = request.getParameter(“nome”);
String[] filmes = request.getParameterValues(“filme”);
...
}
getParameter( String str); retorna null ou (“”) ,
dependendo do Servidor web.
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
...
response.setContentType(“text/ html”);
...
}
PrintWriter out = response.getWriter(); out.println(“< html> TESTE</ html>”); out.close();
...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("text/html");
StringBuffer str = new StringBuffer();
str.append("<html>\n");
str.append("<head>\n");
str.append("<title>Página de exemplo 2</title>\n");
str.append("</head>\n");
str.append("<body bgcolor='white'>\n");
str.append("<h1>Exemplo 2</h1>\n");
str.append("<h4>Página formada usando o StringBuffer, no Servlet</h4>");
str.append("</body>\n");
str.append("</html>");
response.getWriter().println(str.toString());
}
...
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ExemploServletOutputStream extends HttpServlet {
private FileInputStream in;
private File file;
public void init(ServletConfig config) throws ServletException {
super.init(config);
try{
file = new File("c:\\bola.gif");
in = new FileInputStream(file);
}catch(Exception e){
throw new UnavailableException ("Nao foi possivel abrir o arquivo");
}
}
public void destroy(){
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("image/gif");
ServletOutputStream out = response.getOutputStream();
for(int i=0; i<file.length(); i++){
out.write(in.read());
}
out.close();
}
}
public class ExemploServlet extends HttpServlet implements SingleThreadModel { ... }

Todos os cookies de um cliente são enviados no cabeçalho HTTP de sua requisição.
... Usuario user = new Usuario(); user. setNome(“ Jose da Silva”); user. setIdade( 35); Cookie c = new Cookie(“ jose”, user)); response. addCookie( c); ...
...
Cookie[] cookies = request. getCookies();
Cookie userCookie;
for( i= 0; i < cookies. length; i++) {
Cookie userCookie = cookie[ i];
if(userCookie. getName(). equals(“ jose")) {
Usuario user = (Usuario) userCookie. getValue();
}
}
...
... Cookie c = new Cookie(“ login”,” jose”); c. setMaxAge( int seg); -Define durante quanto tempo o cookie se manterá ativo. Após o “maxAge”, o cookie é apagado. ...
... HttpSession sessao = request.getSession(); Ou HttpSession sessao = request.getSession(true); ...
sessao.setAttribute(“cesta”, new Cesta());
...
HttpSession sessao = request. getSession();
if(! sessao. isNew()){
Cesta cesta = (Cesta) sesso. getAttribute(“ cesta”);
}
...
... HttpSession sessao = request. getSession(); sessao. invalidate(); ...
sessao. setMaxInactiveInterval( 60* 5); // 5 mins
...
getServletContext(), herdado da super classe HttpServlet;
public void doGet( HttpServletRequest ...){
ServletContext c = getServletContext();
}
...
c.setAttribute(“ BD”, new DBAccess());
ServletContext c = getServletContext(); DBAccess db = (DBAccess) c.getAttribute(“ BD”);
ServletContext c = getServletContext(); c.removeAttribute(“DB”);