Java Servlets e JDBC

Propaganda
Desenvolvimento de aplicações
Web com J2EE
Servlets
Mauro Schramm
Rogério Sorroche
Roteiro

Introdução
– Java 2 Enterprise Edition (J2EE)
– Aplicação Web: estrutura e deployment descriptor

Servlets
– Arquitetura
– Ciclo de vida
– Comunicação com cliente
 Geração de saída
 Recebimento de parâmetros
– Sessões

JSP
–
–
–
–
Introdução
Ciclo ed vida
Elementos
Objetos implícitos
Java 2 Enterprise Edition

J2EE é
– Uma especificação para servidores de aplicação que define padrão de
suporte a componentes e serviços
– Um pacote de APIs e ferramentas para desenvolver componentes que
rodam nesses servidores


A plataforma J2EE tem por objetivo reduzir o custo e a
complexidade de desenvolvimento de aplicações multicamada
Servidores de aplicação compatíveis com J2EE oferecem:
– Suporte à arquitetura de componentes EJB
– Suporte à serviços WEB: servlets e JSP
– Suporte a serviços de middleware implícito e explícito
Java 2 Enterprise Edition
Containers J2EE

Um container é a interface entre componentes e as funções de baixo nível da
plataforma onde roda.
– Antes que um componente EJB ou Web possa ser executado em um container
J2EE ele precisa ser montado em uma aplicação J2EE e implantado no seu
container



O container é responsável por chamar os métodos que controlam o ciclo de
vida dos componentes
O Container também serve de interface para que o componente possa utilizar
serviços de middleware implícito declarado nos seus arquivos de
configuração
A plataforma J2EE oferece três tipos de containers:
– EJB
– Web
– Cliente
Aplicações WEB

Composta de:
–
–
–
–
–

Servlets
Páginas JSP
Classes utilitárias
Documentos estáticos (html, imagens, sons, etc)
Descritores de implantação (deployment descriptors)
Pode ser empacotada em um arquivo WAR (Web
Application Archive)
– Arquivo ZIP com a extensão .war
– Padrão portável entre os vários servidores de aplicação J2EE

A aplicação Web é implantada em um caminho específico
no servidor chamado Contexto
– Ex: http://www.minhaempresa.com.br/contexto
Estrutura de um contexto
Componentes do contexto

Raiz geralmente define o nome do contexto
– No JBoss por default o contexto é o nome do arquivo WAR
 Pode ser alterado através do arquivo jboss-web.xml ou do arquivo
application.xml se o WAR for empacotado em um arquivo EAR
– {contexto}/WEB-INF
 Diretório especial com arquivos de configuração
 Seu conteúdo não pode ser acessado pelos clientes
– {contexto}/WEB-INF/web.xml
 Arquivo de configuração da aplicação
 Define parâmetros iniciais, mapeamentos e outras configurações
– {contexto}/WEB-INF/classes/
 Classes que não estão empacotados em um arquivo JAR
– {contexto}/WEB-INF/lib/
 Arquivos JAR contento classes e Servlets que serão incluídos no
classpath da aplicação
Exemplo da estrutura de diretórios
/index.jsp
/ajuda.html
/imagens/logo.gif
/WEB-INF/web.xml
/WEB-INF/lib/utilitarios.jar
/WEB-INF/classes/MeuServlet.class
/WEB-INF/classes/ServletUtil.class
Deployment Descriptor

Arquivo de configuração que descreve para o
servidor como gerenciar a aplicação Web
 Configura a aplicação de forma declarativa sem
necessidade de re-compilar o código
 Deve ter o nome de web.xml e estar localizado no
diretório WEB-INF/ da aplicação
Servlets


Necessidade de um container para gerenciar seu ciclo de vida
Características da API
– pacotes javax.servlet e javax.servlet.http
– recebe parâmetros (javax.servlet.http.HttpServletRequest) e gera saída
(javax.servlet.http.HttpServletResponse) para um servidor web
– controle de sessões




