Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
DEPARTAMENTO DE INFORMÁTICA
JAVA NA PRÁTICA
Volume II
2002
Java na Prática – Volume II 1
Sumário
Capítulo I - Concorrência ....................................... 3
CRIANDO THREADS EM JAVA ..................................................................................................... 5
Criando threads por meio da interface Runnable ............................................................ 8
A CLASSE THREAD ..................................................................................................................... 9
Hierarquia ............................................................................................................................ 9
Construtores ......................................................................................................................... 9
Métodos .............................................................................................................................. 10
Variáveis públicas .............................................................................................................. 11
CICLO DE VIDA DOS THREADS ................................................................................................. 12
sleep(), yield(), join(), destroy(), stop(), suspend() e resume(). ................ 13
DAEMON THREADS .................................................................................................................. 17
INFLUÊNCIA DO SISTEMA OPERACIONAL NO COMPORTAMENTO DOS THREADS....................... 18
Forma de escalonamento de threads.................................................................................. 19
Relacionamento entre os níveis de prioridades definidas na linguagem Java e os níveis de
prioridades definidas nos Sistemas Operacionais.............................................................. 20
COMPARTILHAMENTO DE MEMÓRIA E SINCRONIZAÇÃO .......................................................... 22
Atomicidade de Instruções e Sincronização do Acesso à Sessões Críticas ........................ 25
Comunicação entre Threads: wait() e notify() ................................................................... 31
Capítulo II - Animação ......................................... 46
Capítulo III - Programação em rede ........................... 50
CONCEITOS SOBRE PROTOCOLOS USADOS NA INTERNET......................................................... 50
TCP..................................................................................................................................... 52
UDP.................................................................................................................................... 52
IDENTIFICAÇÃO DE HOSTS (Número IP)...................................................................... 53
Identificação de Processos (Portas)................................................................................... 54
PROGRAMAÇÃO EM REDE COM JAVA ....................................................................................... 54
Comunicação Básica Entre Aplicações.............................................................................. 55
Comunicação Sem Conexão (UDP) ................................................................................... 60
Comunicação por meio de URL ......................................................................................... 63
Capítulo IV – Computação Distribuída (RMI) ................... 69
CRIANDO NOSSA AGENDA DISTRIBUÍDA ................................................................................... 69
Implementar interface do objeto remoto ............................................................................ 69
Capítulo V - Acesso a Banco de Dados ......................... 71
MODELOS DE ACESSO A SERVIDORES ...................................................................................... 71
TIPOS DE DRIVERS JDBC......................................................................................................... 72
Obtendo os Drivers JDBC.................................................................................................. 74
PREPARANDO UM BANCO DE DADOS ....................................................................................... 74
Configurando o ODBC....................................................................................................... 77
EXEMPLO INICIAL .................................................................................................................... 78
Carregando o Driver.......................................................................................................... 79
Estabelecendo a conexão ................................................................................................... 79
Criando e Executando Comandos ...................................................................................... 81
RECUPERANDO VALORES......................................................................................................... 82
TRANSAÇÕES E NÍVEL DE ISOLAMENTO ................................................................................... 83
Transação........................................................................................................................... 83
Capítulo I - Concorrência
Um sistema operacional é dito concorrente se permite que mais que uma
tarefa seja executada ao mesmo tempo. Na prática a concorrência real ou
paralelismo só é possível se o hardware subjacente possui mais de um
processador. No entanto, mesmo em computadores com apenas um processador
é possível obter um certo tipo de concorrência fazendo com o processador
central execute um pouco de cada tarefa por vez, dando a impressão de que as
tarefas estão sendo executadas simultaneamente.
Memória Processo
A
10100
01001
B
11001 1010001001110
10100
01010 0101010101010
01001
1010 11001 1010000101101
1010100010101
Thread 1
0111 01010
1010
Código 0101011011001
0101010100101
0111 0101010010101 Thread 2
C 0101001000000
1010101010101
10100
01001
11001
10100111001 Área de pilha
01010101010
01010 10101010101 do thread2
1010
Dados 01010101000
11110101010
0111
Área de pilha do thread1
Mesmo que você não crie mais de um thread todo processo Java possui
vários threads: thread para garbage collection, thread para monitoramento de
eventos, thread para carga de imagens, etc.
0 Linha2
0 Linha1
1 Linha2
1 Linha1
2 Linha2
2 Linha1
3 Linha2
3 Linha1
4 Linha2
4 Linha1
FIM! Linha2
FIM! Linha1
Neste caso alguns cuidados devem ser tomados, uma vez que existe o
compartilhamento das variáveis do objeto por dois threads. Os problemas que
podem advir de uma situação como esta serão tratados mais adiante.
A classe Thread
Hierarquia
java.lang.Object
java.lang.Thread
Construtores
Construtor Descrição
Thread(ThreadGroup g, String nome) Cria um novo thread com o nome
especificado dentro do grupo g.
Thread(Runnable ob, String nome) Cria um novo thread para executar
sobre o objeto ob, com o nome
especificado.
Thread(ThreadGroup g, Runnable ob, Cria um novo thread para executar
String nome) sobre o objeto ob, dentro do grupo
g, com o nome especificado.
Thread(String nome) Cria um novo thread com o nome
especificado.
Thread() Cria um novo thread com o nome
default.
Thread(Runnable ob) Cria um novo thread para executar
Métodos
Método Descrição
currentThread() Retorna uma referência para o thread corrente em
execução.
destroy() Destroi o thread sem liberar os recursos.
dumpStack() Imprime a pilha de chamadas do thread corrente.
enumerate(Thread[] v) Copia para o array todos os thread ativos no
grupo do thread.
getName() Obtém o nome do thread.
getPriority() Obtém a prioridade do thread.
getThreadGroup() Retorna o grupo do thread.
resume() Reassume a execução de um thread previamente
suspenso.
run() Se o thread foi construído usando um objeto
Runnable separado então o método do objeto
Runnable é chamado. Caso contrário nada
ocorre.
setName(String name) Muda o nome do thread.
setPriority(int newPriority) Muda a prioridade do thread.
sleep(long millis) Suspende o thread em execução o número de
milisegundos especificados.
sleep(long millis, int Suspende o thread em execução o número de
nanos) milisegundos mais o número de nanosegundos
especificados.
start() Inicia a execução do thread. A máquina virtual
chama o método run() do thread.
stop() Força o encerramento do thread.
suspend() Suspende a execução de um thread.
yield() Faz com que o thread corrente interrompa
permitindo que outro thread seja executado.
Deadlock
Travamento causado pela espera circular de recursos em um conjunto de threads. O
travamento por deadlock mais simples é o abraço mortal onde um thread A espera que um thread
B libere um recurso, enquanto que o thread B só libera o recurso esperado por A se obter um
recurso mantido por A. Desta forma os dois threads são impedidos indefinidamente de
prosseguir.
Método Descrição
notify() Notifica um thread que está esperando sobre
um objeto.
notifyAll() Notifica todos os threads que está esperando
sobre um objeto.
wait() Espera para ser notificado por outro thread.
wait(long timeout, int nanos) Espera para ser notificado por outro thread.
wait(long timeout) Espera para ser notificado por outro thread.
Variáveis públicas
As variáveis públicas da classe Thread definem valores máximo, mínimo
e default para a prioridade de execução dos threads. Java estabelece dez valores
de prioridade. Como essas prioridades são relacionadas com as prioridades do
Variável Descrição
static final int MAX_PRIORITY A prioridade máxima que um thread pode ter.
static final int MIN_PRIORITY A prioridade mínima que um thread pode ter.
static final int NORM_PRIORITY A prioridade default associado a um thread.
Estados Ativos
thread em
Execução
thread thread
novo morto
thread
suspenso
Agora que vimos os estados que podem ser assumidos por um thread em
seu ciclo de vida vamos examinar mais detalhadamente alguns dos métodos
responsáveis pela mudança de estado de um thread.
yield()
Uma chamada ao método yield() faz com que o thread corrente libere
automaticamente a CPU para outro thread de mesma prioridade. Se não houver
nenhum outro thread de mesma prioridade aguardando, então o thread corrente
mantém a posse da CPU. O exemplo IX.7 altera o exemplo IX.1 de modo a
permitir que outros threads de mesma prioridade sejam executados a cada volta
do loop.
join()
Daemon Threads
Daemon threads são threads que rodam em background com a função de
prover algum serviço mas não fazem parte do propósito principal do programa.
Quando só existem threads do tipo daemon o programa é encerrado. Um
exemplo de daemon é o thread para coleta de lixo.
Um thread é definido como daemon por meio do método de instância
setDaemon(). Para verificar se um thread é um daemon é usado o método de
instância isDaemon(). O exemplo IX.9 mostra o como usar esses métodos.
import java.io.*;
class ThreadDaemon extends Thread
{
public ThreadDaemon()
{
setDaemon(true);
start();
}
public void run()
{
for(;;) yield();
}
}
0 Linha2
1 Linha2
2 Linha2
3 Linha2
4 Linha2
FIM! Linha2
0 Linha1
1 Linha1
2 Linha1
3 Linha1
4 Linha1
FIM! Linha1
}
public static void main(String args[])
{
258
259
Serie iniciada por573
574
575
576
577
578
579
580
581
582
Serie iniciada por80
81
82
Figura IX.4 – Saída do exemplo IX.8.
class Compartilhada
{
private int vetInt[];
public Compartilhada() {vetInt=new int[10];}
public void setVal()
{
for (;;)
{
vetInt[0] = (int)(Math.random() * 1000);
for (int i=1;i<10;i++) vetInt[i]= vetInt[0]+i;
}
}
public int getVal(int i) {return vetInt [i];}
}
}
public static void main(String args[])
{
Compartilhada obj = new Compartilhada();
CalcDez2 t1 = new CalcDez2(obj,1);
CalcDez2 t2 = new CalcDez2(obj,2);
t1.start();
t2.start();
}
}
Monitor de x Monitor de x
passe !
Objeto x Objeto x
thread t1 !
thread t2
Monitor de x Monitor de x
!
Objeto x Objeto x
Nos resta saber como solicitar o passe ao monitor. Isto é feito por meio
da palavra chave synchronized. Existem duas formas de se usar a palavra
chave synchronized: na declaração de métodos e no início de blocos. O
exemplo IX.10 mostra duas versões da classe FilaCirc que implementa uma
fila circular de valores inteiros: uma com métodos synchronized e outra
com blocos synchronized. Um objeto desta classe pode ser compartilhado
por dois ou mais threads para implementar o exemplo clássico de concorrência
do tipo produtor/consumidor.
Exemplo IX.10 – Duas versões de uma classe que implementa uma fila circular
de inteiros.
inicio = (++inicio)%TAM;
inicio = (inicio+1)%TAM;
a) b)
class X class Y
c)
class Z
{
X ob;
...
public int mc()
{
...
synchronized (ob)
{
// Notifica todos os threads que esperam na fila
// do monitor de ob
ob.notifyAll();
...
}
...
}
class FilaCirc
{
private final int TAM = 10;
private int vetInt[];
private int inicio, total;
public FilaCirc()
{
vetInt=new int[TAM];
inicio=0;
total =0;
}
public synchronized void addElement(int v) throws Exception
{
while (total == TAM) wait();
vetInt[(inicio+total)%TAM] = v;
total++;
notify();
}
public synchronized int getElement() throws Exception
{
while (total == 0 ) wait();
int temp = vetInt[inicio];
inicio = (++inicio)%TAM;
total--;
notify();
return temp;
}
}
Exemplo IX.13 – Classe que implementa uma fila circular de inteiros com
notificação.
Método: addElement()
condição: total == TAM
thread 3
thread 2
Método: addElement()
condição: total < TAM
thread 1
Método: getElement()
Tempo
Executando Esperando CPU Esperando notificação
Porém, existem alguns casos mais complexos onde podem existir vários
threads aguardando em um mesmo monitor mas esperando por evento diferentes.
Neste caso podemos usar o notifyAll() para notificar todos os threads que
esperam em um único monitor que um evento ocorreu. Cada thread, a medida
que fosse escalado, testaria se ocorreu condição para a execução e em caso
positivo prosseguiria na execução e em caso contrário voltaria a aguardar no
monitor.
O exemplo IX.14 mostra o código de um gerenciador de mensagens. Ele
é responsável por receber mensagens destinadas à vários threads. As mensagens
import java.util.*;
class GerenteMen {
private Hashtable tamMen;
Thread.currentThread().getName();
Thread.currentThread().getThreadGroup();
obtém uma referência para o grupo de threads ao qual pertence o thread corrente.
Na linha 31 é declarada uma variável que irá referenciar um vetor contendo
referências a todos os threads ativos do grupo. Entre as linhas 32 e 44 é
executado um laço com 100 iterações que produz e armazena as mensagens. Na
linha 34 é realizado um teste para a verificação da necessidade de criar o vetor
que irá conter as referências para os threads ativos. Ele deve ser criado a
primeira vez e toda vez que a capacidade do vetor for diferente do número de
threads ativos do grupo. O tamanho do vetor é determinado pelo método de
instância activeCount() da classe ThreadGroup. A linha 36 contém o
código
tg.enumerate(tl);
int n = (int)(Math.random()*1000)%tl.length;
da linha 37 calcula um número que será usado para acessar o thread dentro do
vetor de referências. O teste da linha 38 impede que seja enviada uma mensagem
para o próprio gerador. Essas mensagens são descartadas. As linhas 40 a 42
tratam da impressão e envio da mensagem construída. Já fora da iteração, as
linhas 45 a 49 tratam da do envio da mensagem “fim” para todos os threads
receptores, o que fará com que encerrem sua execução.
...
g>Mensagem enviada para r_dois:mensagem 88
r_um>Mensagem recebida:mensagem 87
g>Mensagem enviada para r_dois:mensagem 90
r_dois>Mensagem recebida:mensagem 88
g>Mensagem enviada para r_um:mensagem 91
r_dois>Mensagem recebida:mensagem 90
g>Mensagem enviada para r_um:mensagem 93
r_um>Mensagem recebida:mensagem 91
g>Mensagem enviada para r_um:mensagem 95
r_um>Mensagem recebida:mensagem 93
g>Mensagem enviada para r_um:mensagem 96
r_um>Mensagem recebida:mensagem 95
g>Mensagem enviada para r_um:mensagem 97
r_um>Mensagem recebida:mensagem 96
g>Mensagem enviada para r_dois:mensagem 99
r_um>Mensagem recebida:mensagem 97
r_dois>Mensagem recebida:mensagem 99
Pressione qualquer tecla para continuar . . .
import java.util.*;
class GerenteMen {
private Hashtable tamMen;
Operação Descrição
inicializar Um valor inteiro maior ou igual a zero é atribuído ao semáforo.
P Se o semáforo é maior que zero, o semáforo é decrementado. Caso
contrário, o thread é suspenso até que o semáforo contenha um
valor maior que zero.
V Incrementa o semáforo e acorda os threads que estiverem
bloqueados na fila de espera do semáforo.
Produtor Consumidor
s=1; n=0;
início loop início loop
Produz mensagem P(n) // Verifica se existe mensagens
P(s) // Verifica se pode entrar na região P(s) // Verifica se pode entrar na região
// crítica //crítica
Coloca mensagem no buffer Retira mensagem
V(n) // incrementa no, de mensagens V(s) // sai da região crítica
V(s) // sai da região crítica Consome Mensagem
fim loop fim loop
import java.util.Vector;
Capítulo II - Animação
Animação é exibir uma figura que muda com o tempo. No momento o
suporte a animação da API central do Java é limitado. Espera-se para o final de
1997 uma API que dê suporte avançado para animação. A animação pode ser
controlado por um thread que é executado em um certo intervalo pré-definido.
Eliminar o “flicker”
Default
Mudança
Eliminando conflitos
Copiando a figura
Double-buffer
Ticker-Tape
// Move Right
nXPos -= 10;
if (nXPos < -nMessageWidth)
nXPos = nAppletWidth - 10;
}
public void run()
{
int ndx = 0;
Thread.currentThread().setPriority
(Thread.MIN_PRIORITY);
MIME
Camada de rede IP
Dados
Aplicação
TCP
O protocolo TCP é um protocolo orientado a conexão que provê um
fluxo confiável de dados entre dois computadores. Por protocolo orientado a
conexão queremos dizer que é estabelecido um canal de comunicação ponto-a-
ponto onde os dados podem trafegar em ambas as direções. O TCP garante que
os dados enviados em uma ponta cheguem ao destino, na mesma ordem que
foram enviados. Caso contrário, um erro é reportado. Protocolos como HTTP,
FTP e TELNET exigem um canal de comunicação confiável e a ordem de
recebimento dos dados é fundamental para o sucesso dessas aplicações.
UDP
No entanto, nem todas as aplicações necessitam destas características do
protocolo TCP e o processamento adicional exigido para garantir a
confiabilidade e a ordenação dos dados podem inviabilizá-las. Para esses casos
existe o protocolo de transporte UDP. UDP é um protocolo para envio de
pacotes independentes de dados, chamados de datagramas, de um computador a
outro, sem garantias sobre a chegada dos pacotes. O protocolo UDP não é
orientado a conexão.
Protocolo Porta
HTTP 80
echo 7
FTP 20,21
SMTP 25
Finger 79
Daytime 13
pop3 110
Uma vez associado a uma porta o serviço pode ser acessado por uma
aplicação cliente, bastando para isso que ela indique o nome do Host e o número
da porta ao se comunicar.
Classe Descrição
Socket Provê um socket cliente para comunicação orientada à
conexão via protocolo TCP.
ServerSocket Provê um socket servidor para comunicação orientada à
conexão via protocolo TCP.
DatagramSocket Provê um socket UDP para comunicação não orientada
à conexão.
DatagramPacket Representa um datagrama que pode ser enviado usando
DatagramSocket.
InetAddress Representa os dados de um Host (Nome e endereço IP)
Para comunicar via protocolo TCP é preciso que a aplicação cliente crie
um objeto Socket. É preciso passar o nome ou número IP do Host e o número
da porta onde o servidor está esperando as solicitações de serviço. A Classe
Socket possui os métodos getInputStream() e
import java.io.*;
import java.net.*;
try {
socket = new Socket(args[0], 13);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
}catch (UnknownHostException e)
{System.err.println("Não achou o host:"+args[0]);
System.exit(1);}
catch (IOException e)
{System.err.println("Erro de I/O."+e.getMessage());
System.exit(1);}
in.close();
socket.close();
}
}
import java.util.*;
import java.io.*;
import java.net.*;
out.close();
socket.close();
}
}
import java.util.*;
import java.net.*;
import java.io.*;
while(true)
{
try
{
Socket socket = ssocket.accept();
(new serversec(socket)).start();
}
catch(Exception e) {System.err.println(e);}
}
}
}
import java.io.*;
import java.net.*;
import java.io.*;
import java.net.*;
byte [] buff;
for (;;)
{
Thread.sleep(1000);
String s = (new Date()).toString();
buff = s.getBytes();
dp = new DatagramPacket(buff, buff.length, addr, 5013);
ds.send(dp);
}
}
}
A parte do protocolo define o protocolo que deve ser usado para acessar
o recurso. Os protocolos mais comuns são FTP, HTTP e file, este último
indicando que o recurso se encontra no sistema de arquivos local. O protocolo é
seguido do caractere “:”.
http://java.sun.com:80/doc/tutorial.html
http://infax.com.br."claudio"."1234"/base/vendas
Classe Descrição
URL Representa um URL
URLConnection Classe abstrata que representa uma conexão entre uma
aplicação e um URL. Instâncias desta classe podem ser
usadas para ler e escrever no recurso referenciado pela
URL.
URLEncoder Usada para lidar com o formato MIME.
Isto tem o mesmo efeito que gerar uma instância da classe URL com
primeiro construtor, passando como parâmetro o endereço:
http://www.dpi.ufv.br/professores.html
import java.net.*;
import java.io.*;
String linha;
in.close();
}
}
2
Common-Gateway Interface (CGI) é um mecanismo para gerar páginas Web dinamicamente.
Os dados são obtidos de fórmulários HTML e submetidos a um programa binário no servidor
#!/opt/internet/bin/perl
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",
hex($1))/eg;
# Stop people from using subshells to execute commands
$value =~ s/~!/ ~!/g;
$FORM{$name} = $value;
}
que gera a resposta na forma de uma página Web. O programa pode ser escrito em uma
variadade delinguagens, como Perl e C.
out.println("string=" + string);
import java.io.*;
import java.net.*;
if (args.length != 1)
{
System.err.println("Uso: java Inverte string");
System.exit(1);
}
in.close();
}
}
Capítulo IV – Computaç ã o
Distribuída (RMI)
A RMI (Invocação de métodos remotos) é uma tecnologia que coloca a
programação com rede em um nível mais alto. RMI torna possível que objetos
distribuídos em uma rede se comuniquem de forma transparente para o
programador utilizando chamadas de procedimentos remotos.
O principal objetivo da tecnologia RMI é permitir que programadores
desenvolvam programas distribuídos utilizando a mesma sintaxe e semântica de
programas Java convencionais. Antes da introdução da RMI no mundo Java, no
JDK 1.1, para fazer com que dois objetos em máquinas diferentes se
comunicassem o programador deveria definir um protocolo de comunicação e
escrever código utilizando socket para implementar este protocolo. Com RMI a
maior parte do trabalho quem realiza é a máquina virtual Java.
Existem outras tecnologias, como CORBA (Common Object Request
Brocker Architecture), que também tem como objetivo fazer com que objetos
distribuídos em uma rede se comuniquem. Java também tem suporte a CORBA,
mas para projetos em um ambiente Java puro, a RMI é consideravelmente mais
simples que a CORBA.
Aplicação
Java
DBMS
Aplicação Java
ou Applet
Aplicação Servidora
Java
JDBC
DBMS
SGBD1
2. Driver Java parcial e Api Nativa – neste caso as chamadas JDBC são
convertidas para as chamadas às APIs nativas do SGBD. Como o driver
possui uma parte em código binário é necessário instalar algum código na
máquina cliente, como é feito nos drivers do tipo 1.
Protocolo do SGBD
Cliente JDBC Java & SGBD
Java Código Binário
3. Driver puro Java e protocolo de rede – neste caso as chamadas JDBC são
convertidas para um protocolo de rede independente do SGBD que é depois
traduzido para as chamadas às APIs nativas do SGBD por um servidor. Esta
é uma arquitetura em três camadas, onde o servidor middleware é capaz de
conectar seus clientes Java puros com vários SGBDs. Esta solução permite o
desenvolvimento de clientes 100% Java, tendo como consequência a não
necessidade de instalação de qualquer código na máquina cliente.
4. Driver Java Puro e protocolo nativo - neste caso as chamadas JDBC são
convertidas para as chamadas às APIs nativas do SGBD pelo driver, que foi
escrito totalmente em Java.
Protocolo do SGBD
Cliente JDBC Java SGBD
Java (100% Java)
alunos
matricula nome
1 Railer Costa Freire
2 Alexandre Altoé
livros
codlivro titulo volume
1 Curso Pratico de Java 1
2 Curso Pratico de Java 2
3 Introdução a Compiladores 1
4 Fundamentos de Banco de Dados 1
5 Redes de Computadores 1
6 Redes de Computadores Fácil 2
7 Lógica matemática 1
8 Engenharia de Software para Leigos 1
9 Aprenda Computação Gráfica em duas 1
10 Aprenda Inteligência Artificial em 5 1
emprestimos
codlivr matricu data_empresti data_devoluc
1 1 01/01/99 10/01/99
7 3 03/01/99 13/01/99
9 6 12/01/99 22/01/99
1 3 20/01/99 30/01/99
4 2 03/02/99 13/02/99
10 2 12/02/99 22/02/99
Alunos livros
matricula codlivro
nome titulo
volume
emprestimos
data_emprestimo
data_devolução
Configurando o ODBC
Como utilizamos nos exemplos a ponte JDBC-ODBC é necessário
configurar o ODBC para acessar a base de dados acima. Na plataforma
Windows 98 isso é feito da seguinte forma:
Exemplo Inicial
O pacote java.sql fornece as classes e interfaces necessárias para a
conexão com uma base de dados e a posterior manipulação dos dados. As etapas
para se criar uma aplicação cliente de um SGBD em Java são as seguintes:
Para comentar cada uma destas etapas utilizaremos o exemplo XII.1 que
mostra o código de uma aplicação que lista no dispositivo de saída padrão o
nome de todos os alunos.
import java.sql.*;
import java.net.URL;
class jdbc
{
public static void main(String a[])
Carregando o Driver
A primeira etapa é carregar o driver JDBC. Para isso é usado o método
estático forName() da classe Class. Em caso de erro este método lança a
exceção ClassNotFoundException. O método cria uma instância do
driver e o registra junto ao DriverManager. No exemplo XIII.1 é carregado o
driver JDBC-ODBC que vem junto com o SDK.
Estabelecendo a conexão
A segunda etapa é realizada por meio do método estático
getConnection() da classe DriverManager. Este método, na sua forma mais
simples, recebe como parâmetro um URL que faz referência a base de dados e
retorna um objeto da classe Connection, que representa a conexão com a base de
dados. Já discutimos sobre URLs no capítulo XI. No entanto, existem algumas
particularidades no que refere a URLs que fazem referência à Banco de Dados.
O formato padrão deste tipo de URL é o seguinte:
jdbc:<subprotocolo>:<identificador>
onde:
jdbc:odbc:<fonte de dados>[;<atributo>=<valor>]*
getConnection("jdbc:odbc:contas",”ana”,”sght”);
URL Descrição
jdbc:odbc:biblioteca Referencia fonte de dados biblioteca via
ponte JDBC-ODBC.
jdbc:odbc:bd1;CacheSize=20 Referencia fonte de dados bd1 via ponte
JDBC-ODBC. É definido o tamanho do
cache.
jdbc:odbc:contas;UID=ana;PWD=sght Referencia fonte de dados contas via
ponte JDBC-ODBC. É passado também o
nome do usuário e a senha.
jdbc:oracle:thin:@sap.dpi.ufv.br:1521:agenda Referencia fonte de dados agenda no host
remoto sap.dpi.ufv.br via subprotocolo
oracle. É passado também o número da
porta usada no acesso.
Recuperando Valores
O objeto ResultSet possui os métodos necessários para recuperar os
valores de cada coluna da tabela, bastando passar o nome da coluna como
parâmetro. No exemplo XIII.1 é utilizado método getString() para
recuperar o valor da coluna “nome”. Os métodos para recuperação possuem o
formato geral getXXX(), onde XXX é o nome de um tipo. A tabela XIII.2
mostra qual o método mais indicado para cada tipo SQL.
T S I B R F D D N B C V L B V L D T T
I M N I E L O E U I H A O I A O A I I
N A T G A O U C M T A R N N R N T M M
Y L E I L A B I E R C G A B G E E E
I L G N T L M R H V R I V S
N I E T E A I A A Y N A T
T N R L C R R A R A
T C R B M
H Y I P
A N
R A
R
Y
getByte X x x x x x x x x x x x x
getShort x X x x x x x x x x x x x
getInt x x X x x x x x x x x x x
getLong x x x X x x x x x x x x x
getFloat x x x x X x x x x x x x x
getDouble x x x x x X X x x x x x x
getBigDecimal x x x x x x x X X x x x x
getBoolean x x x x x x x x x X x x x
getString x x x x x x x x x x X X x x x x x x x
getBytes X X x
getDate x x x X x
getTime x x x X x
getTimestamp x x x x X
getAsciiStream x x X x x x
getUnicodeStre x x X x x x
am
rs.getString(1);
con.setAutoCommit(false);
con.commit();
con.setAutoCommit(false);
try
{
Statement stmt = con.createStatement();
stmt.executeUpdate(“UPDATE ...” );
stmt.executeUpdate(“UPDATE ...” );
con.commit();
stmt.close();
}
catch(Exception e){con.rollback();}
finally
{
try{ con.setAutoCommit(true);}
catch(SQLException sqle)
{System.out.prinln(sql.getMessage());}
}
NumCC Saldo
10189-9 200,00
20645-7 300,00
Transação 1 Transação 2
leitura do saldo 10189
Escrita do Saldo-50,00
leitura do saldo 10189
leitura do saldo 20645
(falha na transação,
realizado rollback) Escrita do Saldo+70,00
Como a transação 1 falhou o valor lido pela transação 2 é um valor que não
foi tornado permanente na tabela. Isto faz com que a transação 2 opere sobre
um resultado desfeito. A tabela resultante, mostrada abaixo estará em um
estado inconsistente.
NumCC Saldo
10189-9 220,00
20645-7 300,00
DatabaseMetaData meta=con.getMetaData();
if(meta.supportsTransactionIsolationLevel(
con.TRANSACTION_READ_COMMITTED)) {
con.setTransactionIsolation(
con.TRANSACTION_READ_COMMITTED);
}
else return;
Constante
TRANSACTION_NONE
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
Prepared Statements
Cada vez que se executa um comando SQL passado por meio de uma
String. Este String deve ser analisado pelo processador de SQL do SGBD que
irá, no caso da String estar sintaticamente correta, gerar um código binário que
será executado para atender à solicitação. Todo esse processo é caro e sua
execução repetidas vezes terá um impacto significativo sobre o desempenho da
aplicação e do SGBD como um todo.
Existem duas abordagens para tentar solucionar esse problema:
Comandos preparados (prepared statements) e procedimentos armazenados
(stored procedures). Discutiremos primeiramente os prepared statements.
Prepared Statement é indicado nos casos onde um comando será
executado várias vezes em uma aplicação. Neste caso é melhor compilar o
comando uma única vez e toda vez que for necessário executá-lo basta enviar o
pstmt.clearParameters();
pstmt.setInt(1,8);
pstmt.setString(2,”Clara Maria”);
pstmt.executeUpdate();
•Reuso de código – o código precisa ser escrito apenas uma vez e usado
em várias aplicações, comunicando com várias linguagens.
•Independencia entre a aplicação e o esquema do BD – se o esquema
mudar, provavelmente apenas os procedimentos armazenados.
•Desempenho – os procedimentos são previamente compilados,
eliminando esta etapa.
•Segurança – as aplicações possuem privilégio apenas para execução de
procedimentos armazenados, evitando assim acessos não autorizados.
CallableStatement cstmt =
con.prepareCall("{ CALL sp_obtem_nome(?,?)}");
cstmt.registerOutParameter(2, Types.VARCHAR);
cstmt.setInt(1, 3);
cstmt.execute();
System.out.prinln(“O nome do aluno numero 3 :”
+cstmt.getString(2);
import java.io.*;
// Construtor
public pessoa(String n, String t) {Nome = n; Tel = t;}
agenda
import java.util.*;
import java.io.*;
import java.sql.*;
import java.net.URL;
// Construtor
public agenda()throws Exception
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:agenda");
}
/**
CloseAgenda
*/
public void CloseAgenda()
{
if (con != null) try{con.close();}catch(Exception e){};
}
/**
inserir
try
{
Statement stmt = con.createStatement();
stmt.executeUpdate("INSERT INTO pessoas(nome,telefone)
"+
"values('"+p.getNome()+"','"+p.getTel()+"')");
stmt.close();
}catch(Exception e) {System.err.println(e);}
}
/**
Consultar
*/
/**
listar
*/
public Enumeration getLista()
{
if (con == null) return null;
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery
("SELECT Nome, Telefone FROM pessoas");
while(rs.next())
pessoas.addElement(new
pessoa(rs.getString("Nome"),
rs.getString("Telefone")));
stmt.close();
} catch(Exception e) {System.out.println(e.getMessage());
e.printStackTrace();}
return pessoas.elements();
}
}
Servidor
import java.util.*;
import java.net.*;
import java.io.*;
/**
CLASS server
*/
class server
{
public static void main(String args[])
{
String oHost="localhost";
ServerSocket ssocket=null;
serversec oServersec;
int pt = 4444;
agenda ag;
try
{
ssocket = new ServerSocket(pt);
pt = ssocket.getLocalPort();
oHost =
ssocket.getInetAddress().getHostName().trim();
}
catch(Exception e) {System.err.println(e);
System.exit(1);}
while(true)
{
try
{
Socket clisocket = ssocket.accept();
oServersec = new serversec(ag,clisocket);
oServersec.start();
} catch(Exception e) {System.err.println(e);}
}
}
}
/**
CLASS serversec
*/
class serversec extends Thread
{
Socket oSocket;
BufferedWriter soutput;
OutputStreamWriter(oSocket.getOutputStream()));
cinput = new BufferedReader(new
InputStreamReader(oSocket.getInputStream()));
soutput.write(p.getNome()+"\n"+p.getTel()+"\n");
}
soutput.write("#\n");
break;
}
soutput.flush();
Thread.yield();
soutput.close();
oSocket.close();
}
catch(Exception e) {System.err.println(e);}
}
}
Socket(InetAddress.getByName(getCodeBase().getHost()),port);
soutput = new BufferedWriter (new
OutputStreamWriter(clisoc.getOutputStream()));
cinput = new BufferedReader(new
InputStreamReader(clisoc.getInputStream()));
soutput.write(mensagem+"\n");
soutput.flush();
Servlets
Servlets são classes Java que são instanciadas e executadas em
associação com servidores Web, atendendo requisições realizadas por meio do
protocolo HTTP. Ao serem acionados, os objetos Servlets podem enviar a
resposta na forma de uma página HTML ou qualquer outro conteúdo MIME. Na
verdade os Servlets podem trabalhar com vários tipos de servidores e não só
servidores Web, uma vez que a API dos Servlets não assume nada a respeito do
ambiente do servidor, sendo independentes de protocolos e plataformas. Em
outras palavras Servlets é uma API para construção de componentes do lado
servidor com o objetivo de fornecer um padrão para comunicação entre clientes
e servidores. Os Servlets são tipicamente usados no desenvolvimento de sites
dinâmicos. Sites dinâmicos são sites onde algumas de suas páginas são
construídas no momento do atendimento de uma requisição HTTP. Assim é
possível criar páginas com conteúdo variável, de acordo com o usuário, tempo,
ou informações armazenadas em um banco de dados.
Requisições
Container
Servidor
Web Instâncias de Servlets
Respostas
Applets X Servlets
Apesar de ser uma solução robusta existem problemas no uso de Applets para
validação de dados e envio para o servidor. O programador precisa contar com o
fato do usuário possuir um navegador com suporte a Java e na versão
apropriada. Você não pode contar com isso na Internet, principalmente se você
deseja estender a um grande número de usuário o acesso às suas páginas. Em se
tratando de Servlets, no lado do cliente pode existir apenas páginas HTML,
evitando restrições de acesso às páginas. Em resumo, o uso de Applets não é
recomendado para ambientes com múltiplos navegadores ou quando a semântica
da aplicação possa ser expressa por componentes HTML.
A API Servlet
A API Servlet é composta por um conjunto de interfaces e Classes. O
componente mais básico da API é interface Servlet. Ela define o
comportamento básico de um Servlet. A figura XX.XX mostra a interface
Servlet.
Servlet
GenericServlet
HttpServlet
HttpServlet
Todos esses métodos são invocados pelo servidor por meio do método
service(). O método doGet() trata as requisições GET. Este tipo de
requisição pode ser enviada várias vezes, permitindo que seja colocada em um
bookmark. O método doPost() trata as requisições POST que permitem que o
cliente envie dados de tamanho ilimitado para o servidor Web uma única vez,
sendo útil para enviar informações tais como o número do cartão de crédito. O
método doPut() trata as requisições PUT. Este tipo de requisição permite que
o cliente envie um arquivo para o servidor à semelhança de como é feito via
FTP. O método doPut() trata as requisições DELETE, permitindo que o
cliente remova um documento ou uma página do servidor. O método
service(), que recebe todas as requisições, em geral não é sobrescrito, sendo
sua tarefa direcionar a requisição para o método adequado.
Exemplo de Servlet
Para entendermos o que é um Servlet nada melhor que um exemplo
simples. O exemplo XV.XX gera uma página HTML em resposta a uma
requisição GET. A página HTML gerada contém simplesmente a frase Ola
mundo!!!. Este é um Servlet bem simples que ilustra as funcionalidades básicas
da classe.
import javax.servlet.*;
import javax.servlet.http.*;
Compilando o Servlet
A API Servlet ainda não foi incorporado ao SDK, portanto, para compilar
um Servlet é preciso adicionar a API Servlet ao pacote SDK. Existem várias
formas de se fazer isso. A Sun fornece a especificação da API e diversos
Instalando o Tomcat
Assim como para se executar um Applet era preciso de um navegador
Web com Java habilitado no caso de Servlets é preciso de servidor Web que
execute Java ou que passe as requisições feitas a Servlets para programas que
executem os Servlets. O Tomcat é tanto a implementação da API Servlet como a
implementação de um container, que pode trabalhar em associação com um
servidor Web como o Apache ou o IIS, ou pode também trabalhar isoladamente,
desempenhando também o papel de um servidor Web. Nos exemplos aqui
mostrados usaremos o Tomcat isoladamente. Em um ambiente de produção esta
configuração não é a mais adequada, uma vez que os servidores Web possuem
um melhor desempenho no despacho de páginas estáticas. As instruções para
configurar o Tomcat para trabalhar em conjunto com um servidor Web podem
ser encontradas junto às instruções gerais do programa. As figuras XV.XX
ilustram essas duas situações.
Servidor Web
Internet
Servlet habilitado
Servlet Container
C:\ jakarta-tomcat-3.2.3
|
|______bin
|______conf
|______doc
|______lib
|______logs
|______src
|______webapps
set JAVA_HOME=C:\jdk1.3
set TOMCAT_HOME=C:\tomcat
C:\tomcat\bin\startup.bat
c:\tomcat\bin\shutdown.bat
http://127.0.0.1:8080/index.html
A número porta default para recebimento das requisições HTTP pode ser
alterada por meio da edição do arquivo server.xml do diretório conf como
mostrado abaixo:
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler"
value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
<Parameter name="port" value="Número da porta"/>
</Connector>
CLASSPATH=${CLASSPATH}:${TOMCAT_HOME}/lib/servlet.jar
webapps
|_____ Nome aplicação
|_____ Web-inf
|_____classes
Diretório de Aplicações
Na verdade é possível definir outro diretório para colocar as aplicações do Tomcat. Para
indicar outro diretório é preciso editar o arquivo server.xml e indicar o diretório por meio da
diretiva home do tag ContextManager.
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
</web-app>
Executando o Servlet
Invocando diretamente pelo Navegador
Podemos executar um Servlet diretamente digitando a URL do Servlet no
navegador. A URL em geral possui o seguinte formato:
http://localhost:8080/teste/servlet/Ola
<servlet>
<servlet-name>
Ola
</servlet-name>
<servlet-class>
Ola
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
Ola
</servlet-name>
<url-pattern>
/Ola
</url-pattern>
</servlet-mapping>
Neste caso o Servlet Ola será solicitado quando o link associado ao texto
“Servlet Ola” for acionado.
Concorrência
Uma vez carregado o Servlet não é mais descarregado, a não ser que o
servidor Web tenha sua execução interrompida. De modo geral, cada requisição
que deve ser direcionada a determinada instância de Servlet é tratada por um
thread sobre a instância de Servlet. Isto significa que se existirem duas
requisições simultâneas que devem ser direcionadas para um mesmo objeto o
container criará dois threads sobre o mesmo objeto Servlet para tratar as
requisições. A figura XX.XX ilustra esta situação.
usuário
thread1
1 Servlet1
usuário thread2
2
thread1 Servlet2
usuário
3
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = req.getParameter(name);
if (value != null) v.add(value);
}
res.setContentType("text/html");
java.io.PrintWriter out = res.getWriter();
out.println("<html>");
out.println("<head><title>Servlet</title></head>");
out.println("<body>");
out.println("<h1> A soma e'");
int soma =0;
for(int i =0; i< v.size() ; i++) {
soma += Integer.parseInt((String)v.get(i));
}
out.println(soma);
out.println("<h1>");
out.println("</body>");
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
Metodo: GET
Request URI: /servlet/RequestInfo
Protocolo: HTTP/1.0
PathInfo: null
Endereco remoto: 127.0.0.1
Connection = Keep-Alive
User-Agent = Mozilla/4.7 [en] (Win95; I)
Pragma = no-cache
Host = localhost:8080
Accept = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding = gzip
Accept-Language = en
Accept-Charset = iso-8859-1,*,utf-8
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
out.println("<h3>Trata formulario</h3>");
String nome = req.getParameter("nome");
Todas essas necessidades não podem ser atendidas com o uso básico do
protocolo HTTP, uma vez que ele não é orientado à sessão ou conexão. Com os
cookies é possível contornar essa deficiência, uma vez que as informações que
são neles armazenadas podem ser usadas para identificar os clientes. Existem
outras formas de contornar a deficiência do protocolo de HTTP, como a
codificação de URL e o uso de campos escondidos nas páginas HTML, mas o
uso de cookies é a técnica mais utiliza, por ser mais simples e padronizada. No
entanto, o usuário pode impedir que o navegador aceite cookies, o que torna o
ato de navegar pela Web muito desagradável. Neste caso, é necessário utilizar as
outras técnicas para controle de sessão.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
out.println("<h3>Teste de Cookies</h3>");
out.println("<P>");
out.print("<form action=\"CookieTeste\" method=POST>");
out.println("Nome : <input type=text length=20 name=cookienome><br>");
out.println("Valor : <input type=text length=20 name=cookievalor><br>");
out.println("<input type=submit></form>");
out.println("</body>");
out.println("</html>");
}
...
Cookie cookie = new Cookie(cName ,cValor);
cookie.setDomain(“*.uvf.br”); // todos os domínios como dpi.ufv.br mas não *.dpi.ufv.br
cookie.setMaxAge (3600); // uma hora de tempo de vida
...
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
out.println("<P>");
out.println("Dados da Sessao:" + "<br>");
Enumeration valueNames = session.getAttributeNames();
while (valueNames.hasMoreElements())
{
String name = (String)valueNames.nextElement();
String value = (String) session.getAttribute(name);
out.println(name + " = " + value+"<br>");
}
out.println("<P>");
out.print("<form action=\"SessionTeste\" method=POST>");
out.println("Nome: <input type=text size=20 name=nomedado><br>");
out.println("Valor: <input type=text size=20 name=valordado><br>");
out.println("<input type=submit>");
out.println("</form>");
out.println("</body></html>");
}
Identificador: session3
Data: Sun May 28 15:19:15 GMT-03:00 2000
Ultimo acesso: Sun May 28 15:19:43 GMT-03:00 2000
Dados da Sessao:
Alcione = 4
Alexandra = 6
Nome
Valor
Enviar Consulta
Figura VI-1 Saída resultante da execução do Servlet que lida com Sessões.
JSP
Servlets é uma boa idéia, mas você se imaginou montando uma página
complexa usando println()? Muitas vezes o desenvolvimento de um site é
uma tarefa complexa que envolve vários profissionais. A tarefa de projeto do
layout da página fica a cargo do Web Designer, incluindo a diagramação dos
textos e imagens, aplicação de cores, tratamento das imagens, definição da
estrutura da informação apresentada no site e dos links para navegação pela
mesma. Já o Desenvolvedor Web é responsável pela criação das aplicações que
vão executar em um site. O trabalho destes dois profissionais é somado na
criação de um único produto, mas durante o desenvolvimento a interferência
mutua deve ser a mínima possível. Ou seja, um profissional não deve precisar
alterar o que é foi feito pelo outro profissional para cumprir sua tarefa. A
tecnologia Servlet não nos permite atingir esse ideal. Por exemplo, suponha que
um Web Designer terminou o desenvolvimento de uma página e a entregou para
o Desenvolvedor Web codificar em um Servlet. Se após a codificação o Web
Designer desejar realizar uma alteração na página será necessário que ele altere o
código do Servlet (do qual ele nada entende) ou entregar uma nova página para o
Desenvolvedor Web para que ele a codifique totalmente mais uma vez. Qualquer
uma dessas alternativas são indesejáveis e foi devido a esse problema a Sun
desenvolveu uma tecnologia baseada em Servlets chamada de JSP.
Java Server Pages (JSP) são páginas HTML que incluem código Java e
outros tags especiais. Desta forma as partes estáticas da página não precisam ser
geradas por println(). Elas são fixadas na própria página. A parte dinâmica
é gerada pelo código JSP. Assim a parte estática da página pode ser projetada
por um Web Designer que nada sabe de Java.
A primeira vez que uma página JSP é carregada pelo container JSP o
código Java é compilado gerando um Servlet que é executado, gerando uma
página HTML que é enviada para o navegador. As chamadas subsequentes são
enviadas diretamente ao Servlet gerado na primeira requisição, não ocorrendo
mais as etapas de geração e compilação do Servlet.
A figura XX.XX mostra um esquema das etapas de execução de uma
página JSP na primeira vez que é requisitada. Na etapa (1) a requisição é enviada
para um servidor Web que reencaminha a requisição (etapa 2) para o container
Servlet/JSP. Na etapa (3) o container verifica que não existe nenhuma instância
de Servlet correspondente à página JSP. Neste caso, a página JSP é traduzida
para código fonte de uma classe Servlet que será usada na resposta à requisição.
Na etapa (4) o código fonte do Servlet é compilado, e na etapa (5) é criada uma
Navegador (1)
Requisição de
página JSP Servidor
Http
(2)
Encaminha a requisição
(6)
Resposta à (3)
requisição Container Traduz Página
Servlet/JSP
jsp
(5) (4)
Instancia e Compila
executa
Bytecode Fonte
Servlet Servlet
PHP X JSP
PHP (Personal Home Pages) é uma linguagem script para ser executada
no lado servidor criada em 1994 como um projeto pessoal de Rasmus Lerdorf.
Atualmente encontra-se na versão 4. A sintaxe é fortemente baseada em C mas
possui elementos de C++, Java e Perl. Possui suporte à programação OO por
meio de classes e objetos. Possui também suporte extensivo à Banco de dados
ODBC, MySql, Sybase, Oracle e outros. PHP é uma linguagem mais fácil no
desenvolvimento de pequenas aplicações para Web em relação à JSP, uma vez
ASP X JSP
ASP (Active Server Pages) é a solução desenvolvida pela Microsoft®
para atender as requisições feitas à servidores Web. Incorporada inicialmente
apenas ao Internet Information Server (IIS), no entanto, atualmente já é
suportada por outros servidores populares, como o Apache. O desenvolvimento
de páginas que usam ASP envolve a produção de um script contendo HTML
misturado com blocos de código de controle ASP. Este código de controle pode
conter scripts em JavaScript ou VBScript. A primeira vantagem de JSP sobre
ASP é que a parte dinâmica é escrita em Java e não Visual Basic ou outra
linguagem proprietária da Microsoft, portanto JSP é mais poderoso e fácil de
usar. Em segundo lugar JSP é mais portável para outros sistemas operacionais e
servidores WEB que não sejam Microsoft.
<html>
<head>
<title>Exemplo JSP</title>
</head>
<body>
<%
String x = "Olá Mundo!";
%>
<%=x%>
</body>
</html>
http://localhost:8080/examples/jsp/ola.jsp
out.write("\r\n");
out.print(x);
out.write("\r\n </body>\r\n</html>\r\n");
...
} catch (Exception ex) {
...
}
}
}
Objetos implícitos
No exemplo XX.XX pode-se ver a declaração de variáveis que
referenciam a alguns objetos importantes. Estas variáveis estão disponíveis para
o projetista da página JSP. As variáveis mais importantes são:
Classe Variável
HttpServletRequest request
HttpServletResponse response
PageContext pageContext
ServletContext application
HttpSession session
JspWriter out
Tags JSP
Os tags JSP possuem a seguinte forma geral:
Expressões
Scriptlets
Declarações
Diretivas
Comentários
Expressões
Exemplos:
<%= new java.util.Date() %>
<%= request.getMethod() %>
Scriptlets
<html>
<head><title>Conversao Celcius Fahrenheit </title></head>
<body>
<%
String valor = request.getParameter("celcius");
if (valor != null )
{
double f = Double.parseDouble(valor)*9/5 +32;
out.println("<P>");
out.println("<h2>Valor em Fahrenheit:" +f +"<h2><br>");
}
%>
<form action=conversao.jsp method=POST>
Celcius: <input type=text size=20 name=celcius><br>
<input type=submit>
</form>
</body>
</html>
Exemplo XX.XX- Página JSP que converte graus Celcius para Fahrenheit.
Valor em Fahrenheit:86.0
Celcius:
Enviar Consulta
Declarações
<%!
private double converte(double c)
{
return c*9/5 +32;
}
%>
Comentários
<%--comentário --%>
<!—comentário -->
Diretivas
Diretivas são mensagens para JSP container. Elas não enviam nada para a
página mas são importantes para definir atributos JSP e dependências com o JSP
container. A forma geral da diretivas é a seguinte:
ou
<%@ Diretiva atributo1 ="valor1"
atributo2 ="valor2"
...
atributoN =" valorN " %>
Diretiva page
<%@ page atributo1 ="valor1" ... atributoN =" valorN " %>
import
contentType
isThreadSafe
Exemplo:
<%
response.setContentType("text/plain")
;
%>
Diretiva include
Exemplo:
Formulário
• telefone = 333-3333
• nome = Alcione
• submit = envie
Nome:
Telefone:
envie
<html><body>
<H1>Session id: <%= session.getId() %></H1>
<%
Cookie[] cookies = request.getCookies();
For(int i = 0; i < cookies.length; i++) { %>
Cookie name: <%= cookies[i].getName() %> <br>
Value: <%= cookies[i].getValue() %><br>
antiga idade máxima em segundos:
<%= cookies[i].getMaxAge() %><br>
<% cookies[i].setMaxAge(5); %>
nova idade máxima em segundos:
<%= cookies[i].getMaxAge() %><br>
<% } %>
<%! Int count = 0; int dcount = 0; %>
<% response.addCookie(new Cookie(
”Cookie " + count++, ”Valor " + dcount++)); %>
</body></html>
<%
Enumeration atribs = session.getAttributeNames();
while(atribs.hasMoreElements()) {
String atrib = (String)atribs.nextElement();
String valor = (String)session.getAttribute(atrib); %>
<li><%= atrib %> = <%= valor %></li>
<% } %>
<html><body>
<H1>Id da sessão: <%= session.getId() %></H1>
<%
String nome = request.getParameter("nome");
String telefone = request.getParameter("telefone");
Formulário
Id da sessão: soo8utc4m1
Essa sessão foi criada em 1002202317590
Antigo intervalo de inatividade = 1800
Novo intervalo de inatividade= 10
telefone = 333-3333
nome = Alcione
Nome:
Telefone:
envie
Id da sessão: soo8utc4m1
Retorna
O Uso de JavaBeans
Página bean.jsp
<HTML> <HEAD>
<TITLE>Uso de beans</TITLE>
</HEAD> <BODY> <CENTER>
Arquivo Curso/BeanSimples.java
package curso;
Uso de JavaBeans
</BODY> </HTML>
Uso de JavaBeans
Mensagem: Ola!
Texto:
envie
Escopo Descrição
page Objetos declarados com nesse escopo são válidos até a
resposta ser enviada ou a requisição ser encaminhada
para outro programa no mesmo ambiente, ou seja, só
podem ser referenciados nas páginas onde forem
declarados. Objetos declarados com escopo page são
referenciados pelo objeto pagecontext.
request Objetos declarados com nesse escopo são válidos durante
a requisição e são acessíveis mesmo quando a requisição
é encaminhada para outro programa no mesmo ambiente.
Objetos declarados com escopo request são
referenciados pelo objeto request.
session Objetos declarados com nesse escopo são válidos durante
a sessão desde que a página seja definida para funcionar
em uma sessão. Objetos declarados com escopo
session são referenciados pelo objeto session.
application Objetos declarados com nesse escopo são acessíveis por
páginas no mesmo servidor de aplicação. Objetos
declarados com escopo application são
referenciados pelo objeto application.
Página compras.jsp
<html>
<jsp:useBean id="carrinho" scope="session" class="compra.Carrinho" />
<jsp:setProperty name="carrinho" property="*" />
<body bgcolor="#FFFFFF">
<%
carrinho.processRequest(request);
String[] items = carrinho.getItems();
if (items.length>0) {
%>
<font size=+2 color="#3333FF">Você comprou os seguintes itens:</font>
<ol>
<%
for (int i=0; i<items.length; i++) {
out.println("<li>"+items[i]);
}
}
%>
</ol>
<hr>
<form type=POST action= compras.jsp>
<br><font color="#3333FF" size=+2>Entre um item para adicionar ou remover:
</font><br>
<select NAME="item">
<option>Televisão
<option>Rádio
<option>Computador
<option>Vídeo Cassete
</select>
<p><input TYPE=submit name="submit" value="adicione">
<input TYPE=submit name="submit" value="remova"></form>
</body>
</html>
JavaBean compra/Carrinho.java
package compra;
import javax.servlet.http.*;
import java.util.Vector;
import java.util.Enumeration;
if (submit.equals("adicione")) addItem(item);
else if (submit.equals("remova")) removeItem(item);
reset();
}
}
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
Servidor de Aplicação
1
3 JavaBean
(modelo)
4
5
JSP
Resposta (Apresentação)
MiddleWare
JDBC
SGBD
USUARIO PESSOA
Alcione de P. Oliveira, Vinícius V. Maciel - UFV
Java na Prática – Volume II 152
1:1 1:1
Arquivo Descrição
agenda.html Página inicial do site, contendo o formulário para a
entrada do login e senha para entrar no restante do
site.
principal.jsp Página JSP contendo o formulário para entrada de
dados para inserção, remoção ou consulta de itens da
agenda.
LoginBean.java JavaBean responsável por verificar se o usuário está
autorizado a acessar a agenda.
AgendaServlet.java Servlet responsável pelo tratamento de requisições
sobre alguma função da agenda (consulta, inserção e
remoção)
AcaoBean.java JavaBean responsável pela execução da ação
solicitada pelo usuário.
ConnectionBean.java JavaBean responsável pelo acesso ao DB e controle
das conexões.
1
agenda.html AgendaServlet
4 6
2
5 3
principal.jsp LoginBean ConnectionBean
8
AcaoBean 7
1 e 4 – Requisições
2 e 6 – instanciações
4 – reencaminhamento de
requisições
3,5,7 e 8 – Chamadas de métodos
1 <HTML>
2 <HEAD>
3 <TITLE>Agenda</TITLE>
4 </HEAD>
5
6 <BODY BGCOLOR="#FFFFFF">
7 <P align="center"><IMG src="tit.gif" width="350" height="100" border="0"></P>
8 <BR>
9
10 <CENTER>
11 <FORM method="POST" name="TesteSub" onsubmit="return TestaVal()"
12 action="/agenda/agenda"><BR>
13 Login:<INPUT size="20" type="text" name="login"><BR><BR>
14 Senha:<INPUT size="20" type="password" name="senha"><BR><BR><BR>
15 <INPUT type="submit" name="envia" value="Enviar">
16 <INPUT size="3" type="Hidden" name="corrente" value="0"><BR>
17 </FORM>
18 </CENTER>
19 <SCRIPT language="JavaScript">
20 <!--
21 function TestaVal()
22 {
23 if (document.TesteSub.login.value == "")
24 {
25 alert ("Campo Login nao Preenchido...Form nao Submetido")
26 return false
27 }
28 else if (document.TesteSub.senha.value == "")
29 {
20 alert ("Campo Senha nao Preenchido...Form nao Submetido")
31 return false
32 }
33 else
34 {
35 return true
36 }
37 }
38 //--></SCRIPT>
39 </BODY></HTML>
1 <HTML><HEAD>
2 <TITLE>Tela da Agenda </TITLE>
3 </HEAD><BODY bgcolor="#FFFFFF">
4 <%@ page session="true" import="agenda.*" %>
5
6 <%
7 agenda.LoginBean lb = (agenda.LoginBean) session.getAttribute("loginbean");
8 agenda.AcaoBean ab = (agenda.AcaoBean) request.getAttribute("acaobean");
9 if (lb != null && lb.getStatus())
10 { %>
11 <H2>Sessão do <%= lb.getNome() %></H2>
12 <%
13 if (ab!=null) out.println(ab.toString());
14 %>
15
16 <P><BR></P>
17 <FORM method="POST" name="formprin" onsubmit="return TestaVal()"
18 action="/agenda/agenda">
19 Nome: <INPUT size="50" type="text" name="nome"><BR>
20 Telefone: <INPUT size="20" type="text" name="telefone"><BR>
21 Endereço: <INPUT size="50" type="text" name="endereco"><BR>
22 Email: <INPUT size="50" type="text" name="email"><BR><BR>
23 Página: <INPUT size="50" type="text" name="pagina"><BR>
24 Celular: <INPUT size="20" type="text" name="celular"><BR>
25 Descrição: <INPUT size="20" type="text" name="descricao">
26 <BR><CENTER>
27 <INPUT type="submit" name="acao" value="Consulta">
28 <INPUT type="submit" name="acao" value="Insere">
29 <INPUT type="submit" name="acao" value="Apaga"></CENTER>
30 <INPUT size="3" type="Hidden" name="corrente" value="1">
31 </FORM>
32
33 <SCRIPT language="JavaScript"><!--
34 function TestaVal()
35 {
36 if (document.formprin.nome.value == "" &&
37 document.formprin.descricao.value== "")
38 {
39 alert ("Campo Nome ou Descricao devem ser Preenchidos!")
40 return false
41 }
42 else
43 {
44 return true
45 }
46 }
47 //--></SCRIPT>
48
49 <%
50 }
51 else
52 {
53 session.invalidate();
1 package agenda;
2
3 import java.sql.*;
4 import java.lang.*;
5 import java.util.*;
6
7 public class ConnectionBean {
8 private Connection con=null;
9 private static int clients=0;
10 static private ConnectionBean instance=null;
11
12 private ConnectionBean() { init(); }
13
14 static synchronized public ConnectionBean getInstance() {
15 if (instance == null) {
16 instance = new ConnectionBean();
17 }
18 return instance;
19 }
20
21 private void init() {
22 try {
23 Class.forName("org.hsqldb.jdbcDriver");
24 con=
25 DriverManager.getConnection("jdbc:hsqldb:hsql://localhost","sa","");
26 } catch(Exception e){System.out.println(e.getMessage());};
27 }
28
29 public synchronized void devolveConnection(Connection con) {
1 package agenda;
2
3 import java.sql.*;
4 import java.lang.*;
5 import java.util.*;
6
7 public class LoginBean {
8 protected String nome = null;
9 protected String login= null;
10 protected boolean status= false;
11
1 package agenda;
2
3 import javax.servlet.*;
4 import javax.servlet.http.*;
5 import agenda.*;
6
7 public class AgendaServlet extends HttpServlet
8 {
9 public void doGet(HttpServletRequest request, HttpServletResponse response)
10 {
11 performTask(request,response);
12 }
13 public void doPost(HttpServletRequest request,
14 HttpServletResponse response)
15 {
16 performTask(request,response);
17 }
18
19 public void performTask(HttpServletRequest request,
20 HttpServletResponse response)
21 {
22 String url;
23 HttpSession sessao;
24 String corrente = request.getParameter("corrente");
25 int icorr=0;
26 if (corrente != null) icorr = Integer.parseInt(corrente);
27
28 try
1 package agenda;
2
3 import java.lang.*;
4 import java.util.*;
5 import java.sql.*;
6
7 public class AcaoBean
8 {
9 private Connection con=null;
10 private StringBuffer retorno = null;
11 private Statement stmt=null;
12 private String [] legenda= {"Código","Nome","Telefone",
13 "Endereço", "email","hp",
Instalação do SGBD
SET CLASSPATH=%CLASSPATH%;c:\sgbd\hsqldb_v.1.61\lib\hsqldb.jar
c:\sgbd\hsqldb_v.1.61\demo\runServer.bat
c:\sgbd\hsqldb_v.1.61\demo\runManager.bat
Instalação da Aplicação
páginas
HTML e JSP Servlets e
JavaBeans
Alcione de P. Oliveira, Vinícius V. Maciel - UFV
arquivo
web.xml
Java na Prática – Volume II 169
webapps
|_____ agenda
|_____ Web-inf
|_____classes
|_______agenda
...
<web-app>
<servlet>
<servlet-name>
agenda
</servlet-name>
<servlet-class>
agenda.AgendaServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
agenda
</servlet-name>
<url-pattern>
/agenda
</url-pattern>
</servlet-mapping>
...
</web-app>
Resposta: isso pode ser feito com o método de instância exec da classe
Runtime.
Como criar um TextField que não exiba o que está sendo digitado para
se usado como campo de entrada de senhas?
Bibliografia
Eckel B. Thinking in Java. 2nd Ed. New Jersey : Prentice Hall, 2000.
Gosling J., Joy W., Steele G. The Java Language Specification. Massachusetts :
Addison-Wesley, 1996.
Oaks S., Wong H. Java Threads. 2ª Ed. California : O’Reilly & Associates, Inc,
1999.
Ethan H., Lycklama E. How do you Plug Java Memory Leaks? Dr. Dobb´s
Journal, San Francisco, CA, No. 309, February 2000.
Wahli U. e outros. Servlet and JSP Programming with IBM WebSphere Studio
and VisualAge for Java, IBM RedBooks, California, May 2000.
Links
Revistas
http://www.javaworld.com/
Revista online sobre Java.
Livros
http://www.eckelobjects.com/
Página do autor do livro Thinking in Java, atualmente em segunda edição. O
livro pode ser baixado gratuitamente no site.
http://www.redbooks.ibm.com/booklist.html
Livros da IBM
Servidores
http://jakarta.apache.org
Página do projeto Jakarta que desenvolveu o Tomcat.
http://www.metronet.com/~wjm/tomcat
Lista Tomcat
http://www.jboss.org
Servidor de aplicação gratuito habilitado para EJB
http://gamelan.earthweb.com/
Página da com informações, Applets, Lista de discussão, tutoriais.
http://www.inquiry.com/techtips/java_pro
Ask the Java Pro
http://www.jguru.com/
jGuru.com(Home): Your view of the Java universe
http://www.soujava.org.br
Servlets e JSP
http://www.servlet.com/srvdev.jhtml
Servlet Inc : Developers Forum
http://www.servlets.com
Servlets.com
http://www.jspin.com/home
Jspin.com - The JSP Resource Index
http://www.burridge.net/jsp/jspinfo.html
Web Development with JSP: JSP, Java Servlet, and Java Bean
Information
http://www.apl.jhu.edu/~hall/java/Servlet-
Tutorial
A Tutorial on Java Servlets and Java Server Pages (JSP)
Índice
MVC.............................................. 148, 151
A
N
ASP ........................................................124
Níveis de isolamento ............................... 85
C
Nível de Isolamento................................. 83
Calendar ................................................1
P
CGI ..........................................................99
contexto da aplicação .............................107 PHP........................................................ 123
Cookies ..................................................115 pool de conexões.................................... 157
CORBA....................................................69 Prepared Statements ................................ 87
Procedimentos Armazenados................... 88
D
R
Demilitarized Zone ................................151
DMZ...............Consulte Demilitarized Zone RMI ......................................................... 69
E S
EJB.........................................................149 Servlets .................................................... 97
Enterprise JavaBeans ............. Consulte EJB Singleton................................................ 158
sites dinâmicos......................................... 97
J Stored Procedures.................................... 88
JSP ...................................................97, 122 T
M Transação................................................. 83
Mudança de Contexto..............................5