2. O QUE É QUE NÓS VAMOS VER?
JavaScript
O que é AJAX?
Fazendo requisições ao servidor com AJAX
Frameworks JavaScript para facilitar o
desenvolvimento de aplicações com AJAX;
AJAX em Java com DWR;
3. JOÃO É UM FELIZ DESENVOLVEDOR DA
FOO CORP.
Olá, eu sou o João!
10. ...
É... Sabe....
É Sabe Meio que... que
Eu... Hum... Não... Sei...
Fazer... Aquilo...
11. JOÃO SABE DE MUITA COISA, MAS NÃO
SABE O QUE É AJAX...
AJAX, o lava roupas
do Google!
E Tripla Ação!
12. MAS O JOÃO NÃO FOI O ÚNICO A SER PEGO
DE SURPRESA
13. UM POUCO DE HISTÓRIA
Antes do Google Maps e do GMail, poucas
pessoas conheciam o AJAX;
Antes de se descobrir o AJAX, não havia um
modo simples de se atualizar uma página HTML
sem ter que pedir um novo documento ao
servidor;
Antes do AJAX, as pessoas achavam que usar
AJAX
<frame>s era lindo;
14. MAS O QUE É AJAX?
AJAX é o acrônimo para:
Assinchronous
JAvaScript
JA S i
&
XML
15. PAUSA PRA UM EXEMPLO DE ASSÍNCRONIA
– CORRIDAS DE CARRO SÃO ASSÍNCRONAS?
17. UMA AULINHA BÁSICA DE HISTÓRIA
A Microsoft precisava de um modo de fazer um
cliente web para o Outlook;
O cliente web precisava atualizar a página sem
ter que fazer um “refresh” a cada atualização;
refresh
Então l
E tã eles criaram um objeto que fazia
i bj t f i
exatamente isso;
18. XMLHTTPREQUEST É A MÁGICA
É o objeto JavaScript que faz as requisições ao
servidor web, sem que seja necessário fazer um
refresh;
Com ele é possível invocar qualquer um dos
métodos HTTP em uma URL e passar
parâmetros para a invocação;
O resultado da requisição é utilizado para
atualizar a página automaticamente;
19. REVISÃO BÁSICA DE JAVASCRIPT
Linguagem d programação orientada a objetos,
Li de ã i t d bj t
baseada em protótipos;
Criada pela NetScape (olha a idade...);
Não parece nem um pouco com Java;
Tipada dinamicamente;
Interpretada;
Roda fora dos browsers;
Baseada na especificação ECMAScript;
21. DECLARANDO VARIÁVEIS
Variáveis podem ou não ser declaradas com a
palavra-chave “var”;
Uma variável pode receber qualquer valor, pois
ela não tem um tipo específico;
JavaScript suporta basicamente 5 ti
J S i t t b i t tipos,
números, boolean, String, objetos puros e objetos
função;
22. DECLARANDO FUNÇÕES
function somarNumeros( um, dois) {
return um + dois;
}
alert( somarNumeros( 1, 2 ) );
function inicializar() {
alert("Inicializado");
}
window.onload = inicializar;
23. DECLARANDO FUNÇÕES
Funções são um tipo especial de objeto, eles são
declarados com a palavra chave “function” e
podem receber parâmetros e retornar um valor;
Uma função é invocada através da declaração do
seu nome seguido de parenteses “()”, com os
parâmetros que ela deve receber;
Não é possível fazer sobrecarga de funções em
JavaScript;
24. DETALHES DAS FUNÇÕES
A quantidade d parâmetros passada é sempre
tid d de â t d
variável, não é possível obrigar o usuário a
passa
passar mais ou menos;
aso e os;
Não é possível fazer sobrecarga de funções em
p g ç
JavaScript;
Ao declarar uma função, uma variável com o seu
nome é automaticamente criada;
Uma função pode ser atribuída a um “listener”
através da declaração do seu nome;
ç ;
25. O QUE É O DOM?
Document Object Model (DOM) é a estrutura que
os navegadores criam para todos os documentos
HTML que eles carregam;
É possível interagir com o DOM através de
JavaScript, tanto para leituras quanto para
alterações;
(Quase) Qualquer tag HTML pode ser alterada e
os navegadores costumam se comportar
corretamente;
26. ALTERANDO O CONTEÚDO DE UM NÓ
HTML – (JEITO FÁCIL)
<script t
< i t type="text/javascript">
"t t/j i t">
function alterarTexto() {
document.getElementById("message")
g y g
.innerHTML =
"<span style='color:red;'>Eu sou o
valor alterado!</span> ;
alterado!</span>";
}
</script>
<body>
<div id="message"></div>
id= message ></div>
<button onclick="alterarTexto()">Click
Me</button>
</body>
/b d
27. AGORA NO MODO “HARD”
function alterarTextoCriandoElemento() {
f ti lt T t C i d El t ()
var span = document.createElement("span");
p ( p );
span.setAttribute("style", "color:red;");
var textNode =
document.createTextNode("Eu sou o valor
alterado de baixo");
span.appendChild( textNode);
var div =
document.getElementById("message2");
d t tEl tB Id(" 2")
div.appendChild(span);
}
28. MAGIA NEGRA EM JAVASCRIPT (MENTIRA,
ISSO É HTML)
<html>
<head>
</head>
<body>
<div id="message"></div>
<button onclick="modifyPage()">Click
Me</button>
</body>
</html>
29. MAGIA NEGRA EM JAVASCRIPT 2 – A
VINGANÇA
<script type="text/javascript">
var xhr;
function modifyPage() {
xhr = new XMLHttpRequest();
xhr.open("GET", "/message");
xhr.setRequestHeader("User-Agent", "Eu mesmo");
xhr.onreadystatechange=
xhr onreadystatechange= function() {
if (xhr.readyState != 4) return;
document.getElementById("message").innerHTML =
xhr.responseText;
xhr responseText;
}
xhr.send(null);
}
</script>
30. PAUSA PARA OS COMERCIAIS – VALORES
DA PROPRIEDADE “READYSTATE”
0: (Nã iniciado)
0 (Não i i i d ) – O método “send()” ainda não f i
ét d “ d()” i d ã foi
chamado;
1: (Carregando) – O método foi chamado e a
requisição está sendo enviada;
2: (Carregado) – A resposta já foi completamente
enviada pelo servidor;
3: (Interativo) – A resposta está sendo tratada;
4: (Completado) – A resposta foi tratada e está pronta
pra ser consumida;
31. E ESSE É UM SERVLET SEM MÁGICA
NENHUMA
public class MessageSer let e tends HttpSer let {
MessageServlet extends HttpServlet
private final String message = "Olá Mundo Outra Vêz";
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
H S l R )
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.getWriter().print( this.message );
}
}
32. NO FIREFOX É UMA BELEZA, JÁ NA
CONCORRÊNCIA...
E eu... Uma pedra...
p
33. MAGIA NEGRA EM JAVASCRIPT 3 – O
RETORNO
IE < 5
function getXmlHttpObject() {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP"); IE >= 5
} catch (e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xhr = false;
} Firefox – Mozilla – Safari - Opera
}
if (!xhr && typeof XMLHttpRequest != 'undefined') {
xhr = new XMLHttpRequest();
}
return xhr;
}
34. PRIMEIROS PROBLEMAS?
Incompatibilidade entre browsers (a guerra está
de volta?);
Comportamentos diferentes entre os browsers;
O MUNDO usa o Internet Explorer, VOCÊ não
vai mudar isso (armas podem ajudar, mas...);
i d i ( d j d )
35. AGORA PASSEMOS PRA ALGO MAIS ÚTIL
João precisa facilitar a vida dos usuários, no
formulário de cadastro de clientes ele tem que
carregar a rua a cidade e o estado pelo CEP;
rua,
Ele deve ter uma lista disso no servidor;
A página precisa se atualizar automaticamente
á i i t li t ti t
na hora que o usuário terminar de digitar o CEP;
36. OLHEM SÓ, ORIENTADO A OBJETOS!
public class Address {
private String street;
private String city;
private String state;
}
37. INDO PARA O SERVLET
protected void doGet(HttpServletRequest req HttpServletResponse resp)
req,
throws ServletException, IOException {
Address address = null;
String zip = req.getParameter( "zip" );
if ( zip != null ) {
address = this.addresses.get( zip );
g ( p )
}
if ( address == null ) {
address = this addresses values() iterator() next();
this.addresses.values().iterator().next();
}
req.setAttribute("address", address);
req.getRequestDispatcher("/jsp/addressCsv.jsp").forward(req, resp);
}
39. E COM VOCÊS, O JAVASCRIPT!
function getZipData(zipCode) {
xhr = createXHR();
xhr.onreadystatechange=processZipData;
p ( ,
xhr.open("GET",
"/zipService?zip=" + zipCode);
xhr.send(null);
}
function processZipData() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var data = xhr.responseText;
var cityState = data.split(',');
document.getElementById("street").value = cityState[0];
document.getElementById("city").value = cityState[1];
document.getElementById("state").value = cityState[2];
document.getElementById("zipError").innerHTML = "";
} else {
document.getElementById("zipError").innerHTML = "Error - " + hhr.status;
}
}
}
40. O QUE É QUE ACONTECEU?
Quando o usuário terminou de digitar e saiu do
campo, um evento foi enviado (“onblur”);
Respondendo ao evento, nós enviamos uma
chamada assíncrona ao servidor com as
informações do usuário para atualizar a página;
Quando a requisição foi respondida, nós pegamos
os seus dados e atualizamos a interface (ou
mostramos um erro);
41. AGORA TEMOS UM NOVO PROBLEMA...
Eu ainda
estava
digitando
o nome!
42. EXPECTATIVAS
Os usuários web tem expectativas sobre o
funcionamento das páginas;
Uma coisa só está carregando, se ele tiver clicado
em algum lugar pra fazer isso;
As á i
A páginas só se atualizam se ele mandar elas se
ó t li l d l
atualizarem;
Quebrar expectativas não é bom;
44. FRAMEWORK PROTOTYPE
Biblioteca para facilitar o uso de AJAX;
Desenvolvida por desenvolvedores do Ruby on
Rails (muito influenciada por Ruby);
Simples e direta, mas com poucas
funcionalidades avançadas;
f i lid d d
45. FUNÇÕES ATALHO - $(“IDDOELEMENTO”)
<script>
function teste1() {
var d = $('myDiv');
alert(d.innerHTML);
}
function teste2(){
var divs = $('myDiv','myOtherDiv');
for(i=0; i<divs.length; i++) {
g
alert(divs[i].innerHTML);
}
}
</script>
<div id="myDiv">
<p>Este é um parágrafo</p>
</div>
<div id="myOtherDiv">
<p>Outro parágrafo</p>
</div>
<input type="button" value=Teste1 onclick="teste1();"><br/>
p yp ();
<input type="button" value=Teste2 onclick="teste2();"><br/>
48. FUNÇÕES ATALHO - $H(OBJETO)
<script>
function testarHash(){
//criando o objeto
var a = {
primeiro: 10,
segundo: 20,
g ,
terceiro: 30
};
//transformando-o
//transformando o em um hash
var h = $H(a);
alert(h.toQueryString());
//mostra: primeiro=10&segundo=20&terceiro=30
}
/ p
</script>
49. AJAX.REQUEST
function getZipData(zipCode) {
var myAjax = new Ajax.Request(
"/zipService",
{
method: 'get',
parameters: "zip=" + zipCode,
onComplete: mostraResposta
});
}
function mostraResposta( xhr ) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var data = xhr responseText;
xhr.responseText;
//mesmo código internamente
}
}
50. AJAX.UPDATER
<script>
function buscaHTML(){
var url = 'http://servidor/app/buscaHTML';
var pars = 'algumParametro=ABC';
var myAjax =
new Ajax Updater( 'resposta aqui' url
Ajax.Updater( 'resposta_aqui', url,
{
method: 'get',
parameters: pars
});
}
</script>
<input type=button value="Busca HTML"
onclick="buscaHTML()">
<div id="resposta_aqui"></div>
51. IMPLEMENTANDO UM “AUTOCOMPLETE”
PARA O CEP
Implementar a lógica de um autocompletador
para o campo CEP (ZIP);
Conforme o usuário clica, ele deve mostrar os
resultados;
O resultado selecionado pelo usuário d
lt d l i d l á i deve ser o
resultado que vai estar no campo;
Isso não vai ser simples de se fazer no braço...
52. MAS NÓS NÃO VAMOS FAZER NO BRAÇO!
<input
id="zip"
onblur="getZipData(this.value)"
type="text"
name="zip"
autocomplete="off"
/>
<div
class="auto_complete"
id="zip_values"></div>
54. SERVLET AUTOCOMPLETADOR (AQUI TEM
Q
CÓDIGO, FINALMENTE...)
String[] zips = new String[] { "1001000" "1103500" "0000004"
"1001000", "1103500",
};
List results = new ArrayList();
String val = request.getParameter("zip");
for (int i = 0; i < zips.length; i++) {
if (zips[i].startsWith(val))
results.add(zips[i]);
lt dd( i [i])
}
String message = "<ul>";
Iterator iter = results.iterator();
while (iter.hasNext()) {
message += "<li>" + (String) iter.next() + "</li>";
}
message += "</ul>";
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(message);
t i tl ( )
55. MAS AINDA NÃO É O SUFICIENTE...
O usuário ainda não sabe que a requisição está
acontecendo;
Alguma coisa tem que avisar a ele que a
requisição está acontecendo;
Ele também deve ser avisado quando a requisição
El t bé d i d d i i ã
terminar;
56. PREPARANDO O LUGAR...
<input
i t
id="zip"
onblur="getZipData(this.value)"
onblur "getZipData(this value)"
type="text"
name= zip
name="zip"
autocomplete="off"
/>
<span id="zipProgress"
style="display:none;"><img
src="../progress.gif"/></span>
<div class="auto_complete"
id="zip_values">
id "zip values">
57. CHAMANDO OS EFEITOS...
var myAjax = new Ajax.Request(
"/zipService",
{
method: 'get',
parameters: "zip=" + zipCode,
onComplete: mostraResposta,
onLoading: mostrarAnimacao
}); }
58. IMPLEMENTANDO OS EFEITOS
function mostraResposta( xhr ) {
Element.hide('zipProgress');
if (xhr.status == 200) {
var data = xhr.responseText;
p ;
var cityState = data.split(',');
document.getElementById("street").value = cityState[0];
document.getElementById("city").value = cityState[1];
document.getElementById("state").value = cityState[2];
document.getElementById("zipError").innerHTML = "";
new Effect.Highlight('tableForm', { duration: 3.0 } );
} else {
document.getElementById("zipError").innerHTML = "Error -
" + hhr.status;
}
}
function mostrarAnimacao() {
Element.show('zipProgress');
El t h (' i P ')
}
59. AJAX EM JAVA COM DWR
Direct Web Remoting (DWR) é uma biblioteca de
AJAX que integra JavaScript com Java;
É possível invocar objetos Java de dentro de
páginas JavaScript alterando o estado de objetos
JavaScript,
no servidor;
Não depende de nenhum outro framework;
Tem integrações para o framework Spring e
Struts;
60. CONFIGURANDO O SERVLET DO DWR
<servlet>
<ser let>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
p
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</init param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
p / / / p
</servlet-mapping>
61. CRIANDO O ARQUIVO DE CONFIGURAÇÃO
Q Ç
DO DWR – DWR.XML
<?xml version="1 0" encoding="UTF 8"?>
version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web
Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<convert match="org.maujr.aulas.ajax.*"
< t t h " j l j *"
converter="bean"/>
<create javascript="CustomerManager" creator="new"
scope="application">
li i
<param name="class"
value="org.maujr.aulas.ajax.CustomerManager"/>
</create>
</allow>
</dwr>
62. DECLARANDO A DEPENDÊNCIA DO DWR
NO CÓDIGO
<script
i t
type="text/javascript"
src /dwr/interface/CustomerManager.js
src="/dwr/interface/CustomerManager js
“/>
<script
type="text/javascript"
src="/dwr/engine.js"></script>
<script
< i t
type='text/javascript'
src /dwr/util.js >
src='/dwr/util js'> </script>
64. IMPLEMENTAÇÃO DA ADIÇÃO
function addCustomer(){
var customer = { number:null, name:null, email:null };
dwr.util.getValues( customer );
CustomerManager.addCustomer( customer );
CustomerManager.getCustomers( fillList );
}
function fillList( customers ) {
$("customers").innerHTML = ""
$(" t ") i HTML "";
for ( var x = 0; x < customers.size() ; x++ ) {
$( customers ).innerHTML
$("customers").innerHTML += customers[x].name + ", ";
, ;
}
return false;
}
65. ALÉM DO AJAX – CLIENTES RICOS PARA A
WEB
Flex - Air
Silverlight
Google Gears
XUL
JavaFX
66. REFERÊNCIAS
Livros
Pragmatic AJAX
AJAX In Action
Sites
Prototype - htt //
P t t http://www.prototypejs.org/
t t j /
Scrip.taculo.us - http://script.aculo.us/
DWR - http://getahead org/dwr
http://getahead.org/dwr