troca de informações entre um encadeamento de telas
necessidade gerada pelo fato de http não ser um protocolo orientado a conexão
Necessariamente classe Java que estende javax.servlet.http.HttpServlet
Acesso a todas APIs de Java (menos GUI)
– JDBC
– RMI
– CORBA
– Etc
Arquitetura de Servlets
Servidor WEB
Navegador
WEB
http
Container Servlet
Servlet
Servlet
Servlet
JDBC
RMI
CORBA
DB
Servidores
RMI
Servidores
EJB
“Anatomia” de um Servlet
(não é a única!)
import
import
import
import
javax.servlet.*;
javax.servlet.http.*;
java.io.*;
java.util.*;
public class Demo extends HttpServlet {
//subclasse de HttpServlet
public void init(ServletConfig config) throws ServletException { //método sobrescrito
super.init(config);
}
public void service(
//método que trata as requisições (sobrescrito)
HttpServletRequest request, //manipulador para parâmetros, host do cliente, etc
HttpServletResponse response //manipulador para geração da saída
) throws ServletException, IOException {
response.setContentType("text/html");
//define o MIME type
PrintWriter out = response.getWriter(); //abre a saída
out.println("<HTML><TITLE>Hello</TITLE><HEAD></HEAD>");
out.println("<BODY><H2>Hello World!</H2></BODY></HTML>");
out.close();
}
public void destroy() {//método sobrescrito
super.destroy();
}
}
Método service()
container servlet
requisição get
resposta
MeuServlet (extends HttpServlet)
service()
requisição post
resposta
método sobrescrito
Ciclo de vida de um Servlet
init()
service()
destroy()
Ciclo de vida de um Servlet
Métodos doGet() e doPost()

Outra “anatomia” (bastante utilizada) é sobrescrever os métodos doGet() e
doPost() e não sobrescrever service()
– A implementação de service() em HttpServlet chamará doGet() quando o servlet
for chamado pelo método http get ou doPost() quando chamado por http post
– Parâmetro HttpRequest contém indicação do tipo de chamada
container servlet
requisição get
resposta
requisição post
resposta
MeuServlet (extends HttpServlet)
doGet()
service()
doPost()
método sobrescrito
Formulário com chamada pelo método
post...
<html>
<head>
<title>Exemplo http post</title>
</head>
<body>
<form method="POST" action="ExemploTrataParametro">
Parâmetro 1 <input type="text" name="parametro1">
<br>Parâmetro 2 <input type="text" name="parametro2">
<br><input type="submit" value="Submeter" name="Botao1">
</form>
</body>
</html>
...e tratamento por um servlet
import ...
public class ExemploTrataParametro extends HttpServlet {
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String parametro1 = request.getParameter("parametro1");
String parametro2 = request.getParameter("parametro2");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>Exemplo</title></head>");
out.println("<body><h2>Exemplo parâmetros</h2>");
out.println("<br>Método=" + request.getMethod());
out.println("<br>Parametro1=" + parametro1);
out.println("<br>Parametro2=" + parametro2);
out.close();
}
}
Formulário com chamada pelo método get e
tratamento pelo mesmo Servlet
<html>
<head>
<title>Exemplo http get</title>
</head>
<body>
<form method="GET" action="ExemploTrataParametro">
Parâmetro 1 <input type="text" name="parametro1">
<br>Parâmetro 2 <input type="text" name="parametro2">
<br><input type="submit" value="Submeter" name="Botao1">
</form>
</body>
</html>
Parâmetros passados pela
URL
javax.servlet - principais interfaces

ServletContext
– define um conjunto de métodos que um servlet utiliza para comunicar-se
com o container

RequestDispatcher
– define um objeto que recebe requisições de um cliente e as envia para
outro recurso do servidor (servlet, arquivo jsp ou arquivo html)
javax.servlet.http - principais interfaces

