11.07.2015 Views

AJAX - Universidad de Deusto

AJAX - Universidad de Deusto

AJAX - Universidad de Deusto

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE<strong>AJAX</strong>: AsynchronousJavaScript and XML (<strong>AJAX</strong>)Dr. Diego Lz. <strong>de</strong> Ipiña Gz. <strong>de</strong> Artazahttp://paginaspersonales.<strong>de</strong>usto.es/dipinadipina@esi<strong>de</strong>.<strong>de</strong>usto.es<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEContenidos• Introducción a <strong>AJAX</strong>• Análisis <strong>de</strong> sus componentes:• XHTML y CSS• JavaScript• DOM y XSLT• Hola mundo en <strong>AJAX</strong>• Frameworks <strong>AJAX</strong>• Ejemplos avanzados• Conclusión1


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEConcepto <strong>AJAX</strong>• <strong>AJAX</strong> (Asynchronous Javascript and XML) es una técnica <strong>de</strong><strong>de</strong>sarrollo web que genera aplicaciones web interactivascombinando:• XHTML y CSS para la presentación <strong>de</strong> información• Document Object Mo<strong>de</strong>l (DOM) para visualizar dinámicamente einteractuar con la información presentada• XML, XSLT para intercambiar y manipular datos• JSON y JSON-RPC pue<strong>de</strong>n ser alternativas a XML/XSLT• XMLHttpRequest para recuperar datos asíncronamente• Javascript como nexo <strong>de</strong> unión <strong>de</strong> todas estas tecnologías• <strong>AJAX</strong> es un patrón <strong>de</strong> diseño que propone un nuevo mo<strong>de</strong>lo<strong>de</strong> interacción Web combinando las tecnologías anteriores• Los navegadores que soportan las tecnologías mencionadas sonlas plataformas en las que se ejecutan las aplicaciones <strong>AJAX</strong>(Firefox, Iexplorer, Opera, Konqueror y Safari)<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE¿Por qué <strong>AJAX</strong>?• Las aplicaciones web proliferan <strong>de</strong>bido a su simplicidad,pero:• Ofrecen una menor interactividad y usabilidad en comparacióncon las aplicaciones <strong>de</strong>sktop.• La interacción <strong>de</strong>l usuario con una aplicación web se interrumpecada vez que se necesita algo <strong>de</strong>l servidor• Varias tecnologías han sido diseñadas para resolver esteproblema:• Java Applets, FLASH• ¡<strong>AJAX</strong> es una nueva solución!• Término acuñado por Jesse James Garrett enhttp://www.adaptivepath.com/publications/essays/archives/000385.php• No requiere plugins o capacida<strong>de</strong>s específicas <strong>de</strong> ciertosnavegadores.• ¿En competición con Smart Clients <strong>de</strong> MicroSoft?2


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDTML y <strong>AJAX</strong>, ¿lo mismo?• DTML (Dynamic HTML) técnica <strong>de</strong> <strong>de</strong>sarrollo<strong>de</strong> webs interactivas combinando HTML,client-si<strong>de</strong> scripting con JavaScript y ellenguaje <strong>de</strong> <strong>de</strong>finición <strong>de</strong> estilos (CSS)• Realmente <strong>AJAX</strong> es un refinamiento <strong>de</strong> DTML• Al igual que en <strong>AJAX</strong> el principal problema <strong>de</strong>DTML es el diferente soporte <strong>de</strong> estastecnologías en los navegadores y losdiferentes tamaños <strong>de</strong> pantalla <strong>de</strong> usuarios• El mismo DOM (Document Object Mo<strong>de</strong>l) essoportado por las últimas versiones <strong>de</strong> losnavegadores<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECaracterísticas <strong>AJAX</strong>• Las aplicaciones son más interactivas, respon<strong>de</strong>n a lasinteracciones <strong>de</strong>l usuario más rápidamente, al estilo <strong>de</strong>sktop• Estas aplicaciones tienen un look and feel muy similar a lasaplicaciones <strong>de</strong> sobremesa tradicionales sin <strong>de</strong>pen<strong>de</strong>r <strong>de</strong> pluginso características específicas <strong>de</strong> los navegadores• Se reduce el tamaño <strong>de</strong> la información intercambiada• Muchas micro-peticiones, pero el flujo <strong>de</strong> datos global es inferior• Se libera <strong>de</strong> procesamiento a la parte servidora (se realiza en laparte cliente)• <strong>AJAX</strong> actualiza porciones <strong>de</strong> la página en vez <strong>de</strong> la páginacompleta• Es necesario asegurarse que una aplicación <strong>AJAX</strong> funciona entodo navegador, lo mismo que en DHTML3


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE<strong>AJAX</strong> vs. Aplicaciones WebTradicionales• Las aplicaciones web tradicionales:• Requieren que el usuario rellene formularios y haga un POST<strong>de</strong> los mismos a un servidor web• El servidor web procesa los datos enviados y genera un nuevapágina web en consecuencia• Mientras el servidor realiza cierto procesamiento – recuperadatos, realiza cálculos – para generar una página, el usuario ha<strong>de</strong> esperar• Aparte <strong>de</strong> los datos <strong>de</strong> la aplicación la información <strong>de</strong>formateo en XHTML <strong>de</strong>be ser transmitida• En ocasiones el HTML <strong>de</strong> una página a la siguiente varía muyligeramente.• <strong>AJAX</strong> solamente envía peticiones a los servidores víaHTTP y procesa la información recuperada(únicamente la necesitada) mediante JavaScript<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE<strong>AJAX</strong> vs. Aplicaciones WebTradicionalesNavegador ClienteNavegador ClienteInterfaz <strong>de</strong> UsuarioPetición HTTPTransporte http(s)Datos HTML + CSSServidor WebInterfaz <strong>de</strong> UsuarioLlamada JavaScriptDatos HTML+CSSMódulo (Motor) AjaxPetición HTTPTransporte http(s)Datos XMLServidor Web y XMLRDBMS, ERP, CRMSistema ServidorMo<strong>de</strong>lo clásico <strong>de</strong>aplicación webRDBMS, ERP, CRMSistema ServidorMo<strong>de</strong>lo Ajax <strong>de</strong>aplicación web4


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE<strong>AJAX</strong> vs. Aplicaciones WebTradicionales<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE<strong>AJAX</strong> vs. Aplicaciones WebTradicionales5


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEAplicaciones <strong>AJAX</strong> famosas• Empresas <strong>de</strong> renombre internacional están <strong>de</strong>finiendosoluciones basadas en <strong>AJAX</strong>:• Google• Orkut (https://www.orkut.com/Login.aspx) es una comunidad virtualque conecta online a gente a través <strong>de</strong> una red <strong>de</strong> amigos.• Gmail (www.gmail.com)• Google Suggest (http://www.google.com/webhp?complete=1&hl=en) sugiere valores <strong>de</strong> búsqueda a medida que escribes caracteres• Google Maps (http://maps.google.com/)• Yahoo!• Flickr (http://www.flickr.com/) es una aplicación para gestionar ycompartir fotos• Oddpost (http://oddpost.com/learnmore)• El equipo <strong>de</strong> webmail Oddpost actualmente están trabajando en rediseñarYahoo! Mail siguiendo la filosofía <strong>AJAX</strong>• En <strong>de</strong>finitiva, <strong>AJAX</strong> no es solamente un buena solución técnicasino que a<strong>de</strong>más tiene una gran aplicabilidad como se<strong>de</strong>muestra por aplicaciones reales complejas.<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEGoogle Gmail(www.gmail.com)• Gmail coloca un motor UI en la parte cliente en forma <strong>de</strong> unmódulo/fichero JavaScript• Cuando hace login en Gmail una copia <strong>de</strong> ese motor es <strong>de</strong>scargado enuno <strong>de</strong> los HTML page frames y permanece ahí por el resto <strong>de</strong> lasesión• Este enfoque no es nuevo, fue adoptado por Oddpost• Las acciones sobre la interfaz <strong>de</strong> Gmail son ruteadas a través <strong>de</strong>l motorUI en el navegador, que realiza peticiones HTTP (con el objetoXmlHttpRequest) al servidor <strong>de</strong> Gmail• El servidor Gmail envía información en DataPack que soninterpretados por el motor UI para actualizar dinámicamente la interfaz• DataPack es similar a Javascript Object Notation (JSON – www.json.org)• Una razón <strong>de</strong>l éxito <strong>de</strong> Gmail es su mucho mayor interactividad yusabilidad.• Otros servicios <strong>de</strong> correo como Hotmail y Yahoo! Mail siguen un enfoquetradicional <strong>de</strong> <strong>de</strong>sarrollo web y vuelven a <strong>de</strong>scargar toda la interfazcompletamente <strong>de</strong>spués <strong>de</strong> cada acción.7


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEPresentación en <strong>AJAX</strong>: XHTMLy CSS• XHTML <strong>de</strong>fine la estructura <strong>de</strong> undocumento• CSS proporciona el “look and feel” aldocumento<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEXHTML (I)• XHTML (eXtensible HyperText Mark-up Language) esla siguiente especificación <strong>de</strong> HTML.• Es HTML basado en XML.• Los usuarios pue<strong>de</strong>n añadir sus propias etiquetas alcontenido.• XHTML 1.1 está modularizado: sus etiquetas seagrupan en módulos, <strong>de</strong> esta forma, todo el lenguajese encuentra <strong>de</strong>scompuesto en módulos.• El significado <strong>de</strong> las etiquetas y su uso sigue elestándar HTML 4.01.8


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEXHTML (II)• Algunos <strong>de</strong> estos módulos son:• Estructura• Texto• Hipertexto• Lista• Applet• Formularios básicos• Formularios• Imagen• Marcos• ...• A<strong>de</strong>más se pue<strong>de</strong>n añadir nuevos módulos.<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEXHTML (III)• XHTML Basic es una versión <strong>de</strong> XHTMLa<strong>de</strong>cuada para terminales móviles.• Incluye los módulos:• Estructura (body, head, html, title)• Texto (abbr, acronym, address, blockquote,br, cite, co<strong>de</strong>, dfn, div, em, h1, h2, h3,h4, h5, h6, kbd, p, pre, q, samp, span,strong, var)• Hipertexto (a)9


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEXHTML (IV)• Incluye los módulos (cont.):• Lista (dl, dt, dd, ol, ul, li)• Formularios básicos (form, input, label, select,option, textarea)• Tablas básicas (caption, table, td, th, tr)• Imagen (img)• Objeto (object, param)• Metainformación (meta)• Link (link)• Base (base)<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECascading Style Sheets (CSS)• CSS es un lenguaje <strong>de</strong> estilos utilizado para <strong>de</strong>scribir lapresentación <strong>de</strong> un documento escrito en lenguaje <strong>de</strong>marcado.• Su uso más típico es proporcionar el “look and feel” <strong>de</strong>páginas web en XHTML, aunque pue<strong>de</strong> ser utilizado enaplicaciones XML como SVG o XUL• La especificación <strong>de</strong> CSS es mantenida por el World Wi<strong>de</strong>Web Consortium (W3C)• A través <strong>de</strong> CSS se pue<strong>de</strong>n <strong>de</strong>finir colores, fuentes,layouts y otros aspectos <strong>de</strong> la presentación <strong>de</strong> undocumento.• Sirve para separar la estructura <strong>de</strong> un documento (HTML)<strong>de</strong> su presentación (CSS).• http://en.wikipedia.org/wiki/Cascading_Style_Sheets10


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUtilidad <strong>de</strong> CSS• Antes <strong>de</strong> CSS, los autores <strong>de</strong> páginas HTML utilizaban elementos como o para cambiar el formato <strong>de</strong> las páginas, combinabanestructura y presentación• Por ejemplo, si queremos que una cabecera esté centrada, en cursiva,en rojo y con la fuente Times New Roman, podríamos hacer:Usage of CSS• Con CSS, el elemento h2 pue<strong>de</strong> ser utilizado para dar estructura altexto, mientras que la hoja <strong>de</strong> estilo le da sus característicaspresentacionales. Así en XHTML tendríamos:Usage of CSS• Mientras que en CSS <strong>de</strong>finiríamos las características <strong>de</strong> formato paratodas las cabeceras h2:h2 {text-align: center;color: red;font: italic large "Times New Roman", serif;}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECSS• La información <strong>de</strong> un CSS pue<strong>de</strong> ser provista por:• Autor <strong>de</strong> estilos• Un fichero CSS referenciado <strong>de</strong>s<strong>de</strong> el documento• Embebido en el documento• Estilo <strong>de</strong>l usuario• Un fichero CSS local es especificado por el usuario en su navegadorpara ser aplicado a todos los documentos• Estilo <strong>de</strong>l User-Agent• La hoja <strong>de</strong> estilo por <strong>de</strong>fecto aplicada por el navegador• Las principales ventajas <strong>de</strong> CSS son:• Información <strong>de</strong> presentación para una página web completa o unacolección <strong>de</strong> páginas resi<strong>de</strong>nte en un único lugar don<strong>de</strong> pue<strong>de</strong> seractualizada• Diferentes usuarios pue<strong>de</strong>n tener sus propias hojas <strong>de</strong> estilo(fuentes gran<strong>de</strong>s)• El código <strong>de</strong>l documento es reducido en tamaño y complejidad,porque no tiene que contener información <strong>de</strong> presentación11


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECSS• Los elementos <strong>de</strong> un documento son seleccionados a través <strong>de</strong>selectores:• Todos los elementos ‘*’• Por nombre <strong>de</strong> elemento ‘p’ ó‘h2’• Descen<strong>de</strong>ntes• Todos los elementos a <strong>de</strong>scendientes <strong>de</strong> li ‘li a’• Atributos <strong>de</strong> clase o i<strong>de</strong>ntificadores• .nombreclase y/o #id para elementos conclass="nombreclase" or id="id"• Estilos adyacentes• Todos los elementos A precedidos por h2 ‘h2+a’• Existen también pseudoclases que re<strong>de</strong>finen el comportamientosobre elementos:• hover <strong>de</strong>fine un estilo cuando el usuario apunta a un elemento• a:hover o #elementid:hover• :first-line, :visited or :before.<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECSS• Una hoja <strong>de</strong> estilos contiene un conjunto <strong>de</strong>reglas• Cada regla consiste <strong>de</strong> un selector y unbloque <strong>de</strong>clarativo• Un bloque <strong>de</strong>clarativo contiene un conjunto<strong>de</strong> <strong>de</strong>claraciones separadas por ;• Cada <strong>de</strong>claración consiste <strong>de</strong> una propiedad,: y un valor12


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo CSSp {font-family: "Garamond", serif;}h2 {font-size: 110%;color: red;background: white;}.note {color: red;background: yellow;font-weight: bold;}p#paragraph1 {margin: none;}a:hover {text-<strong>de</strong>coration: none;}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEExplicación ejemplo CSS• Hay 5 reglas, con los selectores p, h2, .note, p#paragraph1 ya:hover.• Un ejemplo <strong>de</strong> <strong>de</strong>claración es color: red, que asigna el valor rojo auna propiedad.• Las dos primeras reglas <strong>de</strong>finen estilos para los elementos HTML p(párrafo) y h2 (cabecera <strong>de</strong> segundo nivel)• El elemento párrafo se ren<strong>de</strong>rizará en la fuente Garamond y si no estádisponible en Serif.• La cabecera será ren<strong>de</strong>rizada en rojo sobre fondo blanco.• La tercera regla <strong>de</strong>fine una clase en CSS que pue<strong>de</strong> ser asignada acualquier elemento <strong>de</strong>l documento, mediante el atributo class. Porejemplo:This paragraph will be ren<strong>de</strong>red in red andbold, with a yellow background.• La cuarta regla afectará al elemento p cuyo atributo id tenga el valorparagraph1. No tendrá márgenes <strong>de</strong>ntro <strong>de</strong> su caja <strong>de</strong> ren<strong>de</strong>rización• La última regla <strong>de</strong>fine la acción hover para todos los elementos .• Quitará el subrayado cuando el ratón se mueve sobre el elemento enlace.• Los comentarios en CSS se indican con: /* comment */13


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDELógica en <strong>AJAX</strong>: JavaScript• Es un lenguaje <strong>de</strong> scripting orientado a objetos• Es utilizado especialmente para permitir la programación ennavegadores• Algunos lo <strong>de</strong>nominan como “webpage enhancement language”• Otros dicen que es un “client-si<strong>de</strong> scripting language”• La versión estándar <strong>de</strong> JavaScript, <strong>de</strong>nominada ECMAScript vapor la versión 1.5• Java y Javascript son dos lenguajes totalmente diferentes• Presentan similitu<strong>de</strong>s sintácticas, están basados en C• Semánticamente son muy diferentes• Para escribir scripts web en JavaScript hay que familiarizarsecon:• El lenguaje JavaScript• El mo<strong>de</strong>lo <strong>de</strong> objetos <strong>de</strong>l documento (DOM) <strong>de</strong> XHTML<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUsos <strong>de</strong> JavaScript• El motor <strong>de</strong> JavaScript resi<strong>de</strong> en un programahuésped y pue<strong>de</strong> operar sobre su entorno• El JavaScript <strong>de</strong> un página pue<strong>de</strong> manipular yrecuperar su contenido a través <strong>de</strong> la interfaz DOM• El mayor uso <strong>de</strong> JavaScript es para crear aplicaciones webdinámicas• Interactuando con el DOM <strong>de</strong> una página HTML, JavaScriptpue<strong>de</strong>:• Abrir nuevas ventanas• Cambiar imágenes cuando el ratón se mueve encima <strong>de</strong> ellas• Validar campos <strong>de</strong> entrada, etc.• JavaScript también es usado por:• Adobe Acrobat• La plataforma Mozilla con XUL14


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDESintaxis JavaScript• Es case-sensitive• El “;” no es necesario al final <strong>de</strong> cadasentencia• Los comentarios siguen la misma sintáxis queen C++, /**/ y //• Las variables se <strong>de</strong>claran dinámicamenteasignándoles un valor o alternativamenteprecediéndolas con la palabra var• Las variables <strong>de</strong>claradas con var <strong>de</strong>ntro <strong>de</strong> unafunción son locales<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEOOP en JavaScript• Los objetos en Javascript toman la forma internamente <strong>de</strong> unarray asociativo, mapean nombres <strong>de</strong> propieda<strong>de</strong>s a valores• Tiene varios tipos <strong>de</strong> objetos ya <strong>de</strong>finidos:• Array, Boolean, Date, Function, Math, Number, Object,RegExp y String• También existen objetos soportados por el entorno <strong>de</strong> ejecución comowindow, form, links en el DOM.• JavaScript es un lenguaje orientado a objetos basado enprototipos.• La herencia tiene lugar entre objetos en vez <strong>de</strong> clases• Se pue<strong>de</strong>n añadir nuevas propieda<strong>de</strong>s y métodos a un objeto através <strong>de</strong> la palabra clave prototype• No es obligatorio borrar objetos ya que tiene garbage collector• JavaScript tiene los siguientes tipos <strong>de</strong> datos primitivos:• Números 4, 4.4, 44• Strings 'ab' o "ab"• Objetos conjunto <strong>de</strong> strings y numbers15


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo OOP en JavaScript// constructor functionfunction MyObject(attributeA, attributeB) {this.attributeA = attributeAthis.attributeB = attributeB}// create an Objectobj = new MyObject('red', 1000);// access an attribute of objalert(obj.attributeA);// access an attribute with the associative array notationalert(obj["attributeA"]);// add an new attributeobj.attributeC = new Date();// remove an attribute of obj<strong>de</strong>lete obj.attributeB;// remove the whole Object<strong>de</strong>lete obj;<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo Herenciafunction Base() {this.Overri<strong>de</strong> = function() {alert("Base::Overri<strong>de</strong>()");}this.BaseFunction = function() {alert("Base::BaseFunction()");}}function Derive(){this.Overri<strong>de</strong> = function() {alert("Derive::Overri<strong>de</strong>()");}}Derive.prototype = new Base();d = new Derive();d.Overri<strong>de</strong>();d.BaseFunction();d.__proto__.Overri<strong>de</strong>(); // mozilla only• produce:Derive::Overri<strong>de</strong>()Base::BaseFunction()Base::Overri<strong>de</strong>() // mozilla only16


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEAcceso público y privado avariables en JavaScript// <strong>de</strong>clarationfunction myClass() {// variablesvar privateVar = "I am private";this.publicVar = "I am public";// functionsvar privateFunction = function() {alert("I am private");}this.publicFunction = function(){alert("I am public");}}// usagevar myInstance = new myClass();myInstance.publicVar = "new value";alert(myInstance.privateVar);myInstance.publicFunction();myInstance.privateFunction();// un<strong>de</strong>fined!// error!<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEstructuras <strong>de</strong> Datos• Arrays mapas <strong>de</strong> enteros a objetos• Define métodos como join, slice y push• Tiene la propiedad length• Ejemplo:myArray = [0,1,,,4,5]; // array with length6 and 4 elementsmyArray = new Array(0,1,2,3,4,5); // arraywith length 6 and 6 elementsmyArray = new Array(365); // an empty arraywith length 36517


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEstructuras <strong>de</strong> Control• Son idénticas a las que nos encontramos en C++• if … elseif (theForm.mail.value == "" || /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(theForm.mail.value)) {alert("++ Invalid E-mail address! Please reenter.++");return false;}• Operador ?condition ? statement : statement;• Bucle while:while (condition) { statements }• Do … whiledo { statements } while (condition);<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEstructuras <strong>de</strong> Control• For loopfor ([initial-expression]; [condition]; [incrementexpression]){ statements }• For in loopfor (variable in object) { statements }• Switchswitch (expression) {case label1 :statements;break;case label2 :statements;break;<strong>de</strong>fault :statements;}18


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFunciones• Una función es un bloque <strong>de</strong> instrucciones a las que se ha dado unnombre• Los argumentos <strong>de</strong> un función pue<strong>de</strong>n ser accedidos a través <strong>de</strong> lapalabra clave arguments• No es necesario invocar a una función con todos los parámetros<strong>de</strong>clarados, los que no se pasan toman el valor un<strong>de</strong>fined• Ejemplo:function gcd(segmentA, segmentB) {while(segmentA!=segmentB)if(segmentA>segmentB)segmentA -= segmentB;elsesegmentB -= segmentA;return(segmentA);}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManejo <strong>de</strong> Errores• A través <strong>de</strong> las típicas construcciones try/catch/finally• Ejemplo:try {// Create an arrayarr = new Array();// Call a function that may not succeedfunc(arr);} catch (...) {// Recover from errorlogError();} finally {// Even if a fatal error occurred, we can stillfree our array<strong>de</strong>lete arr;}• La función eval() permite evaluar código JavaScript entiempo <strong>de</strong> ejecución.19


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEAñadiendo JavaScript a HMTL• Para incluir un fragmento <strong>de</strong> JavaScript en una página HTML, elcódigo se encierra entre las etiquetas y,normalmente colocadas en la sección // tu código• También se pue<strong>de</strong> incluir un fichero externo <strong>de</strong> JavaScript con:• A<strong>de</strong>más <strong>de</strong>s<strong>de</strong> cualquier elemento se pue<strong>de</strong> invocar aJavaScript:go backgo back<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl mo<strong>de</strong>lo <strong>de</strong> objetos HTMLDOM utilizado por JavaScript• Programar en JavaScript supone operar sobre elmo<strong>de</strong>lo <strong>de</strong> objetos <strong>de</strong>l documento (DOM)• window el objeto central que representa el navegador,contiene los objetos accesible a través <strong>de</strong> propieda<strong>de</strong>s:• Location (window.location)• Document (window.document)• History (window.history)• A<strong>de</strong>más, contiene una serie of métodos como alert(),confirm() y prompt()• No es necesario mencionar este objeto, implícitamente seasume que se invoca algo sobre él• En la siguiente URL tenemos una excelentedocumentación <strong>de</strong> todos los elementos permitidos enel DOM <strong>de</strong> un documento XHTML:• http://www.w3schools.com/htmldom/<strong>de</strong>fault.asp20


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEOperando sobre el documentoen <strong>AJAX</strong>: JavaScript DOM<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManejo <strong>de</strong> eventos• JavaScript aña<strong>de</strong> interactividad a tus páginas webpermitiendo escribir código dirigido por eventos• Ejemplo: conectar un botón a una función que esinvocada cuando el usuario hace clic:• Eventos <strong>de</strong>finidos por algunos controles HTML:• Button onBlur, onClick, onFocus• Form onReset, onSubmit• Frame onLoad, onUnload• Link onClick, onMouseOut, onMouseOver• Select onBlur, onChange, onFocus• Text onBlur, onChange, onFocus• Window onBlur, onError, onFocus, onLoad,onUnload21


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo Manejo <strong>de</strong> Eventos<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEObjeto Window• Representa la ventana <strong>de</strong>l navegador, es la raíz <strong>de</strong> la jerarquía<strong>de</strong> objetos <strong>de</strong> JavaScript• Propieda<strong>de</strong>s:• closed• <strong>de</strong>faultStatus• document• frames[]• location• Métodos:• alert()• confirm()• prompt()• open()• setTimeout()22


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEObjeto String• Propiedad length <strong>de</strong>vuelve su longitud• Métodos:• charAt()• in<strong>de</strong>xOf()• lastIn<strong>de</strong>xOf()• split()• substring()• toLowerCase()• toUpperCase()<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEReferenciando Objetos enJavaScript• Para hacer referencia al documento utilizamoswindow.document o document• Dado el siguiente fragmento <strong>de</strong> código HTML:Enter first name: Enter last name: • Para hacer referencia a la primera entrada <strong>de</strong> texto podríamoshacer:document.form.fName• Alternativamente:document.boxes.fName• Ó:document.forms[0].elements[0]23


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo Función JavaScriptfunction trimAll(str) {if (str!=null) {while (str.length > 0 &&“\n\r\t”.in<strong>de</strong>xOf(str.charAt(str.length - 1)) != -1)str=str.substring(0, str.length – 1);while (str.length > 0 &&“\n\r\t”.in<strong>de</strong>xOf(str.charAt(0)) != -1)str = str.substring(1, str.length);}return str;}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• Document Object Mo<strong>de</strong>l (DOM) es una forma <strong>de</strong> representardocumentos estructurados jerárquicos como un mo<strong>de</strong>loorientado a objetos.• DOM el el estándar oficial <strong>de</strong> la World Wi<strong>de</strong> Web Consortium(W3C) para representar documentos estructurados en unamanera neutral a la plataforma y al lenguaje <strong>de</strong> programación.• DOM fue soportado inicialmente por los navegadores web paramanipular elementos en un documento HTML. A través <strong>de</strong> DOMse pue<strong>de</strong> acce<strong>de</strong>r y actualizar dinámicamente el contenido,estructura y estilo <strong>de</strong> los documentos. Para evitar lasincompatibilida<strong>de</strong>s <strong>de</strong> las diferentes implementaciones <strong>de</strong> DOMen los diferentes navegadores, el W3C <strong>de</strong>sarrolló laespecificación DOM.• Un documento DOM bien formado tiene la forma <strong>de</strong> un árbol. Lamayoría <strong>de</strong> los procesadores <strong>de</strong> XML (Xerces) o XSL como Xalanhan sido <strong>de</strong>sarrollados para hacer uso <strong>de</strong> esta estructura, don<strong>de</strong>el documento es parseado completamente y guardado enmemoria.24


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• DOM es un árbol que representa al documentovisualizado en un navegador• La funcionalidad <strong>de</strong>l WC3 DOM hace posible lacreación <strong>de</strong> documentos web extremadamentedinámicos.• Un documento está conformado por varios nodos,cada uno representado un elemento <strong>de</strong>l documento• Un árbol establece una relación jerárquica entreelementos• Por ejemplo, el documento es un nodo que pue<strong>de</strong> contenernodos imágenes, los cuales pue<strong>de</strong>n contener atributos(relación parent-child)<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• Po<strong>de</strong>mos acce<strong>de</strong>r a cualquier elemento <strong>de</strong> undocumento a través <strong>de</strong> su ID y los siguientesmétodos:• getElementById() <strong>de</strong>vuelve una referencia al nodocorrespondiente a un ID• Por ejemplo:• Se pue<strong>de</strong> acce<strong>de</strong>r en JavaScript como:x = document.getElementById("myElement")• getElementsByTagName() <strong>de</strong>vuelve todos loselementos <strong>de</strong> un documento correspondientes al tipo <strong>de</strong>etiqueta pasado• x = document.getElementsByTagName("img") <strong>de</strong>volvería todos los elementos imagen en un documento• Para recuperar el primer elemento haríamos: firstImage =x.item(0)25


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• Cada elemento en un árbol DOM tiene una serie <strong>de</strong> métodosque permiten manipularlo• Dado el siguiente fragmento XHTML:• Po<strong>de</strong>mos recuperar una referencia al mismo mediante:x = document.getElementById("myImg")• Los siguientes métodos serán disponibles a x:• getAttribute() <strong>de</strong>vuelve el valor <strong>de</strong>l atributo pasadomyValue = x.getAttribute("src") // <strong>de</strong>vuelve jabberwocky.gif• setAttribute() asigna un valor a un atributox.setAttribute("align","right")• removeAttribute() borra el atributo pasadox.removeAttribute("align")<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• A<strong>de</strong>más, po<strong>de</strong>mos aplicar el métodogetElementsByTagName() a un elementocualquiera <strong>de</strong>l árbol• En XHTML:This is Cell FourThis is Cell FiveThis is Cell Six• En Javascript:x = document.getElementById("tableTwo")tableCells = x.getElementsByTagName("TD")26


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• A través <strong>de</strong>l nodo raíz po<strong>de</strong>mos crear nuevos nodos,<strong>de</strong>struirlos o moverlos alre<strong>de</strong>dor• createElement crea una nueva etiquetamyImg = document.createElement("IMG")• Luego le añadimos atributos :myImg.setAttribute("id","imageOne")myImg.setAttribute("src","jabberwocky.gif")• Y lo colocamos en el árbol bajo el elemento body o cualquierotro elemento mediante appendChild:docBody =document.getElementsByTagName("body").item(0)docBody.appendChild(myImg)• Po<strong>de</strong>mos añadir elementos textuales mediantecreateTextNo<strong>de</strong>()<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOMfunction buildTable() {docBody = document.getElementsByTagName("body").item(0);myTable = document.createElement("TABLE");myTable.id ="TableOne“;myTable.bor<strong>de</strong>r = 1;myTableBody = document.createElement("TBODY");for (i = 0; i < 3; i++) {row = document.createElement("TR");for (j = 0; j < 3; j++) {cell = document.createElement("TD");cell.setAttribute("WIDTH","50");cell.setAttribute("HEIGHT","50");textVal = "Cell" + i + "_" + j;textNo<strong>de</strong> = document.createTextNo<strong>de</strong>(textVal);cell.appendChild(textNo<strong>de</strong>);row.appendChild(cell);}myTableBody.appendChild(row);}myTable.appendChild(myTableBody);docBody.appendChild(myTable);}window.onload = buildTable();27


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• Otros métodos disponibles para navegar a través <strong>de</strong> DOM son:• replaceChild(new,old) reemplaza un nodo por otronewRow = document.createElement("TR");tableBody = document.getElementById("myTableBody");oldRow = document.getElementsByTagName("TR").item(0);tableBody.replaceChild(newRow,oldRow);• removeChild(child) borra un nodotableBody = document.getElementById("myTableBody");childOne =document.getElementsByTagName("TR").item(0);tableBody.removeChild(childOne);• insertBefore(new,ref) inserta un nuevo nodo <strong>de</strong>lante <strong>de</strong>otronewRow = document.createElement("TR");tableBody = document.getElementById("myTableBody");allRows = tableBody.getElementsByTagName("TR");lastRow = allRows.item(allRows.length-1);tableBody.insertBefore(newRow,lastRow) ;• hasChildNo<strong>de</strong>s() <strong>de</strong>vuelve true si un nodo tiene hijos.<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:DOM• Por otro lado cada nodo tiene las siguientes propieda<strong>de</strong>s:• no<strong>de</strong>Name <strong>de</strong>vuelve el nombre <strong>de</strong> una etiqueta HTML como un stringx = document.getElementById("myElement");if (x.no<strong>de</strong>Name == "IMG")alert("myElement is an image tag");• no<strong>de</strong>Type <strong>de</strong>vuelve un entero representando el tipo <strong>de</strong> un elemento• (1) nodo elemento, (2) atributo y (3) textox = document.getElementById("myElement");if (x.no<strong>de</strong>Type == 1) {alert("myElement is an element no<strong>de</strong>")}• no<strong>de</strong>Value el valor <strong>de</strong> un nodoa = document.getElementById("myElement");b = a.childNo<strong>de</strong>s.item(4).no<strong>de</strong>Value• parentNo<strong>de</strong> <strong>de</strong>vuelve el nodo padre <strong>de</strong>l actualx = document.getElementById("myElement");xParent = x.parentNo<strong>de</strong> ;• childNo<strong>de</strong>s <strong>de</strong>vuelve los hijos <strong>de</strong> un nodoa = document.getElementById("myElement");b = a.childNo<strong>de</strong>s.length;b = a.childNo<strong>de</strong>s.item(2);• firstChild y lastChild apuntan directamente al primer y últimoelemento en la colección childNo<strong>de</strong>s28


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:XSLT• Los navegadores actuales son capaces <strong>de</strong> realizartransformaciones XSLT• La instrucción <strong>de</strong> procesamiento xmlstylesheetindica cómo realizar taltransformación• Consi<strong>de</strong>remos el documento XML:211100-5<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEManipulando XML en <strong>AJAX</strong>:XSLT Squaresfunction showSquare(n) {alert("the square is " + n*n);} body { font-family: arial,helvetica; }h1 { font-size: 14pt }p { font-size: 10pt}SquaresClick a button to see the square of that number.29


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDocumentación XSLTProcessor• Para acce<strong>de</strong>r <strong>de</strong>s<strong>de</strong> JavaScript a XSLTrevisar documentación en:• http://www.mozilla.org/projects/xslt/jsinterface.html<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDELa magia <strong>de</strong> <strong>AJAX</strong>: El objetoXMLHttpRequest• Gracias a este objeto los clientes webpue<strong>de</strong>n recuperar y entregar XML, enbackground ASÍNCRONAMENTE.• Usando DOM po<strong>de</strong>mos leer el contenido<strong>de</strong>vuelto y modificar el documentopresente en el navegador30


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDECreación <strong>de</strong>l XMLHttpRequest• Desafortunadamente en su creación hay que teneren cuenta las diferencias entre navegadores:• En Mozilla y Safari se hará:var req = new XMLHttpRequest();• En el ActiveX <strong>de</strong> Internet Explorer haríamos:var req = newActiveXObject("Microsoft.XMLHTTP");• ...o en las últimas versiones <strong>de</strong> IE:xmlreq = new ActiveXObject("Msxml2.XMLHTTP");• Este objeto pue<strong>de</strong> trabajar <strong>de</strong> manera asíncrona alusuario<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEMétodos <strong>de</strong>lXMLHttpRequest• abort() para la invocación actual• getAllResponseHea<strong>de</strong>rs() <strong>de</strong>vuelve todas las cabeceras(nombre-valor) como un string• getResponseHea<strong>de</strong>r(“hea<strong>de</strong>rLabel”) <strong>de</strong>vuelve el valorasociado a una cabecera• open("method", "URL"[, asyncFlag[, "userName"[,"password"]]]) abre una conexión remota• Usar POST para invocaciones que envían datos al servidor, <strong>de</strong> untamaño superior a 512 bytes• Usar GET para recuperar datos <strong>de</strong>l servidor• Si asyncFlag es ‘true’ hay que <strong>de</strong>finir un método que recibirá uncallback cuando se genere el evento onreadystatechange• send(content) envía la petición con un contenidoopcional• setRequestHea<strong>de</strong>r("label", "value") aña<strong>de</strong> unacabecera a la petición31


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo XMLHttpRequestvar req = null;function loadXMLDoc(url) {// branch for native XMLHttpRequest objectif (window.XMLHttpRequest) {req = new XMLHttpRequest();// branch for IE/Windows ActiveX version} else if (window.ActiveXObject) {// Create XMLHttpRequest via MS ActiveXtry { // Try to create XMLHttpRequest in later IE versionsxmlreq = new ActiveXObject("Msxml2.XMLHTTP");} catch (e1) { // Failed to create required ActiveXObjecttry { // Try version supported by ol<strong>de</strong>r IE versionsxmlreq = new ActiveXObject("Microsoft.XMLHTTP");} catch (e2) {// Unable to create an XMLHttpRequest with ActiveX}}}if (req) {req.onreadystatechange = processReqChange;req.open("GET", url, true);req.send(null);}}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEPropieda<strong>de</strong>s Métodos <strong>de</strong>lXMLHttpRequest• Propieda<strong>de</strong>s <strong>de</strong>l objeto XMLHttpRequest:• onreadystatechange asocia el manejador <strong>de</strong> eventosinvocado cada vez que cambie el estado <strong>de</strong> una petición• readyState entero con estado <strong>de</strong> objeto:• 0 = no inicializado• 1 = cargando• 2 = cargado• 3 = interactivo• 4 = completado• responseText contenido textual <strong>de</strong> la respuesta enviada porel servidor• responseXML documento DOM correspondiente a la respuesta<strong>de</strong>l servidor• status código numérico <strong>de</strong>vuelto por el servidor• statusText mensaje <strong>de</strong> texto acompañando al código <strong>de</strong>status32


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo procesamientoeventos XMLHttpRequestfunction processReqChange() {// only if req shows "loa<strong>de</strong>d"if (req.readyState == 4) {// only if "OK"if (req.status == 200) {// ...processing statements go here...} else {alert("There was a problem retrieving theXML data:\n" +req.statusText);}}}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDESeguridad en <strong>AJAX</strong>• Por motivos <strong>de</strong> seguridad lasinvocaciones a recursos víaHTTP solamente pue<strong>de</strong>nefectuarse a páginas alojadasen el mismo dominio que el <strong>de</strong>la página que contenía el script• Si queremos que lainformación <strong>de</strong> nuestraspeticiones no sea visible<strong>de</strong>beremos utilizar un canalHTTPS.33


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDTML Document Object Mo<strong>de</strong>l• Da acceso a todo elemento en un documento• Para acce<strong>de</strong>r un elemento <strong>de</strong>ntro <strong>de</strong> un documento, ésteha <strong>de</strong> tener un i<strong>de</strong>ntificadorMy hea<strong>de</strong>rdocument.getElementById('hea<strong>de</strong>r').style.color="red"<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDENuestra primera aplicación<strong>AJAX</strong>• Vamos a consi<strong>de</strong>rar una aplicación webcon un formulario que requierevalidación en el servidor sin necesidad<strong>de</strong> refrescar la página completamente• Es <strong>de</strong>cir, realizar un HTTP POST <strong>de</strong> lapágina implícitamente• La figura en la siguiente transparenciailustra el funcionamiento <strong>de</strong> estaaplicación34


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDENuestra primera aplicación<strong>AJAX</strong><strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDENuestra primera aplicación<strong>AJAX</strong>• Los flujos <strong>de</strong> control serían:1. Un evento ocurre2. Un objeto XMLHttpRequest es creado e inicializado3. Se realiza una invocación remota a través <strong>de</strong>l objetoXMLHttpRequest4. La petición es procesada por el componente servidorValidationServlet5. Este servlet <strong>de</strong>vuelve un documento XML con el resultado6. El objeto XMLHttpRequest invoca la funcióncallback() y procesa el resultado7. El árbol DOM <strong>de</strong> la página web es actualizado35


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUn evento ocurre• Como resultados <strong>de</strong> eventos generados por lainteracción <strong>de</strong>l usuario funciones JavaScriptson invocadas• Ejemplo:<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl objeto XMLHttpRequestes creadovar req;function validate() {var idField = document.getElementById("userID");var url = "validate?id=" + escape(idField.value);if (window.XMLHttpRequest) {req = new XMLHttpRequest();} else if (window.ActiveXObject) {req = new ActiveXObject("Microsoft.XMLHTTP");}req.open("GET", url, true);req.onreadystatechange = callback;req.send(null);}• Los tres parámetros <strong>de</strong>l método open() <strong>de</strong>l objeto XMLHttpRequest indican elmétodo HTTP utilizado, la url <strong>de</strong> <strong>de</strong>stino y si el método se invocará <strong>de</strong> maneraasíncrona o no• req.onreadystatechange = callback; indica la función a invocar cuando lapetición sea resuelta36


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl objeto XMLHttpRequestrealiza una invocación remota• req.send(null); realiza la invocación, sepasa null porque un HTTP GET no tienecuerpo• Si se quiere utilizar un HTTP POST entonces:• Deberíamos enviar la cabecera Content-Type• Ejemplo HTTP POST:req.setRequestHea<strong>de</strong>r("Content-Type","application/x-www-form-urlenco<strong>de</strong>d");req.send("id=" +escape(idTextField.value));<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDELa petición es procesada porValidationServlet// compile: javac -classpath %TOMCAT_HOME%\common\lib\servlet-api.jar ValidationServlet.javaimport java.io.*;import java.text.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;public class ValidationServlet extends HttpServlet {private ServletContext context;private HashMap users = new HashMap();public void init(ServletConfig config) throws ServletException {this.context = config.getServletContext();users.put("solop","account data");users.put("solop","account data");}}public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException {String targetId = request.getParameter("id");if ((targetId != null) && !users.containsKey(targetId.trim())) {response.setContentType(“application/xml");response.setHea<strong>de</strong>r("Cache-Control", "no-cache");response.getWriter().write("invalid");} else {response.setContentType("text/xml");response.setHea<strong>de</strong>r("Cache-Control", "no-cache");response.getWriter().write("valid");}}37


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDELa petición es procesada porValidationServlet• La respuesta necesariamente tiene que seren XML, para evitar caching <strong>de</strong> respuestasse utiliza la cabecera Cache-Control:response.setContentType("text/xml");response.setHea<strong>de</strong>r("Cache-Control","no-cache");response.getWriter().write("valid");<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl objeto XMLHttpRequestinvoca la función callback yprocesa su resultado• La función callback es invocada cuando seproducen cambios en el readyState <strong>de</strong>l objetoXMLHttpRequest. Si readyState == 4 significaque la invocación ha acabado:• Una vez recibida la respuesta la representación DOM<strong>de</strong> un documento XHTML pue<strong>de</strong> ser modificadoincluyendo el contenido <strong>de</strong> la respuesta.• req.responseText <strong>de</strong>vuelve el contenido textual <strong>de</strong> larespuesta• req.responseXML la respuesta XML a la que se lepue<strong>de</strong>n aplicar métodos <strong>de</strong>l estándar DOM38


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl objeto XMLHttpRequestinvoca la función callback yprocesa su resultadofunction callback() {if (req.readyState == 4) {if (req.status == 200) {// update the HTML DOM based on whether or not message is validparseMessage();}}}function parseMessage() {var message = req.responseXML.getElementsByTagName("message")[0];setMessage(message.childNo<strong>de</strong>s[0].no<strong>de</strong>Value);}function setMessage(message) {var userMessageElement = document.getElementById("userIdMessage");userMessageElement.innerHTML = "" + message + "";}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEl XHTML DOM es actualizado• JavaScript pue<strong>de</strong> recoger una referenciaa un elemento en el HTML DOM• Por ejemplo, a través <strong>de</strong> la invocacióndocument.getElementById("userIdMessage")• Con una referencia a un elemento:• Añadir, modificar o eliminar atributos• Añadir, modificar o eliminar elementos39


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEAplicación en Ejecución<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEProblemas <strong>de</strong> <strong>AJAX</strong>• Disponibilidad <strong>de</strong>l objecto XMLHttpRequest• Aunque la mayoría <strong>de</strong> las últimas versiones soportan <strong>AJAX</strong>hay versiones antiguas y algunos navegadores que no lohacen• Usar XMLHttpRequest pue<strong>de</strong> provocar que algunosusuarios no puedan ver tu web• Por tanto, hay que proveer un mecanismo alternativo paraasegurarse que todo el mundo pueda ver tu portal <strong>AJAX</strong>• Usabilidad• Es necesario avisar en ocasiones que una acción lanzadaasíncronamente está en curso• Por ejemplo, mensajito diciendo “Actualizándose ...”• Cambiar colores <strong>de</strong> la parte <strong>de</strong> la página cambiada• Problemas con que el botón <strong>de</strong> “Atrás” <strong>de</strong>l navegador nofunciona y la URL mostrada no representa el estado actual<strong>de</strong> la página40


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEProblemas <strong>de</strong> <strong>AJAX</strong>• Carga <strong>de</strong>l Servidor• Crear una interfaz <strong>de</strong> usuario en vez <strong>de</strong> un form normalpue<strong>de</strong> incrementar el número <strong>de</strong> peticiones que llegan alservidor• Google Suggest• Hay que tener en cuenta la sobrecarga que pue<strong>de</strong> serintroducida al usar Ajax• Hay que bufear peticiones y cachear respuestas en el cliente• Delegar todo lo que se pueda a la parte cliente• Comportamiento Asíncrono• Las peticiones XMLHttpRequest pue<strong>de</strong> que no concluyanen el or<strong>de</strong>n en que fueron emitidas• Se pue<strong>de</strong> incluir un timestamp junto con cada respuesta<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDERefactoring JavaScript• JavaScript ha pasado <strong>de</strong> ser un lenguajeutilizado para aplicar pequeñas mejoras a unaweb, a servir para el <strong>de</strong>sarrollo <strong>de</strong> completasy complejas aplicaciones• Refactoring es una técnica para mejorar suestructura lógica interna y preservar sufuncionalidad• Buena guía en:http://www.softwaresecretweapons.com/jspwiki/Wiki.jsp?page=JavascriptRefactoringForSaferFasterBetter<strong>AJAX</strong>41


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo <strong>de</strong> mal JavaScriptvar req;var ready;function loadXMLDoc(url) {// this function uses req, ready,processStateChange()}function processStateChange() {// this function uses uses req, ready,processXML()}function processXML() {}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEReglas <strong>de</strong> diseño general• Evitar el uso <strong>de</strong> variables globales• Permitir que varias peticionesXMLHttpRequest se ejecutenconcurrentemente• Encapsular código <strong>de</strong> navegador específico• Mejorar el manejo <strong>de</strong> errores y supresentación• Crear archivos JavaScript reutilizables enotros proyectos42


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE1. Colocar las funciones yvariables globales en un objetofunction oyXMLRPCProvi<strong>de</strong>r(){var req;var ready;var loadXMLDoc = function (url) {// this function uses req, ready, processStateChange()}var processStateChange = function () {// this function uses uses req, ready, processXML()}var processXML = function () {}}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE2. Declarar todas las variables comoprivadas y clasificar funcionesfunction oyXMLRPCProvi<strong>de</strong>r(){var req;var ready;}this.loadXMLDoc = function (url) {// this function uses req, ready, processStateChange()}var processStateChange = function () {// this function uses uses req, ready, onComplete()}this.onComplete = function () {}43


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE3. Hacer logging <strong>de</strong> información ymejorar la gestión <strong>de</strong> erroresfunction oyXMLRPCProvi<strong>de</strong>r() {// place here all co<strong>de</strong> from previous stepvar oThis = this;// checks to see if we have too many messages in logvar internalCanMsg = function(){msgCount++;return msgCount < 100;}// adds message to internal logvar internalOnLog = function(msg){if(oThis.onLog && internalCanMsg()) {oThis.onLog(msg);}}// adds message to internal error handlervar internalOnError = function(msg){if(oThis.onError && internalCanMsg()) {oThis.onError(msg);}}this.onLog = function (msg){}this.onError = function (msg){}}<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDE4. Uso <strong>de</strong> la clase generadafunction <strong>de</strong>mo(){// clear logdocument.getElementById('output').value = "";// create logging functionvar myOnLog = function(msg){document.getElementById('output').value += msg + "\n";}// create completion functionvar myOnComplete = function(responseText, responseXML){document.getElementById('outputText').value = responseText;}alert("Done!");// create provi<strong>de</strong>r instance; wire eventsvar provi<strong>de</strong>r = new oyXMLRPCProvi<strong>de</strong>r();provi<strong>de</strong>r.onComplete = myOnComplete;provi<strong>de</strong>r.onLog = myOnLog;provi<strong>de</strong>r.onError = myOnLog;provi<strong>de</strong>r. loadXMLDoc ("../data/data.xml");}44


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks <strong>AJAX</strong>• Las frameworks JavaScript basadas en la parte cliente se divi<strong>de</strong>nen:• Frameworks <strong>de</strong> Infraestructura, abstraen al <strong>de</strong>sarrollador <strong>de</strong> lasi<strong>de</strong>osincracias <strong>de</strong> los diferentes navegadores• AjaxJS, Google<strong>AJAX</strong>SLT, Sarissa• Frameworks <strong>de</strong> aplicación, aparte <strong>de</strong> encapsular el funcionamiento <strong>de</strong>XmlHttpRequest también incluyen widgets al estilo <strong>de</strong> las GUIframeworks• Tibet, DOJO• Los tipos <strong>de</strong> frameworks en la parte servidora son:• Generación <strong>de</strong> HTML/JS se realiza automáticamente en el servidor• Invocación remota, se crea un túnel directamente <strong>de</strong>s<strong>de</strong> JavaScript afunciones en la parte servidora• Direct Web Remoting (JAVA), AjaxAC (PHP) y Ajax.NET• Las frameworks más conocidas aparecen listadas enhttp://www.ajaxpatterns.org/<strong>AJAX</strong>Frameworks• Microsoft quiere incluir soporte <strong>AJAX</strong> en ASP.NET 2.0 con Atlas:http://www.asp.net/<strong>de</strong>fault.aspx?tabin<strong>de</strong>x=7&tabid=47<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDETaxonomía Frameworks <strong>AJAX</strong>• Frameworks JavaScript puras:• Frameworks <strong>de</strong> infraestructura proveen códigoin<strong>de</strong>pendiente <strong>de</strong>l browser• Wrapper alre<strong>de</strong>dor <strong>de</strong> XMLHttpRequest (todas lasframeworks lo ofrecen)• Manipulación e interrogación <strong>de</strong> XML• Manipulación <strong>de</strong>l DOM HTML a partir <strong>de</strong> las respuestas <strong>de</strong>XMLHttpRequest• Frameworks <strong>de</strong> aplicación• Proveen lo mismo que las anteriores frameworks• A<strong>de</strong>más ofrecen widgets <strong>de</strong> manera similar a frameworks <strong>de</strong>GUI• Basadas en la parte servidora45


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDETaxonomía Frameworks <strong>AJAX</strong>• Basadas en la parte servidora• Generación <strong>de</strong> HTML/JS: el servidorprovee la generación completa <strong>de</strong> código yla coordinación entre el navegador y elservidor• Invocación remota: las llamadasJavaScript son ruteadas directamente afunciones en la parte servidora y lasrespuestas a callbacks JavaScript.<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks JavaScript Puras:Aplicación• DOJO (http://dojotoolkit.org) ofrece soporte<strong>de</strong> widgets y <strong>de</strong> mensajería entre navegadory servidor• Framework para crear widgets JavaScriptpropietarios• Librería <strong>de</strong> widgets preconstruidos• Soporte para mensajería browser-servidor• Soporte para manipular urls en el navegador• Es <strong>de</strong> código abierto• Open Rico (http://openrico.org/<strong>de</strong>mos.page)es otra posibilidad46


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo DOJO – Cliente


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks JavaScript Puras:Infraestructura• Sarissa (http://sarissa.sf.net) es una API JavaScript queencapsula la funcionalidad XML en llamadas in<strong>de</strong>pendientes <strong>de</strong>lnavegador• Creación <strong>de</strong>l objeto XMLHttpRequest portable• Consultas XPath portables• Manipulación DOM portable• XSLT portable• Serialización a XML portable• De código abierto• Artículo sobre Sarissa en:http://www.xml.com/lpt/a/2005/02/23/sarissa.html• Documentación <strong>de</strong> Sarissa enhttp://sarissa.sourceforge.net/doc/• Otras frameworks alternativas son: libXmlRequest e InteractiveWebsite Framework<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUsando Sarissa• Para obtener un objeto DOM en Sarissa haríamos:var oDomDoc = Sarissa.getDomDocument();• Para obtener el objeto XMLHttpRequest haríamos <strong>de</strong> manerasíncrona:var xmlhttp = new XMLHttpRequest();xmlhttp.open("GET","http://foo.org/someDocument.xml", false);xmlhttp.send(null);alert(Sarissa.serialize(xmlhttp.responseXML));• Y asíncrona:xmlhttp.onreadystatechange = function() {if(xmlhttp.readyState == 4)alert("Finished loading!");}48


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUsando Sarissa• Cargando un documento remoto:var oDomDoc = Sarissa.getDomDocument();oDomDoc.async = true; // this line can be ommited - true is the<strong>de</strong>fault// we add a listener for the load event to know when loading isfinishedfunction myHandler {if(oDomDoc.readyState == 4)alert(Sarissa.serialize(oDomDoc));// show the file contents};oDomDoc.onreadystatechange = myHandler;oDomDoc.load("someDocument.xml");• Creando un documento XML <strong>de</strong> un string:var oDomDoc = Sarissa.getDomDocument();var xmlString = "my xml!";oDomDoc = (new DOMParser()).parseFromString(xmlString, "text/xml");alert(Sarissa.serialize(oDomDoc));<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEUsando Sarissa• Como serializar un objeto no XML:// create an object hierarchybook.chapters = new Array();book.chapters[0] = "Kingdom of Tags";book.chapters[1] = "Fall";book.chapters[2] = "Final battle";book.chapters[3] = "Characters that need to be escaped:


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks JavaScript: ParteServidora Multilenguaje• S<strong>AJAX</strong> (http://www.mo<strong>de</strong>rnmethod.com/sajax/) rutea las llamadasdirectamente <strong>de</strong> JavaScript en tu lenguaje <strong>de</strong> back-end y viceversa• Pue<strong>de</strong>s llamar al método JavaScript “x_calculateBudget()” e invocará en elservidor el método Java calculateBudget() que <strong>de</strong>volverá el valor al métodojavascript x_calculateBudget_cb().• Facilita el mapeo <strong>de</strong> JavaScript a las operaciones <strong>de</strong>l back-end• Capaz <strong>de</strong> mapear las llamadas a diferentes plataformas servidoras:ASP/ColdFusion/Io/Lua/Perl/PHP/Python/Ruby.• Open-source• Ajax.Net (http://ajax.schwarzinteractive.<strong>de</strong>/csharpsample/<strong>de</strong>fault.aspx)es una librería que permiteel acceso <strong>de</strong>s<strong>de</strong> JavaScript a código servidor en .NET• Como S<strong>AJAX</strong> gestiona la invocación <strong>de</strong> peticiones en la parte servidora y lacomunicación <strong>de</strong> respuestas en la parte cliente• Pue<strong>de</strong> acce<strong>de</strong>r datos <strong>de</strong> sesión en JavaScript• Cachea resultados• Libre, código disponible, sin licencia especificada• Existe un excelente tutorial en:http://www.<strong>de</strong>veloperfusion.co.uk/show/4704/<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo S<strong>AJAX</strong>-PHPMultiplierfunction do_multiply_cb(z) {document.getElementById("z").value = z;}50


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo S<strong>AJAX</strong>-PHPfunction do_multiply() {var x, y;x = document.getElementById("x").value;y = document.getElementById("y").value;x_multiply(x, y, do_multiply_cb);}*=


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks JavaScript Puras:Parte Servidora Java• Direct Web Remoting (http://www.getahead.ltd.uk/dwr/) esuna framework para invocar a métodos Java <strong>de</strong>s<strong>de</strong> JavaScript• Similar a S<strong>AJAX</strong> pasa invocaciones <strong>de</strong> JavaScript a métodos Java y<strong>de</strong>vuelve las repuestas invocando callbacks JavaScript• Pue<strong>de</strong> utilizarse como una framework web - Struts, Tapestry, etc.• Sigue la filosofía <strong>de</strong> Spring (KISS/POJO/orthogonality).• Open-source• Echo 2 (http://www.nextapp.com/products/echo2/) permitecodigicar aplicaciones Ajax en Java• Tiene una <strong>de</strong>mo muy interesante enhttp://<strong>de</strong>mo.nextapp.com/InteractiveTest/ia• Genera automáticamente HTML y Javascript.• Co-ordina los mensajes XML entre navegador y servidor• Permite la creación <strong>de</strong> controles JavaScript• Open source<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEFrameworks JavaScript Puras:Parte Servidora PHP• AjaxAC (http://ajax.zervaas.com.au/)encapsula la aplicación en una clase PHP• Todo el código <strong>de</strong> la aplicación es autocontenidoen una clase que hace referencia al JavaScript y ala funcionalidad para manejar eventos JavaScript• Infraestructura para crear peticiones y manejarlas• Todos los eventos JavaScript son asignadosdinámicamente• Facilmente integrable con motores <strong>de</strong> templates• Estructura <strong>de</strong> widgets extensible52


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEGoogle Maps API• Disponible en la siguiente url:• http://www.google.com/apis/maps/• Es preciso registrarse y obtener unaclave <strong>de</strong> acceso<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo <strong>de</strong> Acceso a GoogleMapsGoogle Maps JavaScript API Example - simple//53


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDENuevas Aplicaciones <strong>AJAX</strong>• Equivalente web <strong>de</strong> Microsoft Office:• http://online.thinkfree.com – online office suite• Writely• Meebo.com – Instant messaging basado en <strong>AJAX</strong>• http://www.zimbra.com/ -- Groupware• Project Management --http://www.basecamphq.com/• Gestión <strong>de</strong> citas, calendario --http://www.calendarhub.com/• Openomy – online file system --http://www.iseff.com/2005/07/introducingopenomy.html<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDesarrollando un lector RSSen <strong>AJAX</strong>• Vamos a <strong>de</strong>finir un lector <strong>de</strong> noticias RSS, capaz <strong>de</strong> gestionar lasfuentes RSS• RSS es una familia <strong>de</strong> ficheros XML para la sindicación web usandowebs <strong>de</strong> noticas y weblogs.• Su nombre hace referencia a uno <strong>de</strong> los siguientes estándares:• Rich Site Summary (RSS 0.91)• RDF Site Summary (RSS 0.9, 1.0 and 1.1)• Really Simple Syndication (RSS 2.0)• RSS ofrece <strong>de</strong>scripciones breves <strong>de</strong> contenido web junto con enlaces alas versiones completas <strong>de</strong>l documento.• El fichero XML en el que se envía esta información es <strong>de</strong>nominado RSSfeed, webfeed, RSS stream, o RSS channel.• Gracias a RSS y con la ayuda <strong>de</strong> un news aggregator po<strong>de</strong>mosmonitorizar los cambios en el contendio <strong>de</strong> un portal que ofrecesindicación RSS.• http://blogs.law.harvard.edu/tech/rss#ltenclosuregtSubelementOfLtitemgt54


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo fichero RSS 2.0Ejemplo <strong>de</strong> canalhttp://example.com/Ejemplo <strong>de</strong> fuente RSSes1 &lt; 2http://example.com/1_less_than_2.html1 &lt; 2, 3 &lt; 4. En HTML, &lt;b&gt; comienza unafrase en negritay pue<strong>de</strong>s comenzar un enlace con &lt;a href=<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDesarrollando un lector RSSen <strong>AJAX</strong>55


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDesarrollando un lector RSSen <strong>AJAX</strong><strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDesarrollando un lector RSSen <strong>AJAX</strong>56


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEDesarrollando un lector RSSen <strong>AJAX</strong><strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEEjemplo Carrito <strong>de</strong> la Compra• Revisar ejemplo examples\ShoppingCart,compuesto por 2 paquetes, 1 jsp y 2 js:• Paquete <strong>de</strong>veloperworks.ajax.store,contiene las clases Cart, Catalog e Item• Paquete <strong>de</strong>veloperworks.ajax.servlet,contiene el servlet CartServlet• in<strong>de</strong>x.jsp – visualiza la página inicial• ajax1.js – contiene las funciones generalesmostradas en el artículo• cart.js – funciones específicas al ejemplo <strong>de</strong>lcarrito57


<strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEConclusión• <strong>AJAX</strong> es un nuevo enfoque <strong>de</strong> <strong>de</strong>sarrollo web quegarantiza una mayor interactividad y usabilidad <strong>de</strong>portales web• Su utilización por lí<strong>de</strong>res en la industria web comoGoogle o Yahoo, da una i<strong>de</strong>a <strong>de</strong> su potencial.• Incluso MicroSoft ya está pensando en añadir a ASP.NET 2.0un conjunto <strong>de</strong> controles basados en tecnología <strong>AJAX</strong>.• El <strong>de</strong>sarrollo web con <strong>AJAX</strong> no es trivial y difícil <strong>de</strong>hacer <strong>de</strong>bugging• Sin embargo, las frameworks que están emergiendosimplificarán el <strong>de</strong>sarrollo web basado en <strong>AJAX</strong><strong>Universidad</strong> <strong>de</strong> <strong>Deusto</strong>. . . .ESIDEReferencias• XMLHttpRequest –http://<strong>de</strong>veloper.apple.com/internet/webcontent/xmlhttpreq.html• Asynchronous JavaScript Technology and XML (<strong>AJAX</strong>) With Java 2 Platform, EnterpriseEditionhttp://java.sun.com/<strong>de</strong>veloper/technicalArticles/J2EE/<strong>AJAX</strong>/• HTML DOM – http://www.w3schools.com/htmldom/<strong>de</strong>fault.asp• Javascript – http://en.wikipedia.org/wiki/Javascript• Core JavaScript Reference –http://research.nihonsoft.org/javascript/CoreReferenceJS15/in<strong>de</strong>x.html• Mi página web – Curso <strong>AJAX</strong> –, http://paginaspersonales.<strong>de</strong>usto.es/dipina• Ajax for Java <strong>de</strong>velopers: Build dynamic Java applications – http://www-128.ibm.com/<strong>de</strong>veloperworks/library/j-ajax1/?ca=dgr-lnxw01Ajax• Web 2.0 http://www.web2con.com/• JavaScript XSLT --http://www.soi.city.ac.uk/~sa386/epterm2/sqlxml/week9/The%20XSLT-JavaScript%20Interface%20In%20Gecko.htm• <strong>AJAX</strong> gives software a fresh look –http://news.com.com/<strong>AJAX</strong>+gives+software+a+fresh+look/2100-1007_3-5886709.html?tag=st.prev58

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!