SlideShare una empresa de Scribd logo
1 de 84
Descargar para leer sin conexión
Ajax on Struts:
Coding an Ajax Application with Struts 2
 Wednesday, October 1st, 2:35p-3:35p
             Ted Husted
 In this session, we explore
     How to integrate an Ajax UI framework with a
     Struts 2 business framework.
     Business services Struts can provide to an Ajax UI,
     Basics of the Struts 2 web application framework.
     Basics of the Yahoo User Interface Library (YUI).
Ajax on Struts:
Coding an Ajax Application with Struts 2




                       Square One University Series
Ajax on Struts

For the latest version of this presentation,
visit http://slideshare.com/ted.husted
For the latest version of source code,
visit http://code.google.com/p/yazaar/
Abstract

Ajax is the web's hottest user interface.
Struts is Java's most popular web
framework. What happens when we put
Ajax on Struts?
During the session, we will cover
  Integrating an Ajax UI with Struts 2
  Using Yahoo User Interface (YUI) Library
  Using Struts to provide services to Ajax UI
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side data?
What about error-handling?
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side data?
What about error-handling?
What are Ajax widgets?
Ajax lets scripts make requests and
update content without a page refresh
Widgets are “black-box” user interfrace
(UI) components
Typically, widgets are configured without
touching the component's internals
DataGrids, Calendars, Carousels, even
TextBoxes
What are Ajax widgets?
Widgets can be used with any server platform
   PHP, Java, .NET, Ruby, Python
Client-side widget provides UI
Server-side technology provides data access
and business logic
What is Apache Struts?
Free open-source framework for creating
Java web applications
Provides three major components
  Request handler
  Response handler
  Tag libraries for JSP, as well as
  Freemarker, and Velocity
Can we use Ajax with a Struts
        application?
XHR is just another request/response
Struts can stream data as a response
Use JSP scriptlets
Use Ajax JSP tag libraries
Use plain-vanilla Ajax libraries
Why use Apache Struts?
Mature, well-supported, well-understood
Provides input validation and data conversion
Interacts well with Spring, Hibernate, et al
Defacto standard for Java web applications
Where do we start?
Case study
  Pure Ajax prototype
  Test data encapsulated as JSON
  Later, replace test data with JSON via XHR
Use “spikes” to separates concerns
How do we select an Ajax library?
 Submit before you commit
 Code your own sample application
 Pick the one that works for you and
 yours
 We tried Dojo and YUI
http://dojotoolkit.org/
http://developer.yahoo.com/yui/
Why Yahoo User Interface
      (YUI) Library?
Well documented and supported
Lots of working examples
New BSD license
Easy to read code
Easy to hack code
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side daa?
What about error-handling?
What did we code?
1 Provide a list of employees
2 Record employee's first name, last name,
extension, username, hire date, and hours
worked per week.
 3 Record to be updated by authorized users
 4 Allow list to be filtered by first name, last
name, or username.
 5 Allow full or filtered list to be sorted by any
field
What did we code?
Use YUI DataTable to display list
Share DataTable record with data-entry
form
 Use TabView to separate list and edit
What are we going to code?
Prototype with static data
Request data from Struts 2 Action
  Use Struts 2 Plugin to return JSON
How does the Struts 2
          JSON plugin work?
    Exposes action properties as fields in a
    JSON record.
{
    stringValue : quot;A string valuequot;,
    intArray: [10, 20],
    map: {
        Zaphod : quot;Just this guy, you knowquot;,
        Arthur : quot;Monkey-boyquot;
    },
    record: quot;start a named recordquot;
}
public class ExampleOutputAction {

   private String stringValue = quot;A string valuequot;;
   public String getStringValue() {
       return stringValue;
   }
   public void setStringValue(String value) {
       stringValue = value;
   }

   private int[] intArray = {10, 20};
   public int[] getIntArray() {
       return intArray;
   }
   public void setIntArray(int[] value) {
       intArray = value;
   }

   private Map map = new HashMap();
   public Map getMap() {
       return map;
   }
   public void setMap(Map value) {
       map = value;
   }
private String nextRecord = quot;start a named recordquot;;
    @JSON(name=quot;recordquot;)
    public String getNextRecord() {
        return nextRecord;
    }

    //'transient' fields are not serialized
    @SuppressWarnings(quot;unusedquot;)
    private transient String stayHome;

    //fields without getter method are not serialized
    @SuppressWarnings(quot;unusedquot;)
    private String noGetterForMe;

    public String execute() {
        map.put(quot;Zaphodquot;, quot;Just this guy, you knowquot;);
        map.put(quot;Arthurquot;, quot;Monkey-Boyquot;);
        return quot;successquot;;
    }
}
{
    quot;intArrayquot;:[10,20],
     quot;mapquot;: { quot;Arthurquot;: quot;Monkey-Boyquot;,
              quot;Zaphodquot;:quot;Just this guy, you knowquot;},
     quot;recordquot;:quot;start a named recordquot;,
     quot;stringValuequot;:quot;A string valuequot;
}

{
    stringValue : quot;A string valuequot;,
    intArray: [10, 20],
    map: {
        Zaphod : quot;Just this guy, you knowquot;,
        Arthur : quot;Monkey-boyquot;
    },
    record: quot;start a named recordquot;
}
package actions;

import   java.util.Map;
import   java.util.HashMap;
import   com.googlecode.jsonplugin.annotations.JSON;
import   org.texturemedia.smarturls.ParentPackage;
import   org.texturemedia.smarturls.Result;

@ParentPackage(quot;json-defaultquot;)
@Result(name=quot;successquot;, type=quot;jsonquot;, location=quot;quot;)
public class ExampleOutputAction {

    private String stringValue = quot;A string valuequot;;