HttpServletRequest
– o container servlet implementa esta interface para criar objetos que serão
usados para passar informações do cliente para o método service() de
HttpServlet

HttpServletResponse
– permite ao método service() enviar respostas para os clientes usando http

HttpSession
– utilizado para manter uma sessão entre um cliente http e um servidor http
por um tempo determinado, através de múltiplas conexões e requisição
de páginas
javax.servlet.http - principais classes

HttpServlet
– classe abstrata que deverá ser extendida (e ter seus métodos sobrescritos)
para criar nossos próprios servlets

HttpUtils
– provê uma série de métodos (estáticos) que são úteis na construção de
servlets
Classe HttpServlet




Classe abstrata que deverá ser estendida para criação de servlets
Métodos sobrescritos desta classe serão acionados pelo
container servlet para tratamento de requisições http
Comunicação com o cliente através de parâmetros do tipo
HttpServletRequest (entrada) e HttpServletResponse (saída)
Definição
– public abstract class HttpServlet extends GenericServlet
implements java.io.Serializable
Classe HttpServlet – principais métodos

protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, java.io.IOException
–


recebe as requisições http e os encaminha para um dos métodos doXXX definidos nesta
classe
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, java.io.IOException
– recebe requisições http post encaminhadas pelo método service()
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, java.io.IOException
– recebe requisições http get encaminhadas pelo método service()

public ServletContext getServletContext()
– obtém o objeto de contexto
Interface HttpServletRequest
principais métodos



public java.lang.String getParameter(java.lang.String name)
– retorna o valor do parâmetro como String
public java.util.Enumeration getParameterNames()
– retorna um Enumeration de objetos String contendo os nomes dos parâmetros
public HttpSession getSession(boolean create)
– retorna a sessão associada com o request, ou cria uma nova sessão (caso o parâmetro seja
true)





public void setAttribute(java.lang.String name,
java.lang.Object value)
– cria um atributo no “request” identificado por name e cujo valor é value
public java.lang.Object getAttribute(java.lang.String name)
– obtém um atributo do “request” identificado por name
public java.lang.String getMethod()
– retorna o nome do método http utilizado (“POST”,”GET”,...)
public java.lang.String getRemoteAddr()
– retorna o endereço IP da estação cliente
public java.lang.String getRemoteHost()
– retorna o nome da estação cliente
Interface HttpServletResponse
principais métodos

public void setContentType(java.lang.String type)
– Indica o tipo de resposta enviada ao clinete (MIME type). Exemplo: “text/html”

public java.io.PrintWriter getWriter() throws java.io.IOException
– retorna um objeto PrintWriter que pode ser utilizado para enviar texto para o
cliente

public void sendRedirect(java.lang.String location)
throws java.io.IOException
– indica um redirecionamento para a url especificada no parâmetro

public void sendRedirect(java.lang.String location)
throws java.io.IOException
– utilizado para controle de sessões sem uso de cookies

public java.lang.String encodeURL(java.lang.String url)
– utilizado para controle de sessões sem uso de cookies

public java.lang.String encodeRedirectURL(java.lang.String url)
– utilizado para controle de sessões sem uso de cookies
Exercício
Construir um Servlet que mostre o número de requisições
processadas por ele mesmo. Utilize init() para inicializar o
contador.
Sessões

Manter informações entre diversas requisições de telas, permitindo manter estado da
sessão do cliente
 Pode-se manter atributos (objetos) que formam o estado da sessão do usuário
 Como funciona, já que http não mantém estados entre diversas requisições?
–
Identificador da sessão gravado no cliente



ou com a gravação de um cookie no navegador
ou via parâmetro na url
parâmetro na url é utilizado quando os cookies estiverem desabilitados, controlado
automaticamente pela API
Container Servlet
Navegador
xyz
Sessionid=xyz
objeto HttpSession
servlet
objeto HttpSession
“perfil”
objeto PerfilUsuario
“itens”
objeto Itens
...
...
Criando uma sessão

