DLSI - Universidad de Alicante. 1. Departamento de Lenguajes y. Sistemas
Informáticos. Ajax Technology in Web. Programming. Sergio Luján Mora.
Ajax Technology in Web Programming. API for accessing and ... Document
Object Model Level 1 (Second Edition) (29/9/2000). – Level 2. • Document Object
...
when send returns, the fetched text will be stored in request's responseText ... most Ajax code uses an anonymous functi
AJAX TECHNOLOGY IN WEB PROGRAMMING. EXERCISES. JAVASCRIPT. 1.
Define a queue and stack using an array: Queue interface: Stack interface: TIPS:.
AJAX and GWT programming! In this book, we will start with downloading and
installing GWT and walk through the creation, testing, debugging, and
deployment ...
This paper presents Ur/Web, a domain-specific, statically typed functional ... tures
of Ur/Web and discuss the language implementation and the production Web ...
Jan 28, 2013 - News from ... Total average daily energy expenditure .... The modernized facility will generate enough re
As Technical Director for SitePoint, Kevin Yank oversees all of its technical
publica- ... Kevin lives in Melbourne, Australia, and enjoys performing improvised
...
Mar 13, 2009 ... For starting Ajax programming: Ajax for Dummies. ... If you have not downloaded
the example application and made its files available to your ...
Web 2.0 applications induce larger, heavier, and more bursty traffic on the un- derlying networks. .... lyzer of Bro [10
The development will create over 200 jobs, approximately 107 spin- ... program
at the McLean Community Centre) ... fun programming for children and youth.
Google Maps, modern Web-email, and social networking Web sites, and compare them with ... A good overview of the traditional Web is given in the book by Krishnamurthy and .... 1 We use server and host interchangeably in this discussion.
Jul 12, 2011 ... the optimal configuration of the web server according to the workload. ...... in
contrast to process-based web servers, nginx worker processes ...
18 Feb 2005 ... Sobre este libro... ▫ Los contenidos de este libro están bajo una licencia Creative
Commons Reconocimiento -. No Comercial - Sin Obra ...
The proposed model based for the first time to the best of our knowledge, the Hebbian trained ... web developer efforts will be reduced on white box testing type.
email: [email protected] .... and compose with other DAML-S compliant web services ... duces a HTML document corresponding to the com-. ponent's ...
less experienced programmers, it also makes reasoning about the behaviour of the complete ... application, we have casted Web Cube with Misra's Seuss [8].
We propose a new programming model for web applications which is (1) seamless; one program and one language is used to p
Colocation constraint enforced the deployment of redundant components into ... istically to hosts according to the connectivity the host provides, obtaining a ...
Nov 19, 2013 ... sources: Programming the World Wide Web, Sebesta, Ch 10, Addison-Wesley ....
Ajax server software components can also return. – XHTML.
Beginner (No Experience Required (Course ... (Course Technology)) Full eBook ... Developed by computer science instructo
With Asynchronous Javascript and XML (Ajax) programming, interac- tive web
forms ... Model-View-Controller (MVC) [13] is a design pattern commonly used for
.
be directly named, each sender in a network must know the name of the operation of the ..... Brinch Hansen, 1978] Per Brinch Hansen, \Distributed Processes: A ...
ies that involve measured settlements of shallow foundations. ... ize the learning and apply it to predict settlement of foundations for new cases not used in the ...
AJAX stands for Asynchronous JavaScript And XML (term ... JavaScript as a
programming language ... It is the heart of an AJAX application because it allows.
Ajax: A new programming model for the Web Juan M. Gimeno, Josep M. Rib´ o May, 2009
INDEX
Contents
1. Rich Internet Applications 2. AJAX Components 3. Example 1: AJAX Flow 4. Example 2: Modifications 5. DOM: Document Object Model 6. Example 3: Modifications Using DOM 7. Example 4: Autocomplete 8. Prototype: a JavaScript library for Ajax 9. Example 5: Prototype
1
INDEX
Two Splitted Worlds Rich Desktop Applications • • • •
Difficult to distribute and deploy Rich user experience Rapid response to the user Off-line
Classical Web Applications • • • •
Easy to distribute and deploy Poor user experience Delayed responses On-line Can we get the best of these two worlds?
2
INDEX
Rich Internet Applications • Rich user experience • Easy to distribute and deploy • Easy to actualize • Rich user experience • Rapid response to the user • Can work off-line • Multiplatform
3
INDEX
Adobe Flash
RIA Platforms
• Was the creator of the RIA concept • More oriented to graphical designers than to developers Adobe Flex • Based on flash but oriented to developers • XML (MXML) + Action Script 3.0 Open Laszlo • XML (LZX) + ECMAScript • Compiles into Flash or AJAX Microsoft Silverlight • XML (XAML) + .NET (web version of WPF: Windows Presentation Foundation) Java Web Start • Autodeployable and updatable applications JavaFX ???? • JavaFX Script • JavaFX Mobile AJAX 4
INDEX
AJAX • Based on standards and not owned by any company • AJAX stands for Asynchronous JavaScript And XML (term coined by Jesse James Garret in a famous article) • AJAX is not new but it was not popular until Google used it into its products • Based on the XMLHTTP object introduced in IE5.0 (1999) to allow remote scripting of Outlook Web Access • All browsers have included their own version of the XMLHTTP object • Technologies in AJAX: – (X)HTML and CSS for structure and design – JavaScript as a programming language – DOM (Document Object Model) to dynamically modify the structure – XML as a data transport language between client and server (but it can use others such as JSON)
XMLHTTP Object • History: – 1998, Microsoft presents Remote Scripting to allow, by means of an applet, make requests from JS without the user noticing it – 1999, IE5.0 incorporates, under ActiveX, the XMLHTTP object that replaces the applet – 5 years later, and driven by Google, used to create rich webweb applications • Compatibility: – As an ActiveX XMLHTTP object in IE from 5 up to 7 – As a native JS XMLHttpRequest object in Firefox (≥ 1.0), Netscape (≥ 7.1), Opera (≥ 8.0), Safari (≥ 1.2), IE 7, Konqueror, Opera Mobile, Nokia Web Browser, ... • It is the heart of an AJAX application because it allows to asynchronically make requests to the server without changing the page
8
INDEX
Using the XMLHTTP Object To make a request to the server from JavaScript using the XMLHTTP Object, one must follow these steps: 1. Obtain the XMLHTTP object 2. Configure and open the connection with the server 3. Define a JavaScript callback function to administer the evolution of the request (because it is asynchronous) 4. Send the request and data to the server 5. The before mentioned function must: • Administer the state of the request • Get the result from the server • Process the result (i.e. updating the page)
9
INDEX
Obtaining the XMLHTTP object 1 f u n c t i o n getXHR ( ) { 2 req = false ; 3 i f ( window . XMLHttpRequest ) { 4 r e q = new XMLHttpRequest ( ) ; 5 } else { 6 i f ( ActiveXObject ) { 7 m s V e r s i o n s = [ ”MSXML2 . XMLHttp5 . 0 ” , ”MSXML2 . XMLHttp4 . 0 ” , 8 ”MSXML2 . XMLHttp3 . 0 ” , ”MSXML2 . XMLHttp ” , 9 ” M i c r o s o f t . XMLHttp” ] ; 10 f o r ( v a r i =0; i var xhr ; f u n c t i o n modifyPage ( ) { . . . } C l i c k Me
15
INDEX
Example1: JavaScript Code 1 var xhr ; 2 function modifyPage ( ) { 3 try { 4 x h r = new A c t i v e X O b j e c t ( ” Msxml2 .XMLHTTP” ) ; 5 a l e r t ( ” Msxml2 .XMLHTTP A c t i v e X O b j e c t c r e a t e d ” ) ; 6 } catch ( e ) { 7 try { 8 x h r = new A c t i v e X O b j e c t ( ” M i c r o s o f t .XMLHTTP” ) ; 9 a l e r t ( ” M i c r o s o f t .XMLHTTP A c t i v e X O b j e c t c r e a t e d ” ) ; 10 } catch ( E ) { 11 xhr = f a l s e ; 12 } 13 } 14 i f ( ! x h r && t y p e o f XMLHttpRequest != ’ u n d e f i n e d ’ ) { 15 x h r = new XMLHttpRequest ( ) ; 16 a l e r t ( ” XMLHttpRequest O b j e c t c r e a t e d ” ) ; 17 } 18 x h r . open ( ”GET” , ” . / g e t M e s s a g e ” , ” t r u e ” ) ; 19 a l e r t ( ” Open method c a l l e d ” ) ; 20 x h r . s e t R e q u e s t H e a d e r ( ” User −Agent ” , ”my b r o w s e r ” ) ; 21 a l e r t (” Request header s e t t e d ” ) ; 22 xhr . onreadystatechange = function () { 23 a l e r t ( ” S t a t e : ” + x h r . r e a d y S t a t e + ”” ) ; 24 i f ( x h r . r e a d y S t a t e != 4 ) r e t u r n ; 25 i f ( x h r . s t a t u s == 2 0 0 ) { 26 a l e r t ( ” The message i s : \ n” + x h r . r e s p o n s e T e x t ) ; 27 } else 28 a l e r t ( ” E r r o r p r o c e s s i n g r e s p o n s e . S t a t u s =” + x h r . s t a t u s ) ; 29 } 30 xhr . send ( n u l l ) ; 31 }
package a j a x i a n . book . e x p l a i n e d . s e r v l e t ; import j a v a . i o . ∗ ; import j a v a x . s e r v l e t . ∗ ; import j a v a x . s e r v l e t . h t t p . ∗ ; p u b l i c c l a s s M e s s a g e S e r v l e t extends H t t p S e r v l e t { @Override p u b l i c v o i d doGet ( H t t p S e r v l e t R e q u e s t r e q u e s t , HttpServletResponse response ) throws I O E x c e p t i o n , S e r v l e t E x c e p t i o n { response . setContentType ( ” t e x t / p l a i n ” ) ; r e s p o n s e . s e t H e a d e r ( ” Cache−C o n t r o l ” , ”no−c a c h e ” ) ; r e s p o n s e . g e t W r i t e r ( ) . w r i t e ( ” H e l l o from t h e s e r v e r ” ) ;
} } 17
INDEX
Accessing and modifying the page • In the past example we have only shown alerts but we have not accessed the page content. • Usually AJAX applications modify the current content of the page with the response obtained from the server. • To do so, we need: 1. parts of the page (tipically a
) must be uniquely identifiable (using its id attribute’s value). 2. to modify the content we can use the innerHTML property of the element (simpler than pure DOM nodes manipulation) 3. the AJAX request must be sent when we are sure the
) is loaded. If one wants the request to be done when the page is being loaded, one must use the onload method of the body. 4. the XMLHTTP object must be a global variable of the page, so it can be accessed from different functions.
< s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” x h r . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ”>\ b e g i n { l s t l i s t i n g } [ l a n g u a g e=J a v a S c r i p t , n var xhr ; f u n c t i o n modifyPage ( ) { x h r = getXHR ( ) ; x h r . open ( ”GET” , ” . / g e t M e s s a g e ” , ” t r u e ” ) ; x h r . s e t R e q u e s t H e a d e r ( ” User −Agent ” , ”my b r o w s e r ” ) ; x h r . o n r e a d y s t a t e c h a n g e= f u n c t i o n ( ) { i f ( x h r . r e a d y S t a t e != 4 ) r e t u r n ; i f ( x h r . s t a t u s == 2 0 0 ) { document . g e t E l e m e n t B y I d ( ” message ” ) . innerHTML = x h r . r e s p o n s e T e x t ; } else { a l e r t ( ” Error p r o c e s s i n g response with s t a t u s ” + xhr . s t a t u s ) ; } } xhr . send ( n u l l ) ; } C l i c k Me
19
INDEX
DOM: Document Object Model
• DOM is a W3C standard that allows the processing of XML documents (HTML is not XML but DOM is also ported to it) • It defines common interfaces to traverse and manipulate a hierarchical representation of the HTML/XML • Implemented in different languages: Java, JavaScript, Python, PHP, ... • In JavaScript we can use the DOM to: – Manipulate the results obtained from the server (if they are expressed in XML) – Manipulate the page by accessing the object window.document (or simply document)
< s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” x h r . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” t e x t − u t i l s . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ”> var xhr ; f u n c t i o n modifyPage ( ) { x h r = getXHR ( ) ; x h r . open ( ”GET” , ” . / g e t M e s s a g e ” , ” t r u e ” ) ; x h r . s e t R e q u e s t H e a d e r ( ” User −Agent ” , ”my b r o w s e r ” ) ; x h r . o n r e a d y s t a t e c h a n g e= f u n c t i o n ( ) { i f ( x h r . r e a d y S t a t e != 4 ) r e t u r n ; i f ( x h r . s t a t u s == 2 0 0 ) { r e p l a c e T e x t ( document . g e t E l e m e n t B y I d ( ” message ” ) , x h r . r e s p o n s e T e x t ) ; } else { a l e r t ( ” Error p r o c e s s i n g response with s t a t u s ” + xhr . s t a t u s ) ; } } xhr . send ( n u l l ) ; } C l i c k Me
function replaceText ( el , text ) { i f ( e l != n u l l ) { clearText ( el ); v a r newNode = document . c r e a t e T e x t N o d e ( t e x t ) ; e l . a p p e n d C h i l d ( newNode ) ; } } function clearText ( e l ) { i f ( e l != n u l l ) { i f ( el . childNodes ) { f o r ( v ar i =0; e l . c h i l d N o d e s . l e n g t h ; i ++) { v ar c h i l d N o d e = e l . c h i l d N o d e s [ i ] ; e l . removeChild ( childNode ) ; } } } } function getText ( e l ) { var t e x t = ” ” ; i f ( e l != n u l l ) { i f ( el . childNodes ) { f o r ( v ar i = 0 ; e l . c h i l d N o d e s . l e n g t h ; i ++) { v ar c h i l d N o d e = e l . c h i l d N o d e s [ i ] ; i f ( c h i l d N o d e . n o d e V a l u e != n u l l ) { t e x t = t e x t + childNode . nodeValue ; } } } } }
22
INDEX
Example: Autocomplete
• An example based (minor modifications) on the J2EE Blueprints Samples from Sun. • When filling a text entry, generates a pop-up with possible completions for the already entered characters • Hands-on-project: modify the example to allow the selection of a name by keyboard and not by mouse.
< s t y l e type=” t e x t / c s s ”> . selected { b a c k g r o u n d : #7A8AFF ; c o l o r : #FFFAFA ; }
var var var var
. unselected { b a c k g r o u n d : #FFFAFA ; c o l o r : #000000; } < s c r i p t type=” t e x t / j a v a s c r i p t ”> isIE ; req ; names ; target ;
f u n c t i o n g e t E l e m e n t X ( e l e m e n t ){ var t a r g e t L e f t = 0 ; i f ( element . o f f s e t P a r e n t ) {
while ( element . o f f s e t P a r e n t ) { t a r g e t L e f t += e l e m e n t . o f f s e t L e f t ; element = element . o f f s e t P a r e n t ; } } else i f ( element . x ) { t a r g e t L e f t += e l e m e n t . x ; } return t a r g e t L e f t ;
} f u n c t i o n g e t E l e m e n t Y ( e l e m e n t ){ var targetTop = 0 ; i f ( element . o f f s e t P a r e n t ) { while ( element . o f f s e t P a r e n t ) { t a r g e t T o p += e l e m e n t . o f f s e t T o p ; element = element . o f f s e t P a r e n t ; } } else i f ( element . y ) { t a r g e t T o p += e l e m e n t . y ; } return targetTop ; } function i n i t () { t a r g e t = document . g e t E l e m e n t B y I d ( ” c o m p l e t e − f i e l d ” ) ; v a r popup = document . g e t E l e m e n t B y I d ( ” menu−popup ” ) ; popup . s t y l e . t o p = ( g e t E l e m e n t Y ( t a r g e t ) + t a r g e t . o f f s e t H e i g h t ) + ” px ” ; popup . s t y l e . l e f t = g e t E l e m e n t X ( t a r g e t ) + ” px ” ; }
function i n i t R e q u e s t ( u r l ) { i f ( window . XMLHttpRequest ) { r e q = new XMLHttpRequest ( ) ; } e l s e i f ( window . A c t i v e X O b j e c t ) { i s I E = true ; r e q = new A c t i v e X O b j e c t ( ” M i c r o s o f t .XMLHTTP” ) ; } } function doCompletion () { v a r u r l = ” a u t o c o m p l e t e ? a c t i o n=c o m p l e t e&i d =” + e s c a p e ( t a r g e t . v a l u e ) ; initRequest ( url ); req . onreadystatechange = processRequest ; r e q . open ( ”GET” , u r l , t r u e ) ; req . send ( n u l l ) ; } function processRequest () { i f ( r e q . r e a d y S t a t e == 4 ) { i f ( r e q . s t a t u s == 2 0 0 ) { parseMessages ( ) ; } e l s e i f ( r e q . s t a t u s == 204) { clearTable (); } } } function parseMessages () { i f ( ! names ) { names = document . g e t E l e m e n t B y I d ( ” names ” ) ;
} clearTable (); v a r e m p l o y e e s = r e q . responseXML . getElementsByTagName ( ” e m p l o y e e s ” ) [ 0 ] ; f o r ( l o o p = 0 ; l o o p < e m p l o y e e s . c h i l d N o d e s . l e n g t h ; l o o p++) { var employee = employees . c h i l d N o d e s [ loop ] ; v a r f i r s t N a m e = e m p l o y e e . getElementsByTagName ( ” f i r s t N a m e ” ) [ 0 ] ; v a r l a s t N a m e = e m p l o y e e . getElementsByTagName ( ” l a s t N a m e ” ) [ 0 ] ; v a r e m p l o y e e I d = e m p l o y e e . getElementsByTagName ( ” i d ” ) [ 0 ] ; appendEmployee ( f i r s t N a m e . c h i l d N o d e s [ 0 ] . nodeValue , l a s t N a m e . c h i l d N o d e s [ 0 ] . nodeValue , employeeId . childNodes [ 0 ] . nodeValue ) ; } } function clearTable () { i f ( names ) { f o r ( l o o p = names . c h i l d N o d e s . l e n g t h −1; l o o p >= 0 ; l o o p −−) { names . r e m o v e C h i l d ( names . c h i l d N o d e s [ l o o p ] ) ; } } } f u n c t i o n appendEmployee ( f i r s t N a m e , lastName , e m p l o y e e I d ) { var f i r s t N a m e C e l l ; var l a s t N a m e C e l l ; if ( isIE ) { row = names . i n s e r t R o w ( names . rows . l e n g t h ) ; n a m e C e l l = row . i n s e r t C e l l ( 0 ) ; } else { row = document . c r e a t e E l e m e n t ( ” t r ” ) ;
n a m e C e l l = document . c r e a t e E l e m e n t ( ” t d ” ) ; row . a p p e n d C h i l d ( n a m e C e l l ) ; names . a p p e n d C h i l d ( row ) ;
} row . s e t A t t r i b u t e ( ” b o r d e r ” , ” 0 ” ) ; n a m e C e l l . s e t A t t r i b u t e ( ” onmouseout ” , ” t h i s . c l a s s N a m e =’ u n s e l e c t e d ’ ; ” ) ; n a m e C e l l . s e t A t t r i b u t e ( ” onmouseover ” , ” t h i s . c l a s s N a m e =’ s e l e c t e d ’ ; ” ) ; n a m e C e l l . s e t A t t r i b u t e ( ” b g c o l o r ” , ”#FFFAFA ” ) ; nameCell . s e t A t t r i b u t e (” border ” , ” 0 ” ) ; v a r l i n k E l e m e n t = document . c r e a t e E l e m e n t ( ” a ” ) ; l i n k E l e m e n t . s e t A t t r i b u t e ( ” s t y l e ” , ” t e x t −d e c o r a t i o n : none ” ) ; l i n k E l e m e n t . s e t A t t r i b u t e ( ” h r e f ” , ” a u t o c o m p l e t e ? a c t i o n=l o o k u p&i d =” + e m p l o y e e I d ) ; v a r nameFontElement = document . c r e a t e E l e m e n t ( ” f o n t ” ) ; nameFontElement . s e t A t t r i b u t e ( ” s i z e ” , ”+1”); nameFontElement . s e t A t t r i b u t e ( ” c o l o r ” , ” b l a c k ” ) ; nameFontElement . a p p e n d C h i l d ( document . c r e a t e T e x t N o d e ( f i r s t N a m e + ” ” + l a s t N a m e ) ) ; l i n k E l e m e n t . a p p e n d C h i l d ( nameFontElement ) ; nameCell . appendChild ( linkElement ) ; < t i t l e>Auto−C o m p l e t i o n u s i n g A s y n c h r o n o u s J a v a S c r i p t and XML (AJAX)
Auto−C o m p l e t i o n u s i n g A s y n c h r o n o u s J a v a S c r i p t and XML (AJAX)
T h i s e x a m p l e shows how you can do r e a l t i m e auto−c o m p l e t i o n u s i n g AJAX i n t e r a c t i o n s .
I n t h e form b e l o w e n t e r a name . P o s s i b l e names t h a t w i l l be c o m p l e t e d a r e d i s p l a y e d b e n e a t h t h e form . C l i c k on one o f t h e s e l e c t i o n s t o s e e t h e e m p l o y e e d e t a i l s . Try t y p i n g &q u o t ; Greg&q u o t ; , &q u o t ; Murray&q u o t ; , &q u o t ; J o n e s&q u o t ; , o r &q u o t ; C i n d y&q u o t ; .
package com . sun . j 2 e e . b l u e p r i n t s . b p c a t a l o g . a j a x ; import import import import
java . io .∗; javax . s e r v l e t .∗; javax . s e r v l e t . http .∗; java . u t i l .∗;
p u b l i c c l a s s A u t o c o m p l e t e S e r v l e t extends H t t p S e r v l e t { private ServletContext context ; p r i v a t e HashMap e m p l o y e e s = new HashMap ( ) ; p u b l i c v o i d i n i t ( S e r v l e t C o n f i g c o n f i g ) throws S e r v l e t E x c e p t i o n { this . context = config . getServletContext ( ) ; e m p l o y e e s . p u t ( ”1” , new EmployeeBean ( ”1” , ” Greg ” , ” Murray ” ) ) ; e m p l o y e e s . p u t ( ”2” , new EmployeeBean ( ”2” , ” Greg ” , ” Murphy ” ) ) ; e m p l o y e e s . p u t ( ”3” , new EmployeeBean ( ”3” , ” Ge or ge ” , ” Murphy ” ) ) ; e m p l o y e e s . p u t ( ”4” , new EmployeeBean ( ”4” , ” Ge or ge ” , ” Murray ” ) ) ; e m p l o y e e s . p u t ( ”5” , new EmployeeBean ( ”5” , ” P e t e r ” , ” J o n e s ” ) ) ; e m p l o y e e s . p u t ( ”6” , new EmployeeBean ( ”6” , ”Amber” , ” J o n e s ” ) ) ; e m p l o y e e s . p u t ( ”7” , new EmployeeBean ( ”7” , ”Amy” , ” J o n e s ” ) ) ; e m p l o y e e s . p u t ( ”8” , new EmployeeBean ( ”8” , ” Bee ” , ” J o n e s ” ) ) ; e m p l o y e e s . p u t ( ”9” , new EmployeeBean ( ”9” , ” Beth ” , ” Johnson ” ) ) ;
e m p l o y e e s . p u t ( ” 10 ” , new EmployeeBean ( ” 10 ” , ” C i n d y ” , ” Johnson ” ) ) ; e m p l o y e e s . p u t ( ” 11 ” , new EmployeeBean ( ” 11 ” , ” C i n d y ” , ” Murphy ” ) ) ; e m p l o y e e s . p u t ( ” 12 ” , new EmployeeBean ( ” 12 ” , ”Duke” , ” Hazerd ” ) ) ;
} p u b l i c v o i d doGet ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) throws I O E x c e p t i o n , S e r v l e t E x c e p t i o n { String action = request . getParameter ( ” action ” ) ; String t a r g e t I d = request . getParameter (” id ” ) ; S t r i n g B u f f e r sb = new S t r i n g B u f f e r ( ) ; i f ( t a r g e t I d != n u l l ) { t a r g e t I d = t a r g e t I d . trim ( ) . toLowerCase ( ) ; } boolean namesAdded = f a l s e ; i f ( ” complete ” . equals ( action )) { I t e r a t o r i t = employees . keySet ( ) . i t e r a t o r ( ) ; while ( i t . hasNext ( ) ) { String id = ( String ) i t . next ( ) ; EmployeeBean e = ( EmployeeBean ) e m p l o y e e s . g e t ( i d ) ; // s i m p l e matching o n l y f o r s t a r t o f f i r s t or l a s t name i f ( ( e . getFirstName ( ) . toLowerCase ( ) . s t a r t s W i t h ( t a r g e t I d ) | | e . getLastName ( ) . t o L o w e r C a s e ( ) . s t a r t s W i t h ( t a r g e t I d ) ) && ! t a r g e t I d . e q u a l s ( ”” ) ) { sb . append ( ”” ) ; sb . append ( ”” + e . g e t I d ( ) + ”” ) ; sb . append ( ”” + e . g e t F i r s t N a m e ( ) + ”” ) ; sb . append ( ”” + e . getLastName ( ) + ”” ) ; sb . append ( ”” ) ; namesAdded = t r u e ;
} } i f ( namesAdded ) { r e s p o n s e . s e t C o n t e n t T y p e ( ” t e x t / xml ” ) ; r e s p o n s e . s e t H e a d e r ( ” Cache−C o n t r o l ” , ”no−c a c h e ” ) ; r e s p o n s e . g e t W r i t e r ( ) . w r i t e ( ”” + sb . t o S t r i n g ( ) + ”” ) ; } else { // n o t h i n g t o show r e s p o n s e . s e t S t a t u s ( H t t p S e r v l e t R e s p o n s e . SC\ NO\ CONTENT ) ; } } i f ( ” lookupbyname ” . e q u a l s ( a c t i o n ) ) { I t e r a t o r i t = employees . keySet ( ) . i t e r a t o r ( ) ; A r r a y L i s t names = new A r r a y L i s t ( ) ; while ( i t . hasNext ( ) ) { String id = ( String ) i t . next ( ) ; EmployeeBean e = ( EmployeeBean ) e m p l o y e e s . g e t ( i d ) ; // s i m p l e matching o n l y f o r s t a r t o f f i r s t or l a s t name i f ( e . getFirstName ( ) . toLowerCase ( ) . s t a r t s W i t h ( t a r g e t I d ) | | e . getLastName ( ) . t o L o w e r C a s e ( ) . s t a r t s W i t h ( t a r g e t I d ) ) { names . add ( e ) ; } } i f ( names . s i z e ( ) > 0 ) { r e q u e s t . s e t A t t r i b u t e ( ” e m p l o y e e s ” , names ) ; } c o n t e x t . g e t R e q u e s t D i s p a t c h e r ( ”/ e m p l o y e e s . j s p ” ) . f o r w a r d ( r e q u e s t , r e s p o n s e ) ; } else i f (” lookup ” . equals ( action )) { // p u t t h e t a r g e t employee i n t h e r e q e u s t s c o p e t o d i s p l a y i f ( ( t a r g e t I d != n u l l ) && e m p l o y e e s . c o n t a i n s K e y ( t a r g e t I d . t r i m ( ) ) ) {
33
INDEX 84 85 86 87 88 89 90 91 }
r e q u e s t . s e t A t t r i b u t e ( ” employee ” , employees . get ( t a r g e t I d ) ) ; c o n t e x t . g e t R e q u e s t D i s p a t c h e r ( ”/ e m p l o y e e . j s p ” ) . f o r w a r d ( r e q u e s t , r e s p o n s e ) ; } else { c o n t e x t . g e t R e q u e s t D i s p a t c h e r ( ”/ e r r o r . j s p ” ) . f o r w a r d ( r e q u e s t , r e s p o n s e ) ; }
} }
34
INDEX
Example: Autocomplete
employees.jsp 1 2 3 4 5 6 7
S e a r c h R e s u l t s
8 9 10 11 12
U n a b l e t o l o c a t e any e m p l o y e e s .
• Trying to program in JavaScript without any library is almost suicidal – There are subtle differences among the implementations of JS in the different browsers – Programming in JavaScript is tricky (e.g. it has objects but no classes nor inheritance) – (the language has some flaws but it was a ”hack that got shipped”) • Prototype is a fairly broad library that u ¨pgrades”the language – makes common tasks easier (mainly Ajax oriented) – provides ways to implement Java-style inheritance – extends HTML DOM elements with new properties and methods – provides utilities for working with JSON (Java Script Object Notation)
37
INDEX
Example: The MyTunes Application
index.html 1 2 3 4 < t i t l e>MyTunes L i b r a r y 5 < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” j s / p r o t o t y p e . j s ”> 6 < s c r i p t type=” t e x t / j a v a s c r i p t ”> 7 f u n c t i o n loadTunes () { 8 new A j a x . U p d a t e r ( ’ tunesBox ’ , ’ l i s t . j s p ’ , { method : ’ get ’ } ) ; 9 } 10 11 < l i n k r e l=” s t y l e s h e e t ” h r e f=” c s s / t u n e s . c s s ” type=” t e x t / c s s ”/> 12 13 14 MyTunes 15 16 17 18 19
< !DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 T r a n s i t i o n a l //EN” ” h t t p : / /www. w3 . o r g /TR/ html4 / l o o s e . d t d ”> < t i t l e> E d i t a Song < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” j s / p r o t o t y p e . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” j s / e d i t o r . j s ”> < l i n k r e l=” s t y l e s h e e t ” h r e f=” c s s / t u n e s . c s s ”/> E d i t Song Name : ? A r t i s t : ? Album : ? Genre : ?
// g l o b a l u s e d t o k e e p t r a c k o f what ’ s c u r r e n t l y b e i n g e d i t e d var c u r r e n t E l e m e n t = n u l l ; function loadSong (){ params = window . l o c a t i o n . s e a r c h . p a r s e Q u e r y ( ) ; v a r i d = params [ ” i d ” ] ; // c r e a t e h a n d l e r t h a t w i l l be i n v o k e d // when r e s p o n s e i s r e c e i v e d from s e r v e r v a r h a n d l e r = f u n c t i o n ( x h r ){ // u s e responseJSON p r o p e r t y added by P r o t o t y p e v ar j s o n = x h r . responseJSON ; // c h e c k f o r e r r o r i f ( j s o n . e r r o r ){ // d i s p l a y t h e e r r o r } v ar song = j s o n . song ; // c l e a r t h e s p i n n e r // u s e P r o t o t y p e ’ s $ ( ) s h o r t c u t n o t a t i o n $ ( ” s p i n n e r ” ) . innerHTML = ” ” ; // s e t t h e d i s p l a y d a t a $ ( ” i d ” ) . v a l u e = song . i d ; $ ( ” t i t l e ” ) . innerHTML = song . t i t l e ; $ ( ” a r t i s t ” ) . innerHTML = song . a r t i s t ; $ ( ” album ” ) . innerHTML = song . album ; $ ( ” g e n r e ” ) . innerHTML = song . g e n r e ; $ ( ” y e a r ” ) . innerHTML = song . y e a r ; }; // c r e a t e o p t i o n s f o r var o p t i o n s = { method : ” g e t ” , onSuccess : handler , parameters : { ” id ” : id } }; // s e n d t h e r e q u e s t new A j a x . R e q u e s t ( ” S o n g S e r v l e t ” , o p t i o n s ) ;
}
42
INDEX
Example: The MyTunes Application
SongServlet.java 1 p u b l i c c l a s s S o n g S e r v l e t extends H t t p S e r v l e t { 2 3 protected void p r o c e s s R e q u e s t ( H t t p S e r v l e t R e q u e s t request , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) 4 throws S e r v l e t E x c e p t i o n , I O E x c e p t i o n { 5 response . setContentType ( ” a p p l i c a t i o n / json ” ) ; 6 P r i n t W r i t e r out = r e s p o n s e . g e t W r i t e r ( ) ; 7 try { 8 S t r i n g message = ”” ; 9 JSONObject r e s p = new JSONObject ( ) ; 10 try { 11 C o n t e x t i n i t C o n t e x t = new I n i t i a l C o n t e x t ( ) ; 12 C o n t e x t e n v C o n t e x t = ( C o n t e x t ) i n i t C o n t e x t . l o o k u p ( ” j a v a : / comp/ env ” ) ; 13 D a t a S o u r c e ds = ( D a t a S o u r c e ) e n v C o n t e x t . l o o k u p ( ” j d b c /MyTunesDS” ) ; 14 C o n n e c t i o n conn = ds . g e t C o n n e c t i o n ( ) ; 15 S t a t e m e n t stmt = conn . c r e a t e S t a t e m e n t ( ) ; 16 R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ”SELECT ∗ FROM Songs WHERE i d=” + 17 request . getParameter ( ” id ” ) ) ; 18 i f ( rs . next ()) { 19 JSONObject song = new JSONObject ( ) ; 20 S t r i n g [ ] a t t r s = { ” i d ” , ” t i t l e ” , ” a r t i s t ” , ” album ” , ” g e n r e ” , ” y e a r ” } ; 21 for ( String attr : a t t r s ) { 22 song . p u t ( a t t r , r s . g e t S t r i n g ( a t t r ) ) ; 23 }
} } catch ( JSONException ex ) { L o g g e r . g e t L o g g e r ( S o n g S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , message= ” Problema amb e l JSON” ; } catch ( SQLException ex ) { L o g g e r . g e t L o g g e r ( S o n g S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , message = ” Problema amb l a BD” ; } catch ( N a m i n g E x c e p t i o n ex ) { L o g g e r . g e t L o g g e r ( S o n g S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , message = ” Problema amb JNDI” ; } r e s p . p u t ( ” e r r o r ” , message ) ; out . w r i t e ( r e s p . t o S t r i n g ( ) ) ; } catch ( JSONException ex ) { L o g g e r . g e t L o g g e r ( S o n g S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , n u l l // D e s e s p e r a t e d w i t h cached e x c e p t i o n s ; − ) } finally { out . c l o s e ( ) ; }
f u n c t i o n e d i t ( elem ) { v a r i d = elem . i d ; // D i s a b l e o n c l i c k when e d i t i n g elem . o n c l i c k = ” ” ; v a r s t r = c r e a t e E d i t o r ( i d , elem . innerHTML ) ; // Re−e n a b l i n g i t elem . o n c l i c k = ” e d i t ( t h i s ) ” ; elem . innerHTML = s t r ; c u r r e n t E l e m e n t = $ ( ” s o n g ”+ i d ) ; $ ( ” s o n g ”+ i d ) . f o c u s ( ) ; } f u n c t i o n c r e a t e E d i t o r ( name , v a l u e ) { v a r s t r = ”< i n p u t o n k e y p r e s s =\”c a t c h S u b m i t ( e v e n t ) \ ” o n B l u r=\”makeText ( t h i s ) \ ” t y p e =\” t e x t \ ” name= \ ””; s t r += name ; s t r += ” \ ” v a l u e = \ ””; s t r += v a l u e ; s t r += ” \ ” i d =\” s o n g ” ; s t r += name ; s t r += ” \ ”/ > ”; return s t r ; } f u n c t i o n c r e a t e S p a n ( name , v a l u e ) { v a r s t r = ”< s pa n o n C l i c k =\” e d i t ( t h i s ) \ ” i d = \ ””; s t r += name ; s t r += ” \ ” > ”; s t r += v a l u e ; s t r += ” ”; return s t r ; }
f u n c t i o n makeText ( i n p u t ) { // s a v e r e c o r d v a r formData = $ ( ” songForm ” ) . s e r i a l i z e ( t r u e ) ; s a v e D a t a ( formData ) ; // go back t o d i s p l a y i n p u t . p a r e n t N o d e . innerHTML = i n p u t . v a l u e ; } f u n c t i o n s a v e D a t a ( song ) { v a r h a n d l e r = f u n c t i o n ( x h r ){ v ar j s o n = x h r . responseJSON ; i f ( j s o n . e r r o r ){ // d i s p l a y t h e e r r o r } }; var o p t i o n s = { method : ” p o s t ” , onSuccess : handler , p a r a m e t e r s : song }; new A j a x . R e q u e s t ( ” U p d a t e S e r v l e t ” , o p t i o n s ) ; } f u n c t i o n c a t c h S u b m i t ( e v e n t ){ // KEY RETURN i s a f i e l d added t o t h e E v e n t c l a s s by P r o t o t y p e i f ( e v e n t . keyCode == E v e n t . KEY RETURN) { makeText ( c u r r e n t E l e m e n t ) ; } }
46
INDEX
Example: The MyTunes Application
SongServlet.java 1 p u b l i c c l a s s U p d a t e S e r v l e t extends H t t p S e r v l e t { 2 3 protected void p r o c e s s R e q u e s t ( H t t p S e r v l e t R e q u e s t request , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) 4 throws S e r v l e t E x c e p t i o n , I O E x c e p t i o n { 5 response . setContentType ( ” a p p l i c a t i o n / json ” ) ; 6 P r i n t W r i t e r out = r e s p o n s e . g e t W r i t e r ( ) ; 7 S t r i n g c l a u s e = ”” ; 8 S t r i n g message = ”” ; 9 try { 10 C o n t e x t i n i t C o n t e x t = new I n i t i a l C o n t e x t ( ) ; 11 C o n t e x t e n v C o n t e x t = ( C o n t e x t ) i n i t C o n t e x t . l o o k u p ( ” j a v a : / comp/ env ” ) ; 12 D a t a S o u r c e ds = ( D a t a S o u r c e ) e n v C o n t e x t . l o o k u p ( ” j d b c /MyTunesDS” ) ; 13 C o n n e c t i o n conn = ds . g e t C o n n e c t i o n ( ) ; 14 S t a t e m e n t stmt = conn . c r e a t e S t a t e m e n t ( ) ; 15 f o r ( E n u m e r a t i o n k e y s = r e q u e s t . getParameterNames ( ) ; k e y s . h a s M o r e E l e m e n t s ( ) ; ) { 16 S t r i n g key = ( S t r i n g ) keys . nextElement ( ) ; 17 i f ( ! key . e q u a l s ( ” i d ” ) ) { 18 S t r i n g v a l u e = r e q u e s t . getParameter ( key ) ; 19 c l a u s e = c l a u s e + k e y + ”=’” + v a l u e + ” ’ ” ; 20 } 21 } 22 stmt . e x e c u t e U p d a t e ( ”UPDATE Songs SET ” + c l a u s e + ”WHERE i d=” + r e q u e s t . g e t P a r a m e t e r ( ” i d ” ) ) ; 23 } catch ( SQLException ex ) {
47
INDEX 24 25 26 27 28 29 30 31 32 33 34 35 } ;
L o g g e r . g e t L o g g e r ( U p d a t e S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , n u l l , ex ) ; message = ex . t o S t r i n g ( ) ; } catch ( N a m i n g E x c e p t i o n ex ) { L o g g e r . g e t L o g g e r ( U p d a t e S e r v l e t . c l a s s . getName ( ) ) . l o g ( L e v e l . SEVERE , n u l l , ex ) ; message = ex . t o S t r i n g ( ) ; } finally { o u t . w r i t e ( ” {\” e r r o r \ ” : ” + message + ” } ” ) ; }
} // . . .
48
INDEX
As to conclude
• This has been a very rushy introductuon to Ajax • Like it or not, JavaScript is one of the languages of the futureˆHHHHHHpresent • Raw JavaScript is not enought: use at least prototype • (X)HTML + CSS + JS + ¿Prototype? is a MUST • To explore: GWT (Google Web Toolkit) does Ajax from Java