Upload
mauricio-linhares
View
2.525
Download
1
Embed Size (px)
Citation preview
AJAX EM JAVA
Dando vida nova aquelas suas pobres páginas esquecidas
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;
JOÃO É UM FELIZ DESENVOLVEDOR DAFOO CORP.
Olá, eu sou o João!
JOÃO ESTÁ TRABALHANDO EM UM NOVOPROJETO...
E ESTÁ USANDO TODAS AS TECNOLOGIASQUE SEMPRE SONHOU...
JTA
EJBJSF
J
Lucene Quatz
UM BELO DIA, O TELEFONE TOCA.....
Jooooãããããããããããããããããããããããããããoooo!Venha aqui!
E LÁ VAI O POBRE JOÃO...
Pois é, dancei...
NO ABATEDOURO....
Por que o nosso sistema não funciona Por que o nosso sistema não funciona IGUAL ao ????????
NÃO TÁ FUNCIONANDO, MAS VOCÊ,ENTENDEU NÉ...
...
É Sabe Meio que É... Sabe.... Meio que... Eu... Hum... Não... Sei...
Fazer... Aquilo...
JOÃO SABE DE MUITA COISA, MAS NÃO,SABE O QUE É AJAX...
AJAX, o lava roupas do Google!
E Tripla Ação!
MAS O JOÃO NÃO FOI O ÚNICO A SER PEGODE SURPRESA
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 modo simples de se atualizar uma página HTML sem ter que pedir um novo documento ao servidor;servidor;
Antes do AJAX as pessoas achavam que usar Antes do AJAX, as pessoas achavam que usar <frame>s era lindo;
MAS O QUE É AJAX?
AJAX é o acrônimo para:AssinchronousJA S iJAvaScript
&XMLXML
PAUSA PRA UM EXEMPLO DE ASSÍNCRONIA– CORRIDAS DE CARRO SÃO ASSÍNCRONAS?
BEM, A NÃO SER QUE SEJA COM ELES NÉ...
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;ter que fazer um refresh a cada atualização;
E tã l i bj t f i Então eles criaram um objeto que fazia exatamente isso;
XMLHTTPREQUEST É A MÁGICA
ÉÉ o objeto JavaScript que faz as requisições ao servidor web, sem que seja necessário fazer um refresh;refresh;
Com ele é possível invocar qualquer um dos Com ele é possível invocar qualquer um dos métodos HTTP em uma URL e passar parâmetros para a invocação;parâmetros para a invocação;
O resultado da requisição é utilizado para O resultado da requisição é utilizado para atualizar a página automaticamente;
REVISÃO BÁSICA DE JAVASCRIPT
Li d ã i t d bj t Linguagem de programação orientada a objetos, baseada em protótipos;
Criada pela NetScape (olha a idade...);
Não parece nem um pouco com Java;Não parece nem um pouco com Java;
Tipada dinamicamente;
Interpretada;
Roda fora dos browsers;
Baseada na especificação ECMAScript;
DECLARANDO VARIÁVEIS
var variavel = “Sou Uma Variavel”
variavel = 10outraVariavel = 20soma = variavel + outraVariavelvariavel = 5outraVaravel = 10soma = variavel + outraVariavel
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;ela não tem um tipo específico;
J S i t t b i t 5 ti JavaScript suporta basicamente 5 tipos, números, boolean, String, objetos puros e objetos função;função;
DECLARANDO FUNÇÕES
function somarNumeros( um, dois) {return um + dois;
}
alert( somarNumeros( 1, 2 ) );
function inicializar() {alert("Inicializado");
}window.onload = inicializar;
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;podem receber parâmetros e retornar um valor;
Uma função é invocada através da declaração do Uma função é invocada através da declaração do seu nome seguido de parenteses “()”, com os parâmetros que ela deve receber;parâmetros que ela deve receber;
Não é possível fazer sobrecarga de funções em Não é possível fazer sobrecarga de funções em JavaScript;
DETALHES DAS FUNÇÕES
A tid d d â t d é A quantidade de parâmetros passada é sempre variável, não é possível obrigar o usuário a passar mais ou menos;passa a s o 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;ç ;
O QUE É O DOM?Document Object Model (DOM) é a estrutura que os navegadores criam para todos os documentos HTML que eles carregam;HTML que eles carregam;
É possível interagir com o DOM através de É possível interagir com o DOM através de JavaScript, tanto para leituras quanto para alterações;alterações;
(Quase) Qualquer tag HTML pode ser alterada e (Quase) Qualquer tag HTML pode ser alterada e os navegadores costumam se comportar corretamente;
ALTERANDO O CONTEÚDO DE UM NÓHTML – (JEITO FÁCIL)< i t t "t t/j i t"><script type="text/javascript">function alterarTexto() {
document.getElementById("message")g y g.innerHTML =
"<span style='color:red;'>Eu sou o valor alterado!</span>";valor alterado!</span> ;}
</script>
<body><div id="message"></div><div id= message ></div><button onclick="alterarTexto()">Click Me</button>/b d</body>
AGORA NO MODO “HARD”f ti lt T t C i d El t () {function alterarTextoCriandoElemento() {
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 =
d t tEl tB Id(" 2")document.getElementById("message2"); div.appendChild(span);
}}
MAGIA NEGRA EM JAVASCRIPT (MENTIRA, ( ,ISSO É HTML)<html>
<head></head><body><div id="message"></div><button onclick="modifyPage()">Click Me</button></body>
</html>
MAGIA NEGRA EM JAVASCRIPT 2 – A VINGANÇA<script type="text/javascript"><script type="text/javascript">
var xhr;
function modifyPage() {function modifyPage() {
xhr = new XMLHttpRequest();
xhr.open("GET", "/message");xhr.setRequestHeader("User-Agent", "Eu mesmo");xhr onreadystatechange= function() {xhr.onreadystatechange= function() {
if (xhr.readyState != 4) return;document.getElementById("message").innerHTML =
xhr responseText;xhr.responseText;}xhr.send(null);}}
</script>
PAUSA PARA OS COMERCIAIS – VALORESDA PROPRIEDADE “READYSTATE”
0 (Nã i i i d ) O ét d “ d()” i d ã f i 0: (Não iniciado) – O método “send()” ainda não 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;enviada pelo servidor;
3: (Interativo) – A resposta está sendo tratada;
4: (Completado) – A resposta foi tratada e está pronta pra ser consumida;pra ser consumida;
E ESSE É UM SERVLET SEM MÁGICANENHUMApublic class MessageSer let e tends HttpSer let {public class MessageServlet extends HttpServlet {
private final String message = "Olá Mundo Outra Vêz";
@Overrideprotected void doGet(HttpServletRequest req, H S l R )HttpServletResponse resp)throws ServletException, IOException {
resp.setContentType("text/plain");resp.getWriter().print( this.message );
}
}}
NO FIREFOX É UMA BELEZA, JÁ NA,CONCORRÊNCIA...
E eu... Uma pedra...p
MAGIA NEGRA EM JAVASCRIPT 3 – O RETORNOfunction getXmlHttpObject() { IE < 5function getXmlHttpObject() {
try {xhr = new ActiveXObject("Msxml2.XMLHTTP");} catch (e) {
IE >= 5} catch (e) {
try {xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {} catch (E) {xhr = false;
}}
Firefox – Mozilla – Safari - Opera}
if (!xhr && typeof XMLHttpRequest != 'undefined') {xhr = new XMLHttpRequest();xhr = new XMLHttpRequest();
}
return xhr;return xhr;}
PRIMEIROS PROBLEMAS?Incompatibilidade entre browsers (a guerra está de volta?);
Comportamentos diferentes entre os browsers;
O MUNDO usa o Internet Explorer, VOCÊ não i d i ( d j d )vai mudar isso (armas podem ajudar, mas...);
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;carregar a rua, a cidade e o estado pelo CEP;
Ele deve ter uma lista disso no servidor;Ele deve ter uma lista disso no servidor;
A á i i t li t ti t A página precisa se atualizar automaticamente na hora que o usuário terminar de digitar o CEP;
OLHEM SÓ, ORIENTADO A OBJETOS!public class Address {
private String street;
private String city;
private String state;
}
INDO PARA O SERVLETprotected void doGet(HttpServletRequest req HttpServletResponse resp)protected void doGet(HttpServletRequest req, HttpServletResponse resp)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();address = this.addresses.values().iterator().next();
}
req.setAttribute("address", address);req.getRequestDispatcher("/jsp/addressCsv.jsp").forward(req, resp);
}
O HTML<tr><tr><th>Zip:</th>
<td><input onblur="getZipData(this.value)"type="text" name="zip"/></td>yp p / /
<td id="zipError" style="color: red"></td></tr><tr>
<th>Street:</th><td><input id="street" type="text" name="street"/></td>
</tr><t ><tr>
<th>City:</th><td><input id="city" type="text" name="city"/></td>
</tr>/tr<tr>
<th>State:</th><td><input id="state" type="text" name="state"/></td>
</tr>
E COM VOCÊS, O JAVASCRIPT!function getZipData(zipCode) {
xhr = createXHR();
xhr.onreadystatechange=processZipData;
xhr.open("GET",p ( ,
"/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;
}
}
}
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 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 os seus dados e atualizamos a interface (ou mostramos um erro);
AGORA TEMOS UM NOVO PROBLEMA...
Eu ainda estava
digitandoo nome!
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;em algum lugar pra fazer isso;
A á i ó t li l d l As páginas só se atualizam se ele mandar elas se atualizarem;
Quebrar expectativas não é bom;
FRAMEWORKS AJAX
FRAMEWORK PROTOTYPE
Biblioteca para facilitar o uso de AJAX;
Desenvolvida por desenvolvedores do Ruby onRails (muito influenciada por Ruby);
Simples e direta, mas com poucas f i lid d dfuncionalidades avançadas;
FUNÇÕES ATALHO - $(“IDDOELEMENTO”)<script><script>function teste1() {var d = $('myDiv');alert(d.innerHTML);}function teste2(){var divs = $('myDiv','myOtherDiv');for(i=0; i<divs.length; i++) {galert(divs[i].innerHTML);}
}</script></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/>
FUNÇÕES ATALHO - $F(“IDDOELEMENTO”)<script>
function teste3(){
alert( $F('nomeUsuario') );
}
</script>
<input type="text" id="nomeUsuario" value="João da Silva"><br>
<input type="button" value=Teste3 onclick="teste3();"><br>
FUNÇÕES ATALHO - $A(OBJETO)<script><script>
function mostraOpcoes(){var minhaNodeList = $('lstEmpregados').getElementsByTagName('option');var nodes = $A(minhaNodeList);nodes.each(function(node){
alert(node.nodeName + ': ' + node.innerHTML);});
}</script>
<select id="lstEmpregados" size="10" ><select id="lstEmpregados" size="10" ><option value="5">Buchanan, Steven</option><option value="8">Callahan, Laura</option><option value="1">Davolio, Nancy</option></select>
<input type="button" value="Mostre items da lista" onclick="mostraOpcoes();" >
FUNÇÕES ATALHO - $H(OBJETO)<script><script>function testarHash(){//criando o objetovar a = {primeiro: 10,segundo: 20,g ,terceiro: 30};//transformando o em um hash//transformando-o em um hashvar h = $H(a);alert(h.toQueryString()); //mostra: primeiro=10&segundo=20&terceiro=30}</script>/ p
AJAX.REQUESTfunction getZipData(zipCode) {function getZipData(zipCode) {var myAjax = new Ajax.Request(
"/zipService", {{method: 'get', parameters: "zip=" + zipCode, onComplete: mostraRespostaonComplete: mostraResposta
});}function mostraResposta( xhr ) {function mostraResposta( xhr ) {
if (xhr.readyState == 4) {if (xhr.status == 200) {
var data = xhr responseText;var data = xhr.responseText;//mesmo código internamente
}}}
AJAX.UPDATER<script><script>function buscaHTML(){
var url = 'http://servidor/app/buscaHTML';var pars = 'algumParametro=ABC';var pars = 'algumParametro=ABC';
var myAjax = new Ajax Updater( 'resposta aqui' urlnew Ajax.Updater( 'resposta_aqui', url,
{ method: 'get', parameters: parsparameters: pars
});}</script></script>
<input type=button value="Busca HTML" onclick="buscaHTML()">
<div id="resposta_aqui"></div>
IMPLEMENTANDO UM “AUTOCOMPLETE” PARA O CEP
Implementar a lógica de um autocompletadorpara o campo CEP (ZIP);
Conforme o usuário clica, ele deve mostrar os resultados;resultados;
O lt d l i d l á i d O resultado selecionado pelo usuário deve ser o resultado que vai estar no campo;
Isso não vai ser simples de se fazer no braço...
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>
CÓDIGO DO AUTOCOMPLETADOR
new Ajax.Autocompleter( "zip", 'zip_values', '/autoComplete', {})
SERVLET AUTOCOMPLETADOR (AQUI TEM( QCÓDIGO, FINALMENTE...)String[] zips = new String[] { "1001000" "1103500" "0000004"String[] zips = new String[] { "1001000", "1103500", "0000004"
};
List results = new ArrayList();String val = request.getParameter("zip");for (int i = 0; i < zips.length; i++) {
if (zips[i].startsWith(val))lt dd( i [i])results.add(zips[i]);
}String message = "<ul>";Iterator iter = results.iterator();Iterator iter results.iterator();while (iter.hasNext()) {message += "<li>" + (String) iter.next() + "</li>";}message += "</ul>";response.setContentType("text/html");PrintWriter out = response.getWriter();t i tl ( )out.println(message);
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;requisição está acontecendo;
El t bé d i d d i i ã Ele também deve ser avisado quando a requisição terminar;
PREPARANDO O LUGAR...i t<input id="zip"onblur "getZipData(this value)"onblur="getZipData(this.value)"type="text" name="zip"name= zipautocomplete="off"/>/><span id="zipProgress" style="display:none;"><imgsrc="../progress.gif"/></span>
<div class="auto_complete" id "zip values">id="zip_values">
CHAMANDO OS EFEITOS...
var myAjax = new Ajax.Request("/zipService",
{
method: 'get',
parameters: "zip=" + zipCode,
onComplete: mostraResposta,
onLoading: mostrarAnimacao
}); }
IMPLEMENTANDO OS EFEITOSfunction mostraResposta( xhr ) {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 {} else {document.getElementById("zipError").innerHTML = "Error -
" + hhr.status;}
}
function mostrarAnimacao() {El t h (' i P ')Element.show('zipProgress');
}
AJAX EM JAVA COM DWRDirect 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 páginas JavaScript, alterando o estado de objetos no servidor;
Não depende de nenhum outro framework;
Tem integrações para o framework Spring e Struts;Struts;
CONFIGURANDO O SERVLET DO DWR<ser let><servlet><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>
CRIANDO O ARQUIVO DE CONFIGURAÇÃOQ ÇDO DWR – DWR.XML<?xml version="1 0" encoding="UTF 8"?><?xml 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>
< t t h " j l j *"<convert match="org.maujr.aulas.ajax.*" converter="bean"/>
<create javascript="CustomerManager" creator="new" li iscope="application">
<param name="class" value="org.maujr.aulas.ajax.CustomerManager"/>
</create>
</allow></dwr>
DECLARANDO A DEPENDÊNCIA DO DWR NO CÓDIGO
i t<script type="text/javascript" src="/dwr/interface/CustomerManager jssrc /dwr/interface/CustomerManager.js“/>
<script type="text/javascript" src="/dwr/engine.js"></script>
< i t<script type='text/javascript' src='/dwr/util js'> </script>src /dwr/util.js > </script>
FORMULÁRIO DE ADIÇÃO
<input type="button" value="Add Customer" onclick="addCustomer()"/>
<input type="button" value="Show Customers"Customers" onclick="CustomerManager.getCustomers( fillList )"/>) /
IMPLEMENTAÇÃO DA ADIÇÃOfunction addCustomer(){function addCustomer(){
var customer = { number:null, name:null, email:null };dwr.util.getValues( customer );
CustomerManager.addCustomer( customer );CustomerManager.getCustomers( fillList );
}
function fillList( customers ) {
$(" t ") i HTML ""$("customers").innerHTML = "";
for ( var x = 0; x < customers.size() ; x++ ) {$("customers").innerHTML += customers[x].name + ", ";$( customers ).innerHTML customers[x].name , ;
}
return false;}
ALÉM DO AJAX – CLIENTES RICOS PARA AWEB
Flex - Air
Silverlight
Google Gears
XUL
JavaFX
REFERÊNCIAS
LivrosPragmatic AJAXAJAX In Action
SitesP t t htt // t t j /Prototype - http://www.prototypejs.org/Scrip.taculo.us - http://script.aculo.us/DWR - http://getahead org/dwrDWR - http://getahead.org/dwr
DÚVIDAS?