Através do método getSession() do objeto HttpRequest
...
public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// busca sessão se não houver, não força a criação
HttpSession sessao = request.getSession(false);
if (sessao == null) {
//se não há sessão, redirecionar para servlet de autenticação
response.sendRedirect(
response.encodeRedirectURL("br.furb.dsc.pedido.ExibeLogon"));
return;
}
//pega atributo da sessao
Cliente cliente = (Cliente)sessao.getAttribute(“IdObjetoSessao”);
...
Interface HttpSession
principais métodos

public void setMaxInactiveInterval(int interval)
– especifica o tempo máximo (em segundos) que o container servlet manterá esta
seção se o usuário não fizer novas requisições

public void setAttribute(java.lang.String name,
java.lang.Object value)
– cria um atributo de sessão identificado por name e cujo valor é value

public java.lang.Object getAttribute(java.lang.String name)
–

recupera um atributo de sessão identificado por name
public void invalidate()
– destrói a sessão
Métodos encodeXXX de HttpResponse

Geram automaticamente o identificador da sessão em uma url caso os
cookies estejam desabilitados
– utilzar quando se geram links ou redirecionamentos para outros servlets
(encadeamento)
– se os cookies estiverem habilitados, a url não é alterada
Métodos encodeXXX de HttpResponse

public java.lang.String encodeURL(java.lang.String url)
– Aplicado sobre uma url, adiciona o identificador de sessão (se necessário)
...
String urlAdiciona =
response.encodeURL("br.furb.dsc.pedido.AdicionaItem");

out.println("<form method=post action=" + urlAdiciona + ">");
out.println("<input type=hidden name=cdProduto value=" + cdProduto + ">");
...
public java.lang.String encodeRedirectURL(java.lang.String url)
– Semelhante a encodeURL(), porem utilizado somente no método
HttpResponse.sendRedirect()
...
if (sessao == null) {
//se não há sessão, redirecionar para servlet de autenticação
response.sendRedirect(
response.encodeRedirectURL("br.furb.dsc.pedido.ExibeLogon"));
return;
...
Identificador de sessão na url
exemplo
Identificador de
sessão na url
Exercício

Escreva um servlet que crie uma sessão de usuário, grave um
atributo do tipo String (contendo uma mensagem) na sessão e
exiba na tela um link para um segundo servlet. Este segundo
servlet deverá exibir a mensagem gravada pelo primeiro na
sessão e exibi-la na tela.
Interface SingleThreadModel


Torna o servlet thread-safe
Comportamento default de servlets é atender cada requisição do
usuário com a execução do método service() em uma thread
– A interface SingleThreadModel modifica este comportamento
– As requisições são serializadas e somente uma thread com o método
service() é executada simultaneamente

Utilizada para evitar que se construam rotinas de sincronização
manualmente
– Acesso a recursos compartilhados

Formato
– public class MeuServlet extends HttpServlet
implements SingleThreadModel
Filtros


Interceptam uma requisição ou resposta e podem ser encadeados
Principais tarefas realizadas por um filtro
– Interromper o fluxo de requisição/reposta
– Modificar os dados da requisição ou reposta
– Interagir com recursos externos

Aplicações típicas
– Autenticação, logging e criptografia
– Compressão de dados, transformação XML

Para instalar um filtro é preciso
– Programar o filtro
– Programar as requisições e respostas filtradas
– Especificar a ordem de chamada
Filtros

API consiste das interfaces Filter, FilterChain e FilterConfig
– Para criar um filtro é preciso implementar a interface Filter e seus
métodos: doFilter(Request, Response, FilterChain),
init() e destroy()

Filtros são associados a servlets no web.xml
– A ordem em que aparecem determina a ordem de chamada
– Ao chamar-se um servlet com filtros associados, estes são chamados em
seqüência.

Incluído na especificação servlet 2.3
Filtros – exemplo de implementação
public class FiltroAutenticacao implements Filter {
public FiltroAutenticacao() {}
public void init(FilterConfig filterConfig) { }
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Aplicando filtro de autenticacao");
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
// busca indicador de que o usuario efetuou autenticacao
String autenticado =
(String)req.getSession().getAttribute("autenticado");
// se nao esta autenticado, pede autenticacao
if ( ( autenticado == null ) &&
( req.getRequestURI().indexOf("autenticacao") < 0 ) ) {
// vai para pagina de autenticação
res.sendRedirect("autenticacao.jsp");
} else {
chain.doFilter(request, response); // aplica próximo filtro
}
}
}
Filtros – exemplo de arquivo web.xml
<web-app>
<filter>
<filter-name>FiltroAutenticacao</filter-name>
<filter-class>FiltroAutenticacao</filter-class>
</filter>
<filter-mapping>
<filter-name>FiltroAutenticacao</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
...
web.xml - Elementos de Configuração

