SlideShare une entreprise Scribd logo
1  sur  84
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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 .
 

Tendances (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
 

En vedette (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
 

Similaire à 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
 

Similaire à 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
 

Plus 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
 

Plus 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
 

Dernier

BeMetals Investor Presentation_May 3, 2024.pdf
BeMetals Investor Presentation_May 3, 2024.pdfBeMetals Investor Presentation_May 3, 2024.pdf
BeMetals Investor Presentation_May 3, 2024.pdfDerekIwanaka1
 
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...meghakumariji156
 
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...ssuserf63bd7
 
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Oman
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in OmanMifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Oman
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Omaninstagramfab782445
 
Power point presentation on enterprise performance management
Power point presentation on enterprise performance managementPower point presentation on enterprise performance management
Power point presentation on enterprise performance managementVaishnaviGunji
 
Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration PresentationUneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentationuneakwhite
 
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...Falcon Invoice Discounting
 
Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024Marel
 
Cracking the 'Career Pathing' Slideshare
Cracking the 'Career Pathing' SlideshareCracking the 'Career Pathing' Slideshare
Cracking the 'Career Pathing' SlideshareWorkforce Group
 
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdf
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdfTVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdf
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdfbelieveminhh
 
PHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation FinalPHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation FinalPanhandleOilandGas
 
Buy Verified TransferWise Accounts From Seosmmearth
Buy Verified TransferWise Accounts From SeosmmearthBuy Verified TransferWise Accounts From Seosmmearth
Buy Verified TransferWise Accounts From SeosmmearthBuy Verified Binance Account
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwaitdaisycvs
 
Phases of Negotiation .pptx
 Phases of Negotiation .pptx Phases of Negotiation .pptx
Phases of Negotiation .pptxnandhinijagan9867
 
Cannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 UpdatedCannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 UpdatedCannaBusinessPlans
 
CROSS CULTURAL NEGOTIATION BY PANMISEM NS
CROSS CULTURAL NEGOTIATION BY PANMISEM NSCROSS CULTURAL NEGOTIATION BY PANMISEM NS
CROSS CULTURAL NEGOTIATION BY PANMISEM NSpanmisemningshen123
 
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All Time
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All TimeCall 7737669865 Vadodara Call Girls Service at your Door Step Available All Time
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All Timegargpaaro
 

Dernier (20)

BeMetals Investor Presentation_May 3, 2024.pdf
BeMetals Investor Presentation_May 3, 2024.pdfBeMetals Investor Presentation_May 3, 2024.pdf
BeMetals Investor Presentation_May 3, 2024.pdf
 
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...
Escorts in Nungambakkam Phone 8250092165 Enjoy 24/7 Escort Service Enjoy Your...
 
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...
Horngren’s Cost Accounting A Managerial Emphasis, Canadian 9th edition soluti...
 
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Oman
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in OmanMifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Oman
Mifepristone Available in Muscat +918761049707^^ €€ Buy Abortion Pills in Oman
 
Buy gmail accounts.pdf buy Old Gmail Accounts
Buy gmail accounts.pdf buy Old Gmail AccountsBuy gmail accounts.pdf buy Old Gmail Accounts
Buy gmail accounts.pdf buy Old Gmail Accounts
 
Power point presentation on enterprise performance management
Power point presentation on enterprise performance managementPower point presentation on enterprise performance management
Power point presentation on enterprise performance management
 
Uneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration PresentationUneak White's Personal Brand Exploration Presentation
Uneak White's Personal Brand Exploration Presentation
 
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...
Unveiling Falcon Invoice Discounting: Leading the Way as India's Premier Bill...
 
Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024Marel Q1 2024 Investor Presentation from May 8, 2024
Marel Q1 2024 Investor Presentation from May 8, 2024
 
Cracking the 'Career Pathing' Slideshare
Cracking the 'Career Pathing' SlideshareCracking the 'Career Pathing' Slideshare
Cracking the 'Career Pathing' Slideshare
 
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
 
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdf
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdfTVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdf
TVB_The Vietnam Believer Newsletter_May 6th, 2024_ENVol. 006.pdf
 
PHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation FinalPHX May 2024 Corporate Presentation Final
PHX May 2024 Corporate Presentation Final
 
HomeRoots Pitch Deck | Investor Insights | April 2024
HomeRoots Pitch Deck | Investor Insights | April 2024HomeRoots Pitch Deck | Investor Insights | April 2024
HomeRoots Pitch Deck | Investor Insights | April 2024
 
Buy Verified TransferWise Accounts From Seosmmearth
Buy Verified TransferWise Accounts From SeosmmearthBuy Verified TransferWise Accounts From Seosmmearth
Buy Verified TransferWise Accounts From Seosmmearth
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
 
Phases of Negotiation .pptx
 Phases of Negotiation .pptx Phases of Negotiation .pptx
Phases of Negotiation .pptx
 
Cannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 UpdatedCannabis Legalization World Map: 2024 Updated
Cannabis Legalization World Map: 2024 Updated
 
CROSS CULTURAL NEGOTIATION BY PANMISEM NS
CROSS CULTURAL NEGOTIATION BY PANMISEM NSCROSS CULTURAL NEGOTIATION BY PANMISEM NS
CROSS CULTURAL NEGOTIATION BY PANMISEM NS
 
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All Time
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All TimeCall 7737669865 Vadodara Call Girls Service at your Door Step Available All Time
Call 7737669865 Vadodara Call Girls Service at your Door Step Available All Time
 

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.