    // ...
How did we code a UI using
       static data?
Entry list
Entry form
List shares data with form
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side data?
What about error-handling?
Is there an Ajax architecture?
<script src=quot;my.jsquot; type=quot;text/javascriptquot;>
</script>

if (typeof parent.MY != quot;undefinedquot;) {
    var MY = parent.MY; // Prototype namespace
    var my = parent.my; // Variable namespace
} else var
    var MY = {};
    var my = {};
    var MY.Event = {
// ...
    }
    var my.oEvent = {
    // ... instantiate rest of my and MY
Is there an Ajax architecture?
<script src=quot;contacts.jsquot; type=quot;text/javascriptquot;>
</script>



MY.Contacts = function(){
  MY.Contacts.superclass.constructor.call(this);
};
YAHOO.lang.extend(MY.Contacts,YAHOO.yazaar.flev-base);
What's a FLEV widget?
Common business workflow is
  Find / List / Edit / View
  Or quot;FLEVquot;
The FLEV widget defines one columnset
and datasource to use with all four
presentations
MY.Contact.prototype.oColumnHeaders = [
{key:quot;first_namequot;, text:quot;First Namequot;,
sortable:true, resizeable:true,
editor:quot;textboxquot;, formClassName: quot;requiredquot;,
formTitle: quot;Enter employee's first namequot;},

// more entries

];

     key and text are shared attributes
     sortable, resizable are List attribute
     formClassName, formtitle are Edit
     attributes (validation)
MY.Contact.prototype.oResponseSchema = {
fields:[quot;idquot;, quot;last_namequot;, quot;first_namequot;,
quot;extensionquot;, quot;usernamequot;, quot;hiredquot;, quot;hoursquot;,
quot;editorquot;]
};



MY.Contact.prototype.LOCAL_DATA = {
 result : [{id: 'c5b6bbb1-66d6-49cb-9db6-
743af6627828', last_name: 'Beeblebrox ',
first_name: 'Zaphod ', extension: '555-123-
4565', username: 'zaphie ', hired:
'04/01/1978', hours: -1, editor: '1'},
 // ...
];
my.oEvent.createEvent(quot;contactLoadquot;)

my.oEvent.onContactLoadReturn = function(oData)
{
 my.info(quot;Firing contactLoad Eventquot;);
 my.oEvent.fireEvent(quot;contactLoadquot;, oData);
};
<script type=quot;text/javascriptquot;>
 var onContentReady = function() {
  _Contact = new MY.Contact();
  my.oEvent.subscribe(quot;contactLoadquot;,_Contact.load,
   _Contact);
  my.oEvent.onContactLoadReturn(_Contact.LOCAL_DATA);
 };
 YAHOO.util.Event.onContentReady(quot;elBodyquot;,
  onContentReady);
</script>
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side data?
What about error-handling?
How can we switch over to
    server-side data?
Create an example Action that returns
example data
Create a database Action that returns
persistent data
public class ContactLoadAction {
private List contactLoad = new ArrayList();
@JSON(name=quot;resultquot;)
public List getContactLoad() {
  contactLoad.add(new Contact(
    quot;c5b6bbb1-66d6-49cb-9db6-743af6627828quot;,
    quot;Beeblebroxquot;,
    quot;Zaphodquot;,
    quot;555-123-4565quot;,
    quot;zaphiequot;,
    quot;04/01/1978quot;,
    quot;-1quot;,
    quot;1quot;
  ));
  // ...
  return contacts;
}
public class Contact {

public Contact() {};

public Contact(String id, String last_name, String first_name,
String extension, String username, String hired, String hours,
String editor) {
 setId(id);
 setLast_name(last_name);
 setFirst_name(first_name);
 setExtension(extension);
 setUsername(username);
 setHired(new Date(hired));
 setHours(new Double(hours));
  setEditor(editor);
}

private String id;
public void setId(String value) {
  id = value;
}
public String getId() {
  return id;
}

// more properties ...
How can we switch over to
      server-side data?
Action data:
{quot;resultquot;:[{quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123-
4565quot;,quot;first_namequot;:quot;Zaphod quot;, ...
]}

JavaScript data:
MY.Contact.prototype.LOCAL_DATA =
{result:[{id: 'c5b6bbb1-66d6-49cb-9db6-
743af6627828', last_name: 'Beeblebrox ', first_name:
'Zaphod ' ...
http://developer.yahoo.com/yui/connection/
<script>
var transaction = YAHOO.util.Connect.asyncRequest(
    'POST', sUrl, callback, null);
</script>

var callback =
{
  success: function(o) {/*success handler code*/},
  failure: function(o) {/*failure handler code*/},
  argument: [argument1, argument2, argument3]
}

var responseSuccess = function(o){
/* Please see the Success Case section for more
 * details on the response object's properties.
 * o.tId
 * o.status
 * o.statusText
 * o.getResponseHeader[ ]
 * o.getAllResponseHeaders
 * o.responseText
 * o.responseXML
 * o.argument
 */
};
// my.oEvents.onContactLoadReturn(_Self.LOCAL_DATA);
YAHOO.util.Connect.asyncRequest('POST', quot;contact-
load.doquot;, callback, null);

var callback = {
    success : function(o) {
        my.oEvent.onContactLoadReturn(o.responseText);
    }
};
{quot;resultquot;:[
    {quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123-
4565quot;,quot;first_namequot;:quot;Zaphod quot;, ...
]}

MY.Contact.prototype.LOCAL_DATA =
{result:[
// my.oEvents.onContactLoadReturn(_Self.LOCAL_DATA);
YAHOO.util.Connect.asyncRequest('GET', quot;contact-load.doquot;,
callback, null);

var callback = {
    success : function(o) {
      var payload = eval(quot;(quot; + o.responseText + quot;)quot;);
      my.oEvent.onContactLoadReturn(payload);
    }
};

- var payload = eval(quot;(quot; + o.responseText + quot;)quot;) ;
+ var payload = jcontext.parseJSON(o.responseText);




                                     http://json.org/json.js
What about JavaScript Hijacking?
/* {quot;resultquot;:[{quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123-4565quot;,
...
}]} */

var data = o.responseText;
var payload =
eval(quot;(quot;+data.substring(data.indexOf(quot;/*quot;)+2,
    data.lastIndexOf(quot;*/quot;))+quot;)quot;);
my.oEvent.onContactLoadReturn(payload);
What about JavaScript Hijacking?
<package name=quot;my-defaultquot; extends=quot;json-defaultquot;>
 <result-types>
  <result-type name=quot;jsonquot;
   class=quot;com.googlecode.jsonplugin.JSONResultquot;
   default=quot;truequot;>
   <param name=quot;wrapWithCommentsquot;>true</param>
  </result-type>
 </result-types>

 <action name=quot;contact-loadquot;
  class=quot;actions.ContactLoadActionquot;>
  <result />
 </action>
</package>
Ajax on Struts
What are Ajax widgets?
What are we coding?
Is there an Ajax architecture?
How can we switch to server-side data?
What about error-handling?
What about error handling?
var callback = {
  success : function(o) {
    var payload = eval(quot;(quot; + o.responseText + quot;)quot;);
    my.oEvent.onContactLoadReturn(payload);
  }
};

YAHOO.util.Connect.asyncRequest('POST', quot;contact-
load.doquot;, callback, null);
What about error handling?
var callback =
{
  success: function(o) {/*success handler code*/},
  failure: function(o) {/*failure handler code*/},
  argument: [argument1, argument2, argument3]
}
How does JSON-RPC handle errors?
{
    quot;versionquot; : quot;1.1quot;,
    quot;errorquot; : {
      quot;namequot; : quot;JSONRPCErrorquot;,
      quot;codequot; : 123,
      quot;messagequot; : quot;An error occurred parsing the request object.quot;,
      quot;errorquot; : {
         quot;namequot; : quot;JSONErrorquot;,
         quot;messagequot; : quot;Bad arrayquot;,
         quot;atquot; : 42,
         quot;textquot; : quot;{quot;idquot;:1,quot;methodquot;:quot;sumquot;,quot;paramsquot;:[1,2,3,4,5}quot;}
      }
}
How does Struts handle exceptions?
<global-results>
  <result name=quot;errorquot;/>
</global-results>

<global-exception-mappings>
 <exception-mapping
  exception=quot;java.lang.Exceptionquot; result=quot;errorquot;/>
</global-exception-mappings>
How does Struts handle exceptions?
<h2>An unexpected error has occurred</h2>
  <p>Please report this error to your system
administrator or appropriate technical support
personnel. Thank you for your cooperation.</p>
  <hr/>
  <h3>Error Message</h3>
    <p>
      <s:property value=quot;%{exception.message}quot;/>
    </p>
    <hr/>
    <h3>Technical Details</h3>
    <p>
      <s:property value=quot;%{exceptionStack}quot;/>
    </p>
How does Struts handle exceptions?
public String getExceptionMessage() {
 ActionContext context = ActionContext.getContext();
 Object value = context.getValueStack().
  findValue(quot;exception.messagequot;);
  if (value==null) return null;
  return value.toString();
}

public String getExceptionStack() {
 ActionContext context = ActionContext.getContext();
 Object value = context.getValueStack().
  findValue(quot;exceptionStackquot;);
 if (value==null) return null;
 return value.toString();
}
How does Struts handle exceptions?
public String execute() throws Exception {
  throw new Exception(quot;Whoops!quot;);
// return quot;successquot;;
}




  getExceptionMessage :” “Whoops!”
  getExceptionStack: “java.lang.exception
  Whoops! at actions.ContactLoadAction
  ...
How do widgets handle errors?
<!-- ... -->

</div>
<div id=quot;elErrorquot; class=quot;errorquot;></div>
<div

<!-- ... -->
How do widgets handle errors?
my.asyncRequestException = function (o) {
  alert(quot;Error Communicating with Server! See
message area for details.quot;);
  var sTemplate = quot;<table>
   <tr><th>Message:&nbsp;</th>
   <td>{exceptionMessage}</td></tr>
   <tr><th>Location:</th>
   <td>{exceptionStack}</td></tr>
  </table>quot;;
  var oPayload = eval(quot;(quot; + o + quot;)quot;) ;
  document.getElementById(quot;elErrorquot;).innerHTML =
    sTemplate.supplant(oPayload);
How do widgets handle errors?
What about error handling?
var onContentReady = function() {
 _Contact = new MY.Contact();
 my.oEvent.subscribe(quot;contactLoadquot;,_Contact.load,
   _Contact);
 // YAHOO.util.Connect.asyncRequest('POST', quot;contact-
   load.doquot;, callback, null);
 my.asyncRequest(quot;contact-load.doquot;,
   my.oEvent.onContactLoadReturn);
 };
my.asyncRequest = function (sAction, fnCallback) {
 return YAHOO.util.Connect.asyncRequest(quot;POSTquot;, sAction,
{
   success : function(o) {
    var oPayload = eval(quot;(quot; + o.responseText + quot;)quot;) ;
    fnCallback(oPayload);
  }
 });
};
my.asyncRequest = function (sAction, fnCallback) {
 return YAHOO.util.Connect.asyncRequest(quot;POSTquot;, sAction,
{
   success : function(o) {
    var oPayload = eval(quot;(quot; + o.responseText + quot;)quot;) ;
    if (oPayload.exceptionMessage) {
     my.asyncRequestException(oPayload);
    }
    fnCallback(oPayload);
  }
 });
};
my.asyncRequestException = function (oPayload) {
 my.errorMessage(oPayload.exceptionMessage,
  oPayload.exceptionStack);
};
my.errorMessage = function (sMessage, sStackTrace) {
  alert(quot;Error Communicating with Server! // ...
  var sTemplate = quot;<table><tr> // ...
  var oContext = {message: sMessage,
    stackTrace: sStackTrace};
  document.getElementById(quot;elErrorquot;).innerHTML =
    sTemplate.supplant(oContext);
  my.isMessage(true);
  my.error(oContext);
};
Is that all there is?
During this session, we covered
  Integrating an Ajax UI with Struts 2
  Using Yahoo User Interface (YUI) Library
  Using Struts to provide services to Ajax U
Struts University Series
Whats up with Planet Yazaar?
Development team Yahoo! Employees
  Something like Spring, Hibernate
  Unlike Apache projects
No formal mechanism for contributions
Whats up with Planet Yazaar?
Development team Yahoo! Employees
  Something like Spring, Hibernate
  Unlike Apache projects
No formal mechanism for contributions
A cathderal, rather than a bazaar
What's up with Planet Yazaar?
Yazaar - (Yahoo + Bazaar = Yazaar)
Accepts and maintains contributor
extensions and documentation
Working toward quot;soup to nutsquot; project
documentation
Public repository with version-to-version
change logs
What's up with Planet Yazaar?
 Just as an aside ...
  Yahoo GeoCities for public web site
  Uses GoogleCode for repository
  Google Group for mailing list and change
  logs
  Yahoo 360 for Blog
Square One University Series

Más contenido relacionado

La actualidad más candente

GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao IntroductionBooch Lin
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorialKat Roque
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code DevelopmentPeter Gfader
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
C# Advanced L03-XML+LINQ to XML
C# Advanced L03-XML+LINQ to XMLC# Advanced L03-XML+LINQ to XML
C# Advanced L03-XML+LINQ to XMLMohammad Shaker
 
Java script
 Java script Java script
Java scriptbosybosy
 
ORMLite Android
ORMLite AndroidORMLite Android
ORMLite Android哲偉 楊
 
Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Ramamohan Chokkam
 
Reducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLReducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLMongoDB
 
Object Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypassObject Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypassSam Thomas
 
javascript objects
javascript objectsjavascript objects
javascript objectsVijay Kalyan
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreXavier Coulon
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersJoris Verbogt
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Rabble .
 

La actualidad más candente (20)

greenDAO
greenDAOgreenDAO
greenDAO
 
GreenDao Introduction
GreenDao IntroductionGreenDao Introduction
GreenDao Introduction
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
Green dao
Green daoGreen dao
Green dao
 
Green dao
Green daoGreen dao
Green dao
 
Es.next
Es.nextEs.next
Es.next
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
C# Advanced L03-XML+LINQ to XML
C# Advanced L03-XML+LINQ to XMLC# Advanced L03-XML+LINQ to XML
C# Advanced L03-XML+LINQ to XML
 
Java script
 Java script Java script
Java script
 
Slickdemo
SlickdemoSlickdemo
Slickdemo
 
ORMLite Android
ORMLite AndroidORMLite Android
ORMLite Android
 
Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268
 
Reducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQLReducing Development Time with MongoDB vs. SQL
Reducing Development Time with MongoDB vs. SQL
 
Object Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypassObject Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypass
 
javascript objects
javascript objectsjavascript objects
javascript objects
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a Datastore
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web Developers
 
Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007Introduction to Active Record - Silicon Valley Ruby Conference 2007
Introduction to Active Record - Silicon Valley Ruby Conference 2007
 

Destacado (17)

Ajax chap 4
Ajax chap 4Ajax chap 4
Ajax chap 4
 
Ajax chap 2.-part 1
Ajax chap 2.-part 1Ajax chap 2.-part 1
Ajax chap 2.-part 1
 
Ajax chap 3
Ajax chap 3Ajax chap 3
Ajax chap 3
 
Ajax 101 Workshop
Ajax 101 WorkshopAjax 101 Workshop
Ajax 101 Workshop
 
Ajax part i
Ajax part iAjax part i
Ajax part i
 
Dom
DomDom
Dom
 
Ajax Part II
Ajax Part IIAjax Part II
Ajax Part II
 
Ajax chap 5
Ajax chap 5Ajax chap 5
Ajax chap 5
 
Perl Chapter 1
Perl Chapter 1Perl Chapter 1
Perl Chapter 1
 
S.E. DBMS-Paper Analysis
S.E. DBMS-Paper AnalysisS.E. DBMS-Paper Analysis
S.E. DBMS-Paper Analysis
 
AJAX
AJAXAJAX
AJAX
 
Ajax Development With Dreamweaver
Ajax Development With DreamweaverAjax Development With Dreamweaver
Ajax Development With Dreamweaver
 
Python reading and writing files
Python reading and writing filesPython reading and writing files
Python reading and writing files
 
XML
XMLXML
XML
 
OSI Model - Every Detail Explained
OSI Model - Every Detail ExplainedOSI Model - Every Detail Explained
OSI Model - Every Detail Explained
 
TCP-IP Reference Model
TCP-IP Reference ModelTCP-IP Reference Model
TCP-IP Reference Model
 
OSI Model of Networking
OSI Model of NetworkingOSI Model of Networking
OSI Model of Networking
 

Similar a Coding Ajax

Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesJamund Ferguson
 
Pascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax SecurityPascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax Securityamiable_indian
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)Carles Farré
 
Java Intro
Java IntroJava Intro
Java Introbackdoor
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Matt Raible
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesJohn Brunswick
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than WebHeiko Behrens
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 

Similar a Coding Ajax (20)

Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Go react codelab
Go react codelabGo react codelab
Go react codelab
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
 
Pascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax SecurityPascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax Security
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
 
Java Intro
Java IntroJava Intro
Java Intro
 
Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2Migrating from Struts 1 to Struts 2
Migrating from Struts 1 to Struts 2
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 

Más de Ted Husted

.NET @ apache.org
 .NET @ apache.org .NET @ apache.org
.NET @ apache.orgTed Husted
 
The secret life_of_open_source
The secret life_of_open_sourceThe secret life_of_open_source
The secret life_of_open_sourceTed Husted
 
Open Source Secret Sauce - Lugor Sep 2011
Open Source Secret Sauce - Lugor Sep 2011Open Source Secret Sauce - Lugor Sep 2011
Open Source Secret Sauce - Lugor Sep 2011Ted Husted
 
NU FaceBook 101 JCC 2010
NU  FaceBook 101 JCC 2010NU  FaceBook 101 JCC 2010
NU FaceBook 101 JCC 2010Ted Husted
 
Developing java Web Applications Using Google Apps RJUG 2011
Developing java Web Applications Using Google Apps RJUG 2011Developing java Web Applications Using Google Apps RJUG 2011
Developing java Web Applications Using Google Apps RJUG 2011Ted Husted
 
Open source secret_sauce_apache_con_2010
Open source secret_sauce_apache_con_2010Open source secret_sauce_apache_con_2010
Open source secret_sauce_apache_con_2010Ted Husted
 
Drupal kickstart-workshop
Drupal kickstart-workshopDrupal kickstart-workshop
Drupal kickstart-workshopTed Husted
 
Open source-secret-sauce-rit-2010
Open source-secret-sauce-rit-2010Open source-secret-sauce-rit-2010
Open source-secret-sauce-rit-2010Ted Husted
 
Agile Analysis with Use Cases: Balancing Utility with Simplicity
Agile Analysis with Use Cases: Balancing Utility with SimplicityAgile Analysis with Use Cases: Balancing Utility with Simplicity
Agile Analysis with Use Cases: Balancing Utility with SimplicityTed Husted
 
Testing Web Application Security
Testing Web Application SecurityTesting Web Application Security
Testing Web Application SecurityTed Husted
 
API Doc Smackdown
API Doc SmackdownAPI Doc Smackdown
API Doc SmackdownTed Husted
 
Testing The Testers
Testing The TestersTesting The Testers
Testing The TestersTed Husted
 
Testing Ajax Applications
Testing Ajax ApplicationsTesting Ajax Applications
Testing Ajax ApplicationsTed Husted
 
Testing Ajax Web Applications
Testing Ajax Web ApplicationsTesting Ajax Web Applications
Testing Ajax Web ApplicationsTed Husted
 
Open Source Secret Sauce
Open Source Secret SauceOpen Source Secret Sauce
Open Source Secret SauceTed Husted
 

Más de Ted Husted (17)

Ship It!
Ship It!Ship It!
Ship It!
 
.NET @ apache.org
 .NET @ apache.org .NET @ apache.org
.NET @ apache.org
 
The secret life_of_open_source
The secret life_of_open_sourceThe secret life_of_open_source
The secret life_of_open_source
 
Open Source Secret Sauce - Lugor Sep 2011
Open Source Secret Sauce - Lugor Sep 2011Open Source Secret Sauce - Lugor Sep 2011
Open Source Secret Sauce - Lugor Sep 2011
 
NU FaceBook 101 JCC 2010
NU  FaceBook 101 JCC 2010NU  FaceBook 101 JCC 2010
NU FaceBook 101 JCC 2010
 
Developing java Web Applications Using Google Apps RJUG 2011
Developing java Web Applications Using Google Apps RJUG 2011Developing java Web Applications Using Google Apps RJUG 2011
Developing java Web Applications Using Google Apps RJUG 2011
 
Open source secret_sauce_apache_con_2010
Open source secret_sauce_apache_con_2010Open source secret_sauce_apache_con_2010
Open source secret_sauce_apache_con_2010
 
Drupal kickstart-workshop
Drupal kickstart-workshopDrupal kickstart-workshop
Drupal kickstart-workshop
 
Open source-secret-sauce-rit-2010
Open source-secret-sauce-rit-2010Open source-secret-sauce-rit-2010
Open source-secret-sauce-rit-2010
 
Agile Analysis with Use Cases: Balancing Utility with Simplicity
Agile Analysis with Use Cases: Balancing Utility with SimplicityAgile Analysis with Use Cases: Balancing Utility with Simplicity
Agile Analysis with Use Cases: Balancing Utility with Simplicity
 
Testing Web Application Security
Testing Web Application SecurityTesting Web Application Security
Testing Web Application Security
 
API Doc Smackdown
API Doc SmackdownAPI Doc Smackdown
API Doc Smackdown
 
Testing The Testers
Testing The TestersTesting The Testers
Testing The Testers
 
Testing Ajax Applications
Testing Ajax ApplicationsTesting Ajax Applications
Testing Ajax Applications
 
Testing Ajax Web Applications
Testing Ajax Web ApplicationsTesting Ajax Web Applications
Testing Ajax Web Applications
 
Testing Tools
Testing ToolsTesting Tools
Testing Tools
 
Open Source Secret Sauce
Open Source Secret SauceOpen Source Secret Sauce
Open Source Secret Sauce
 

Último

Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesDipal Arora
 
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...Any kyc Account
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityEric T. Tung
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communicationskarancommunications
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayNZSG
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756dollysharma2066
 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with CultureSeta Wicaksana
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Neil Kimberley
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyEthan lee
 
Call Girls in Gomti Nagar - 7388211116 - With room Service
Call Girls in Gomti Nagar - 7388211116  - With room ServiceCall Girls in Gomti Nagar - 7388211116  - With room Service
Call Girls in Gomti Nagar - 7388211116 - With room Servicediscovermytutordmt
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Dave Litwiller
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxAndy Lambert
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...lizamodels9
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
 
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...amitlee9823
 
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...anilsa9823
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfPaul Menig
 

Último (20)

Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
 
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
KYC-Verified Accounts: Helping Companies Handle Challenging Regulatory Enviro...
 
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League City
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communications
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 May
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
 
Organizational Transformation Lead with Culture
Organizational Transformation Lead with CultureOrganizational Transformation Lead with Culture
Organizational Transformation Lead with Culture
 
Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
 
Forklift Operations: Safety through Cartoons
Forklift Operations: Safety through CartoonsForklift Operations: Safety through Cartoons
Forklift Operations: Safety through Cartoons
 
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabiunwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
 
Call Girls in Gomti Nagar - 7388211116 - With room Service
Call Girls in Gomti Nagar - 7388211116  - With room ServiceCall Girls in Gomti Nagar - 7388211116  - With room Service
Call Girls in Gomti Nagar - 7388211116 - With room Service
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptx
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
Call Girls Electronic City Just Call 👗 7737669865 👗 Top Class Call Girl Servi...
 
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdf
 

Coding Ajax

  • 1. Ajax on Struts: Coding an Ajax Application with Struts 2 Wednesday, October 1st, 2:35p-3:35p Ted Husted In this session, we explore How to integrate an Ajax UI framework with a Struts 2 business framework. Business services Struts can provide to an Ajax UI, Basics of the Struts 2 web application framework. Basics of the Yahoo User Interface Library (YUI).
  • 2. Ajax on Struts: Coding an Ajax Application with Struts 2 Square One University Series
  • 3. Ajax on Struts For the latest version of this presentation, visit http://slideshare.com/ted.husted For the latest version of source code, visit http://code.google.com/p/yazaar/
  • 4. Abstract Ajax is the web's hottest user interface. Struts is Java's most popular web framework. What happens when we put Ajax on Struts? During the session, we will cover Integrating an Ajax UI with Struts 2 Using Yahoo User Interface (YUI) Library Using Struts to provide services to Ajax UI
  • 5. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side data? What about error-handling?
  • 6. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side data? What about error-handling?
  • 7. What are Ajax widgets? Ajax lets scripts make requests and update content without a page refresh Widgets are “black-box” user interfrace (UI) components Typically, widgets are configured without touching the component's internals DataGrids, Calendars, Carousels, even TextBoxes
  • 8. What are Ajax widgets? Widgets can be used with any server platform PHP, Java, .NET, Ruby, Python Client-side widget provides UI Server-side technology provides data access and business logic
  • 9. What is Apache Struts? Free open-source framework for creating Java web applications Provides three major components Request handler Response handler Tag libraries for JSP, as well as Freemarker, and Velocity
  • 10. Can we use Ajax with a Struts application? XHR is just another request/response Struts can stream data as a response Use JSP scriptlets Use Ajax JSP tag libraries Use plain-vanilla Ajax libraries
  • 11. Why use Apache Struts? Mature, well-supported, well-understood Provides input validation and data conversion Interacts well with Spring, Hibernate, et al Defacto standard for Java web applications
  • 12. Where do we start? Case study Pure Ajax prototype Test data encapsulated as JSON Later, replace test data with JSON via XHR Use “spikes” to separates concerns
  • 13. How do we select an Ajax library? Submit before you commit Code your own sample application Pick the one that works for you and yours We tried Dojo and YUI
  • 16. Why Yahoo User Interface (YUI) Library? Well documented and supported Lots of working examples New BSD license Easy to read code Easy to hack code
  • 17. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side daa? What about error-handling?
  • 18. What did we code? 1 Provide a list of employees 2 Record employee's first name, last name, extension, username, hire date, and hours worked per week. 3 Record to be updated by authorized users 4 Allow list to be filtered by first name, last name, or username. 5 Allow full or filtered list to be sorted by any field
  • 19. What did we code? Use YUI DataTable to display list Share DataTable record with data-entry form Use TabView to separate list and edit
  • 20.
  • 21.
  • 22. What are we going to code? Prototype with static data Request data from Struts 2 Action Use Struts 2 Plugin to return JSON
  • 23. How does the Struts 2 JSON plugin work? Exposes action properties as fields in a JSON record. { stringValue : quot;A string valuequot;, intArray: [10, 20], map: { Zaphod : quot;Just this guy, you knowquot;, Arthur : quot;Monkey-boyquot; }, record: quot;start a named recordquot; }
  • 24. public class ExampleOutputAction { private String stringValue = quot;A string valuequot;; public String getStringValue() { return stringValue; } public void setStringValue(String value) { stringValue = value; } private int[] intArray = {10, 20}; public int[] getIntArray() { return intArray; } public void setIntArray(int[] value) { intArray = value; } private Map map = new HashMap(); public Map getMap() { return map; } public void setMap(Map value) { map = value; }
  • 25. private String nextRecord = quot;start a named recordquot;; @JSON(name=quot;recordquot;) public String getNextRecord() { return nextRecord; } //'transient' fields are not serialized @SuppressWarnings(quot;unusedquot;) private transient String stayHome; //fields without getter method are not serialized @SuppressWarnings(quot;unusedquot;) private String noGetterForMe; public String execute() { map.put(quot;Zaphodquot;, quot;Just this guy, you knowquot;); map.put(quot;Arthurquot;, quot;Monkey-Boyquot;); return quot;successquot;; } }
  • 26.
  • 27. { quot;intArrayquot;:[10,20], quot;mapquot;: { quot;Arthurquot;: quot;Monkey-Boyquot;, quot;Zaphodquot;:quot;Just this guy, you knowquot;}, quot;recordquot;:quot;start a named recordquot;, quot;stringValuequot;:quot;A string valuequot; } { stringValue : quot;A string valuequot;, intArray: [10, 20], map: { Zaphod : quot;Just this guy, you knowquot;, Arthur : quot;Monkey-boyquot; }, record: quot;start a named recordquot; }
  • 28. package actions; import java.util.Map; import java.util.HashMap; import com.googlecode.jsonplugin.annotations.JSON; import org.texturemedia.smarturls.ParentPackage; import org.texturemedia.smarturls.Result; @ParentPackage(quot;json-defaultquot;) @Result(name=quot;successquot;, type=quot;jsonquot;, location=quot;quot;) public class ExampleOutputAction { private String stringValue = quot;A string valuequot;; // ...
  • 29. How did we code a UI using static data? Entry list Entry form List shares data with form
  • 30.
  • 31.
  • 32. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side data? What about error-handling?
  • 33. Is there an Ajax architecture? <script src=quot;my.jsquot; type=quot;text/javascriptquot;> </script> if (typeof parent.MY != quot;undefinedquot;) { var MY = parent.MY; // Prototype namespace var my = parent.my; // Variable namespace } else var var MY = {}; var my = {}; var MY.Event = { // ... } var my.oEvent = { // ... instantiate rest of my and MY
  • 34. Is there an Ajax architecture? <script src=quot;contacts.jsquot; type=quot;text/javascriptquot;> </script> MY.Contacts = function(){ MY.Contacts.superclass.constructor.call(this); }; YAHOO.lang.extend(MY.Contacts,YAHOO.yazaar.flev-base);
  • 35. What's a FLEV widget? Common business workflow is Find / List / Edit / View Or quot;FLEVquot; The FLEV widget defines one columnset and datasource to use with all four presentations
  • 36. MY.Contact.prototype.oColumnHeaders = [ {key:quot;first_namequot;, text:quot;First Namequot;, sortable:true, resizeable:true, editor:quot;textboxquot;, formClassName: quot;requiredquot;, formTitle: quot;Enter employee's first namequot;}, // more entries ]; key and text are shared attributes sortable, resizable are List attribute formClassName, formtitle are Edit attributes (validation)
  • 37. MY.Contact.prototype.oResponseSchema = { fields:[quot;idquot;, quot;last_namequot;, quot;first_namequot;, quot;extensionquot;, quot;usernamequot;, quot;hiredquot;, quot;hoursquot;, quot;editorquot;] }; MY.Contact.prototype.LOCAL_DATA = { result : [{id: 'c5b6bbb1-66d6-49cb-9db6- 743af6627828', last_name: 'Beeblebrox ', first_name: 'Zaphod ', extension: '555-123- 4565', username: 'zaphie ', hired: '04/01/1978', hours: -1, editor: '1'}, // ... ];
  • 38. my.oEvent.createEvent(quot;contactLoadquot;) my.oEvent.onContactLoadReturn = function(oData) { my.info(quot;Firing contactLoad Eventquot;); my.oEvent.fireEvent(quot;contactLoadquot;, oData); };
  • 39. <script type=quot;text/javascriptquot;> var onContentReady = function() { _Contact = new MY.Contact(); my.oEvent.subscribe(quot;contactLoadquot;,_Contact.load, _Contact); my.oEvent.onContactLoadReturn(_Contact.LOCAL_DATA); }; YAHOO.util.Event.onContentReady(quot;elBodyquot;, onContentReady); </script>
  • 40.
  • 41. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side data? What about error-handling?
  • 42. How can we switch over to server-side data? Create an example Action that returns example data Create a database Action that returns persistent data
  • 43. public class ContactLoadAction { private List contactLoad = new ArrayList(); @JSON(name=quot;resultquot;) public List getContactLoad() { contactLoad.add(new Contact( quot;c5b6bbb1-66d6-49cb-9db6-743af6627828quot;, quot;Beeblebroxquot;, quot;Zaphodquot;, quot;555-123-4565quot;, quot;zaphiequot;, quot;04/01/1978quot;, quot;-1quot;, quot;1quot; )); // ... return contacts; }
  • 44. public class Contact { public Contact() {}; public Contact(String id, String last_name, String first_name, String extension, String username, String hired, String hours, String editor) { setId(id); setLast_name(last_name); setFirst_name(first_name); setExtension(extension); setUsername(username); setHired(new Date(hired)); setHours(new Double(hours)); setEditor(editor); } private String id; public void setId(String value) { id = value; } public String getId() { return id; } // more properties ...
  • 45.
  • 46. How can we switch over to server-side data? Action data: {quot;resultquot;:[{quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123- 4565quot;,quot;first_namequot;:quot;Zaphod quot;, ... ]} JavaScript data: MY.Contact.prototype.LOCAL_DATA = {result:[{id: 'c5b6bbb1-66d6-49cb-9db6- 743af6627828', last_name: 'Beeblebrox ', first_name: 'Zaphod ' ...
  • 48. <script> var transaction = YAHOO.util.Connect.asyncRequest( 'POST', sUrl, callback, null); </script> var callback = { success: function(o) {/*success handler code*/}, failure: function(o) {/*failure handler code*/}, argument: [argument1, argument2, argument3] } var responseSuccess = function(o){ /* Please see the Success Case section for more * details on the response object's properties. * o.tId * o.status * o.statusText * o.getResponseHeader[ ] * o.getAllResponseHeaders * o.responseText * o.responseXML * o.argument */ };
  • 49. // my.oEvents.onContactLoadReturn(_Self.LOCAL_DATA); YAHOO.util.Connect.asyncRequest('POST', quot;contact- load.doquot;, callback, null); var callback = { success : function(o) { my.oEvent.onContactLoadReturn(o.responseText); } };
  • 50.
  • 51. {quot;resultquot;:[ {quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123- 4565quot;,quot;first_namequot;:quot;Zaphod quot;, ... ]} MY.Contact.prototype.LOCAL_DATA = {result:[
  • 52. // my.oEvents.onContactLoadReturn(_Self.LOCAL_DATA); YAHOO.util.Connect.asyncRequest('GET', quot;contact-load.doquot;, callback, null); var callback = { success : function(o) { var payload = eval(quot;(quot; + o.responseText + quot;)quot;); my.oEvent.onContactLoadReturn(payload); } }; - var payload = eval(quot;(quot; + o.responseText + quot;)quot;) ; + var payload = jcontext.parseJSON(o.responseText); http://json.org/json.js
  • 53. What about JavaScript Hijacking? /* {quot;resultquot;:[{quot;editorquot;:quot;1quot;,quot;extensionquot;:quot;555-123-4565quot;, ... }]} */ var data = o.responseText; var payload = eval(quot;(quot;+data.substring(data.indexOf(quot;/*quot;)+2, data.lastIndexOf(quot;*/quot;))+quot;)quot;); my.oEvent.onContactLoadReturn(payload);
  • 54. What about JavaScript Hijacking? <package name=quot;my-defaultquot; extends=quot;json-defaultquot;> <result-types> <result-type name=quot;jsonquot; class=quot;com.googlecode.jsonplugin.JSONResultquot; default=quot;truequot;> <param name=quot;wrapWithCommentsquot;>true</param> </result-type> </result-types> <action name=quot;contact-loadquot; class=quot;actions.ContactLoadActionquot;> <result /> </action> </package>
  • 55.
  • 56. Ajax on Struts What are Ajax widgets? What are we coding? Is there an Ajax architecture? How can we switch to server-side data? What about error-handling?
  • 57. What about error handling? var callback = { success : function(o) { var payload = eval(quot;(quot; + o.responseText + quot;)quot;); my.oEvent.onContactLoadReturn(payload); } }; YAHOO.util.Connect.asyncRequest('POST', quot;contact- load.doquot;, callback, null);
  • 58. What about error handling? var callback = { success: function(o) {/*success handler code*/}, failure: function(o) {/*failure handler code*/}, argument: [argument1, argument2, argument3] }
  • 59. How does JSON-RPC handle errors? { quot;versionquot; : quot;1.1quot;, quot;errorquot; : { quot;namequot; : quot;JSONRPCErrorquot;, quot;codequot; : 123, quot;messagequot; : quot;An error occurred parsing the request object.quot;, quot;errorquot; : { quot;namequot; : quot;JSONErrorquot;, quot;messagequot; : quot;Bad arrayquot;, quot;atquot; : 42, quot;textquot; : quot;{quot;idquot;:1,quot;methodquot;:quot;sumquot;,quot;paramsquot;:[1,2,3,4,5}quot;} } }
  • 60. How does Struts handle exceptions? <global-results> <result name=quot;errorquot;/> </global-results> <global-exception-mappings> <exception-mapping exception=quot;java.lang.Exceptionquot; result=quot;errorquot;/> </global-exception-mappings>
  • 61. How does Struts handle exceptions? <h2>An unexpected error has occurred</h2> <p>Please report this error to your system administrator or appropriate technical support personnel. Thank you for your cooperation.</p> <hr/> <h3>Error Message</h3> <p> <s:property value=quot;%{exception.message}quot;/> </p> <hr/> <h3>Technical Details</h3> <p> <s:property value=quot;%{exceptionStack}quot;/> </p>
  • 62. How does Struts handle exceptions? public String getExceptionMessage() { ActionContext context = ActionContext.getContext(); Object value = context.getValueStack(). findValue(quot;exception.messagequot;); if (value==null) return null; return value.toString(); } public String getExceptionStack() { ActionContext context = ActionContext.getContext(); Object value = context.getValueStack(). findValue(quot;exceptionStackquot;); if (value==null) return null; return value.toString(); }
  • 63. How does Struts handle exceptions? public String execute() throws Exception { throw new Exception(quot;Whoops!quot;); // return quot;successquot;; } getExceptionMessage :” “Whoops!” getExceptionStack: “java.lang.exception Whoops! at actions.ContactLoadAction ...
  • 64. How do widgets handle errors? <!-- ... --> </div> <div id=quot;elErrorquot; class=quot;errorquot;></div> <div <!-- ... -->
  • 65. How do widgets handle errors? my.asyncRequestException = function (o) { alert(quot;Error Communicating with Server! See message area for details.quot;); var sTemplate = quot;<table> <tr><th>Message:&nbsp;</th> <td>{exceptionMessage}</td></tr> <tr><th>Location:</th> <td>{exceptionStack}</td></tr> </table>quot;; var oPayload = eval(quot;(quot; + o + quot;)quot;) ; document.getElementById(quot;elErrorquot;).innerHTML = sTemplate.supplant(oPayload);
  • 66. How do widgets handle errors?
  • 67. What about error handling? var onContentReady = function() { _Contact = new MY.Contact(); my.oEvent.subscribe(quot;contactLoadquot;,_Contact.load, _Contact); // YAHOO.util.Connect.asyncRequest('POST', quot;contact- load.doquot;, callback, null); my.asyncRequest(quot;contact-load.doquot;, my.oEvent.onContactLoadReturn); };
  • 68. my.asyncRequest = function (sAction, fnCallback) { return YAHOO.util.Connect.asyncRequest(quot;POSTquot;, sAction, { success : function(o) { var oPayload = eval(quot;(quot; + o.responseText + quot;)quot;) ; fnCallback(oPayload); } }); };
  • 69. my.asyncRequest = function (sAction, fnCallback) { return YAHOO.util.Connect.asyncRequest(quot;POSTquot;, sAction, { success : function(o) { var oPayload = eval(quot;(quot; + o.responseText + quot;)quot;) ; if (oPayload.exceptionMessage) { my.asyncRequestException(oPayload); } fnCallback(oPayload); } }); };
  • 70. my.asyncRequestException = function (oPayload) { my.errorMessage(oPayload.exceptionMessage, oPayload.exceptionStack); }; my.errorMessage = function (sMessage, sStackTrace) { alert(quot;Error Communicating with Server! // ... var sTemplate = quot;<table><tr> // ... var oContext = {message: sMessage, stackTrace: sStackTrace}; document.getElementById(quot;elErrorquot;).innerHTML = sTemplate.supplant(oContext); my.isMessage(true); my.error(oContext); };
  • 71.
  • 72.
  • 73. Is that all there is? During this session, we covered Integrating an Ajax UI with Struts 2 Using Yahoo User Interface (YUI) Library Using Struts to provide services to Ajax U
  • 75. Whats up with Planet Yazaar? Development team Yahoo! Employees Something like Spring, Hibernate Unlike Apache projects No formal mechanism for contributions
  • 76. Whats up with Planet Yazaar? Development team Yahoo! Employees Something like Spring, Hibernate Unlike Apache projects No formal mechanism for contributions A cathderal, rather than a bazaar
  • 77.
  • 78. What's up with Planet Yazaar? Yazaar - (Yahoo + Bazaar = Yazaar) Accepts and maintains contributor extensions and documentation Working toward quot;soup to nutsquot; project documentation Public repository with version-to-version change logs
  • 79.
  • 80. What's up with Planet Yazaar? Just as an aside ... Yahoo GeoCities for public web site Uses GoogleCode for repository Google Group for mailing list and change logs Yahoo 360 for Blog
  • 81.
  • 82.
  • 83.