Parâmetros iniciais do contexto
 Definição de páginas JSP, Servlets e Filtros
 Mapeamentos para páginas JSP, Servlets e Filtros
 Configuração da Sessão
 Welcome Files
 Páginas de Erro
 Variáveis de Ambiente
 Segurança
 Referências para Recursos e EJBs
Parâmetros Iniciais do Contexto

Definido como
<context-param>
<param-name>nomeCurso</param-name>
<param-value>Curso de J2EE</param-value>
</context-param>

Acessado através do objeto ServletContext
métodos
– getInitParameter()
– getInitParameterNames()
Servlets e Páginas JSP

Definição de um Servlet
<servlet>
<servlet-name>catalogo</servlet-name>
<servlet-class>CatalogoServlet</servlet-class>
<init-param>
<param-name>catalogo</param-name>
<param-value>Produtos</param-value>
</init-param>
</servlet>

Definição de uma página JSP
<servlet>
<servlet-name>index</servlet-name>
<jsp-file>index.jsp</jsp-file>
</servlet>

Os parâmetros iniciais podem ser acessados por
– getInitParameter
ServletConfig
e getInitParameterNames no Servlet ou em
Criando Mapeamentos para Servlets

Maneira de informar ao servidor para encaminhar
uma URL para o Servlet ou página JSP
 Exemplo
– Mapeando todas as solicitações no diretório /clientes
para o Servlet cliente
<servlet-mapping>
<servlet-name>cliente</servlet-name>
<url-pattern>/clientes/*</url-pattern>
</servlet-mapping>
Configurando Filtros

Um filtro pode ser definido usando o elemento filter
<filter>
<filter-name>Filtro Autenticacao</filter-name>
<filter-class>filtros.FiltroAutenticacao</filter-class>
</filter>

Pode ser mapeado para um Servlet
<filter-mapping>
<filter-name> Filtro Autenticacao</filter-name>
<servlet-name>PrincipalServlet</servlet-name>
</filter-mapping>

Ou para um conjunto de Servlets
<filter-mapping>
<filter-name> Filtro Autenticacao</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>

Os filtros serão aplicados na ordem em que estão definidos
Mais Sobre Mapeamentos

Uma string que começa com ‘/’ e termina com ‘/*’ é considerado um
mapeamento de caminho
– Mapemento para o diretório imagens:
<url-pattern>/imagens/*</url-pattern>

Uma string começando com ‘*.’ é usada como mapeamento de extensão
– Mapemento para todos os arquivos .gif:
<url-pattern>*.gif</url-pattern>

Uma string contendo apenas ‘/’ indica o ‘default’ servlet
– Mapeamento para http://host.com/aplicacao/
<url-pattern>/</url-pattern>

Todos outros mapeamentos são para caminhos específicos
Configurando a Sessão




No protocolo HTTP não existe uma terminação explicita de uma
sessão
O mecanismo usado para indicar que um cliente não está mais ativo
é a definição de um período de time-out.
Se não for definido a sessão nunca irá expirar
Exemplo
– A sessão expira se ficar inativa por 6 minutos
<session-config>
<session-timeout>6</session-timeout>
</session-config>
Welcome Files


Permite definir uma lista ordenadas de páginas que são mostradas
caso seja solicitada uma URL que não está mapeada para nenhum
Servlet
Exemplo
– Sempre que for digitado:



http://www.host.com/aplicacao/
http://www.host.com/aplicacao/diretorio1/
http://www.host.com/aplicacao/diretorio2/
– O container irá procurar nestes diretórios uma Welcome File na
ordem em que foram definidas no deployment descriptor
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
Páginas de Erro


Permite ao desenvolvedor customizar a aparência do conteúdo
retornado para o cliente em caso de uma exceção
Pode ser especificado para uma determina Exceção
<error-page>
<exception-type>java.io.IOException</exception-type>
<location>io-exception.html</location>
</error-page>

Ou para um dos códigos de erro definidos pelo protocolo HTTP
<error-page>
<error-code>404</error-code>
<location>notFound.html</location>
</error-page>
Segurança
...
Definição de restrição de acesso
<security-constraint>
<web-resource-collection>
<web-resource-name>Recursos web sistema pedidos</web-resource-name>
<url-pattern>*.do</url-pattern>
Definição de quais páginas/ações
<url-pattern>*.jsp</url-pattern>
restritas
</web-resource-collection>
<auth-constraint>
<role-name>cliente</role-name>
Nome da(s) role(s) com
</auth-constraint>
acesso à área restrita
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
Definição da tela de login
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/login.html</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>cliente</role-name>
</security-role>
...
Definição das roles usadas em
<security-constraint>
Aplicações Web com J2EE
Segurança – associação de usuários com
perfis no JBoss

Inidicação do módulo de login utilizado pela aplicação no arquivo
jboss-web.xml
<jboss-web>
...
<security-domain>java:/jaas/cliente-login</security-domain>
...
</jboss-web>
Nome JNDI do módulo de autenticação
Aplicações Web com J2EE
Segurança – associação de usuários com
perfis no JBoss


Definição dos módulo de autenticação no arquivo conf/login-config.xml
Diversas implementações para obter autenticação de usuários:
org.jboss.security.auth.spi.DatabaseServerLoginModule utiliza cadastro de
usuários/senha em banco de dados relacional
...
Nome do módulo de
<policy>
<!-- curso -->
autenticação
<application-policy name = "cliente-login">
(utilizado como
Nome JNDI para
<authentication>
nome JNDI)
obter conexão JDBC
<login-module
code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
flag = "requisite">
<module-option name = "dsJndiName">java:/DataSourceCurso</module-option>
<module-option name = "principalsQuery">
select ds_senha from cliente where cd_cliente=?
query que retorna
a(s) role(s)
associadas com o
usuário
</module-option>
<module-option name = "rolesQuery">
query para obter a senha
select 'cliente' role, 'Roles' grupo from cliente where cd_cliente = ?
</module-option>
<module-option name = "password-stacking">useFirstPass</module-option>
</login-module>
</authentication>
</application-policy>
...
<policy>
...
Aplicações Web com J2EE
Referências
-HALL, Marty. Core Servlets and JavaServer pages. Upper Saddle River :
Prentice Hall PTR, c2000. xxvii, 575p.
-HUNTER, Jason, CRAWFORD, William. Javas servlet programming. 2.ed.
Beijing : O´Reilly, 2001. xxiii, 753p.
-SESHADRI, Govind, RAJ, Gopalan Suresh. Enterprise Java computing :
applications and architectures. Cambridge : Cambridge University, 1999.
xviii, 353p.
-REESE, George. Database programming with JDBC and Java. 2.ed. Beijing :
O´Reilly, 2000. xvii, 328p.
-http://java.sun.com/
-http://jakarta.apache.org/
http://www.argonavis.com.br
-http://www.inf.furb.br/~jomi/java
Download