ajax magic in structs

Embed Size (px)

Citation preview

  • 8/14/2019 ajax magic in structs

    1/13

    Whitepapers, Consulting andProducts at

    Enterprise Project Rescue

    Business KnowledgeManagement

    Development Process

    Security, Performance andArchitecture

    Dynamic Web 2.0 Solutions

    Firstpartners.net 2005. Article may bere roduced in full with this notice.

    Add Ajax magic in your Struts Web application

    Author Biography

    Based in Dublin, Ireland, Paul Browne has been consulting in Enterprise Java with

    FirstPartners.net for almost 7 years. When not promoting the Red Piranha (Search and

    Knowledge Management) and NoUnit (Java Development Process) projects , he can be

    foundblogging online. This article was originally published on the Sun Java Website.

    Ajax is the latest revolution in web development circles, allowing rich dynamic interfaces deployed

    within a normal web browser. Struts has been one of the de-facto standards for Java-Web developmentfor a number of years, with a large amount of applications already deployed. This article is going toshow you how to combine the richness of an Ajax user interface to your existing Struts applications.

    This article shows a simple and elegant way to do this by includ-

    ing a couple of lines of Javascript on your JSP (Java Server)pages. While we show how to re-use existing Struts Actions, the

    techniques are equally applicable to the Java-Web Framework of

    your choice. The method proposed will also allow a move to thenext version of Struts (Shale) or Java Server Faces (JSF) in the fu-

    ture.

    What is Ajax?

    Ajax is a term standing for 'Asynchronous Javascript and XML'. It

    is a technique, rather than a framework (such as Struts). The reas-

    on for the 'buzz' around both it and Web 2.0 is that it allows webpages to behave less like flat documents and more like dynamic

    GUI apps that users might expect from their desktop environ-

    ments. Ajax techniques can be used for all recent browsers (in-cluding Internet Explorer and Netscape/Mozilla). It is already used

    by (among others) Microsoft (for it's Outlook web client) and Google (for its Maps and Mail applica-

    tions).

    Life Before Ajax

    Most current Struts applications follow the standard 'web page as a flat document' structure. If youwanted to mimic the behaviour GUI Desktop apps (such as those built using Java Swing, Visual Basic

    or Delphi) you had two choices; You could either send all the information that might possibly required

    FirstPartners.Net email: [email protected] Page 1 of 13

    http://www.firstpartners.net/rphttp://red-piranha.sourceforge.net/http://nounit.sourceforge.net/http://www.firstpartners.net/bloghttp://java.net/http://maps.google.com/http://mail.google.com/http://www.firstpartners.net/rphttp://red-piranha.sourceforge.net/http://nounit.sourceforge.net/http://www.firstpartners.net/bloghttp://java.net/http://maps.google.com/http://mail.google.com/
  • 8/14/2019 ajax magic in structs

    2/13

    as part the web page with (a lot of) Javascript to handle the dynamic behaviour (a slow and not very

    Enterprise Java way to do things), or you could do constant form submits back to the server (an effect-

    ive, if somewhat 'clunky' method). Ajax gives you the best of both worlds: Dynamic Web pages, butwith most of the application running in Java on your web server.

    Ajax 101

    Ajax is similar to existing Dynamic HTML techniques, with the addition of a 'background' call to theserver to get new / updated information as required. The mechanics of Ajax have already been covered

    in detail elsewhere - take a look at the resources at the bottom of this article. As an 'Ajax 101' the min-

    imum you need to know is:

    1. The XMLHttpRequest (or Microsoft.XMLHTTP ActiveX object if you are using InternetExplorer). These objects can be called from the Javascript on your web page. Theyallow you to request content from your web server as a background call (i.e. the screendoes not 'go blank' as usually happens during a form submit).

    2. The content that the XMLHttpRequest and Microsoft.XMLHTTP objects return can be treatedas either XML or plain text. Javascript (on your web page) can then update the pagewith this new content as required.

    3. The whole process can be triggered by the usual Javascript events - onclick, onchange,onbluretc.

    Using Ajax in your Struts application

    The chances are that if you are reading this article, then you are interested in Ajax's ability to create dy-namic web interfaces and would like to know how to add it to a Struts application. What are your

    choices if you want to do this?

    Wait until the next version of Struts (Shale) incorporates Ajax techniques. For Strutsdevelopers starting a new application this is probably the best option. The downside isthat this will probably require moving to Java Server Faces - not a bad thing in itself,but may entail fundamental changes if you have an existing application.

    You could move to a new approach, like Direct Web Remoting (DWR) or Ruby on Railsthat are specifically built for Ajax applications. While these are both very impressive

    frameworks, and are worth taking a look at if you wish to consider web developmentwithout Struts, this option would mean rewriting your entire application.

    Add Ajax to your existing Struts application. Since Ajax is a technique, not aframework, it is straightforward to add it to Struts. For existing applications wherestability (e.g. keeping existing libraries is important), this option is recommended andis the one we explore in more detail.

    FirstPartners.Net email: [email protected] Page 2 of 13

    http://c/business/sales_marketing/article-ajax/Sprinkle_some_Ajax_magic_into_your_Struts_application.html#resourceshttp://c/business/sales_marketing/article-ajax/Sprinkle_some_Ajax_magic_into_your_Struts_application.html#resources
  • 8/14/2019 ajax magic in structs

    3/13

    Some other advantages of our preferred option are:

    1. It should not require any new libraries or server side code - only the Struts libraries and

    Actions already in the application need be used.

    2. All the parts of the solution - Javascript, Xml, Java and Struts - are already widelyunderstood.

    3. The application can be migrated to Ajax piece by piece - we can identify those partswhich will most benefit users, and then choose to upgrade them to dynamic Ajaxbehaviour first.

    Implementing the Solution

    So how do we actually implement our chosen solution? Westart by reminding ourselves how a 'standard' (non-Ajax)Struts application works. In this application, the normal flow

    of events is as follows:

    1. The User requests a screen by clicking on ahyperlink or form submit.

    2. The web server runs the requested Struts Action,generating the web page.

    3. The browser displays the page.

    4. When the User presses 'Save' the information isposted to the server where it's converted by theStruts framework to an ActionForm classcontaining the posted data.

    5. As a next step, the Struts framework calls the Struts Action which then processes therequest (e.g. saves the data to a Database).

    6. The page is rendered as per item 2 and the process starts again.

    Existing Struts Application

    A simple Struts application demonstrating this flow of events can be downloaded here : struts-non-ajax.zip. This application, based on the sample applications provided with Struts, either hides or dis-

    plays blue and green tables depending on the values entered by the user. Figure 1 shows the screen on

    initial page load. Figure 2 shows the screen after the user has entered values and pressed 'submit'. Al-though simple, it is enough to demonstrate a Struts application at work.

    FirstPartners.Net email: [email protected] Page 3 of 13

    Whitepapers, Consulting andProducts at

    Enterprise Project Rescue

    Business KnowledgeManagement

    Development Process

    Security, Performance andArchitecture

    Dynamic Web 2.0 Solutions

    Firstpartners.net 2005. Article may bere roduced in full with this notice.

    http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438
  • 8/14/2019 ajax magic in structs

    4/13

    Figure 1: Non Ajax Sample - Initial Screen

    FirstPartners.Net email: [email protected] Page 4 of 13

  • 8/14/2019 ajax magic in structs

    5/13

    Figure 2: Non Ajax Sample - Values Entered, submit pressed

    The Server side code is as you would expect - a Struts Action that forwards to the (same) JSP using thevalues defined instruts-config.xml. Some other points to note in this code sample are:

    The struts-config.xmlis set up to redirect all requests to http://localhost:8080/struts-non-ajax/(or equivalent in your web server) to index.jsp

    index.jsp contains a struts form with two text boxes (showBlue and showGreen). Thepage also contains tags, but as the values for these text boxes are initallyblank, the content within them is not displayed.

    The user enters values (true or false) and presses the Submit button passing control(via the Struts Framework, reading struts-config.xml) to the SampleAction class.

    SampleAction logs the values, then forwards back to index.jsp. A more sophisticated Strutsapplication would do more, such as save / retrieve values from a database.

    index.jsp now evaluates the request - if showBlue or showGreen are true the tables willbe displayed.

    FirstPartners.Net email: [email protected] Page 5 of 13

  • 8/14/2019 ajax magic in structs

    6/13

  • 8/14/2019 ajax magic in structs

    7/13

    Figure 4 - Ajax Sample after Ajax Call

    Adding this Ajax behaviour is surprisingly easy. The server side code is the same as usual - a Struts Ac-tionForm to hold the data, a Struts Action that performs the tasks required (e.g. Database access) then for-

    wards to the appropriate JSP to display the result.

    Don't just sit there ...

    If you wish to stop reading here (and skip the explanation of how this works) then all you needto do to convert your Struts application to a Struts-Ajax application in a similar manner are:

    1. Include the Ajax.js Javascript file on your web page (this file is part of the struts-ajax.zip sample file).Ajax.js contains all the Javascript functions necessary to send andreceive Ajax calls.

    2. Ensure the parts of the web page that you wish to update during Ajax calls aresurrounded by tags, giving each an id.

    3. When something happens that should update the page (e.g. the onchange() method of atextbox), call the retrieveURL() function, passing in the URL to the Struts Action thatwill do the necessary server-side processing.

    FirstPartners.Net email: [email protected] Page 7 of 13

    http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438
  • 8/14/2019 ajax magic in structs

    8/13

    Whitepapers, Consulting andProducts at

    Enterprise Project Rescue

    Business KnowledgeManagement

    Development Process

    Security, Performance andArchitecture

    Dynamic Web 2.0 Solutions

    Firstpartners.net 2005. Article may bere roduced in full with this notice.

    4. For page display/ update the easiest option is for the Struts Action to forward back tothe same JSP. In our sample, we trigger the Ajax call in the onchange() method of the

    showGreen / showBlue textboxes.The Javascript function retrieveURL() calls Struts on the server (via the URL provided), takes the JSP re-

    sponse and updates the web page being displayed where the tags on the existing web page match

    those on the newly returned JSP. Simple!

    The Ajax Solution in more detail

    When we converted the previous sample into an Ajax-Struts application we made threechanges:

    1. Added a Javascript function to do the 'Behind the Scenes' Ajax call to the server.

    2. Added Javascript code to receive the server response and update the web page.

    3. Added tags to the JSP page which mark sections that will be updated during Ajaxcalls.

    We will look at each of these in more detail.

    Making the Ajax Call to Server

    There are two functions (listed below) that are used to callthe server.

    The retrieveURL() function takes a parameter of theURL of the server and the name of the Struts form.The URL will be called using Ajax and the values ofthe form passed to the server.

    getFormAsString() is a function which converts the values on the form named in retrieveURL(), into aquery string suitable for posting to Struts on theserver.

    To use simply add the retrieveURL() function to the onclick() / on-

    Change() method of the event you wish to trigger the screen up-

    date.

    There are some interesting items going on in both methods.

    Within the retrieveURL() method, the line req.onreadystatechange = processStateChange (note - no brackets)

    tells the browser to call theprocessStateChange() method (which we talk through later in this article) oncethe server sends back its response. This method (now standard in Ajax) also determines whether it

    FirstPartners.Net email: [email protected] Page 8 of 13

  • 8/14/2019 ajax magic in structs

    9/13

    should use the Internet Explorer (ActiveX) or Netscape/Mozilla (XmlHttpRequest) object to ensure cross-

    browser compatibility.

    The getFormAsString() method converts the HTML form into a string to be appended to the url (which al-lows us to do a HTTP Get request). This string is escaped (e.g. spaces are converted to %20) and is in a

    format that Struts can use to populate an ActionForm (without Struts being aware of the special Ajaxnature of the request). Note that while we use a HTTP GET in this sample it would be equally possible

    to use a HTTP POST by looping in a similar manner and adding the form fields to the request.

    function retrieveURL(url,nameOfFormToPost) {

    //convert the url to a string

    url=url+getFormAsString(nameOfFormToPost);

    //Do the Ajax call

    if (window.XMLHttpRequest) {

    // Non-IE browsers

    req = new XMLHttpRequest();

    req.onreadystatechange = processStateChange;

    try {

    req.open("GET", url, true);

    } catch (e) {alert("Server Communication Problem\n"+e);

    }

    req.send(null);

    } else if (window.ActiveXObject) {

    // IE

    req = new ActiveXObject("Microsoft.XMLHTTP");if (req) {req.onreadystatechange=processStateChange;

    req.open("GET", url, true);

    req.send();

    }

    }

    }

    getFormAsString() a 'private' method used by the retrieveURL() method.function getFormAsString(formName){

    //Setup the return String

    returnString ="";

    //Get the form values

    formElements=document.forms[formName].elements;

    //loop through the array, building up the url

    //in the format '/strutsaction.do&name=value'

    for(var i=formElements.length-1;i>=0; --i ){

    FirstPartners.Net email: [email protected] Page 9 of 13

  • 8/14/2019 ajax magic in structs

    10/13

    //we escape (encode) each value

    returnString+="&" _

    +escape(formElements[i].name)+"=" _

    +escape(formElements[i].value);}

    //return the values

    return returnString;}

    Updating the web page with the Ajax response

    So far we have looked at the Javascript to do the Ajax call (listed above), and the Struts Action, Action-

    Form and JSP (mostly the same, with the addition of tags). To complete our understanding of the

    the Struts-Ajax project, we need to look at the 3 Javascript functions that are responsible for updatingthe current web page when the results from the server are received.

    processStateChange() - the method name that we set before making the Ajax call. Thismethod is called by the XMLHttpRequest / Microsoft.XMLHTTP object once the server hascompleted sending back it's response.

    splitTextIntoSpan() - loops through the response, picking out an array of NewContentelements.

    replaceExistingWithNewHtml() - loops through this array of span elements, searching for elements in the existing page with 'someName' and replacing them with the new

    content from the server. Note that we get the returned content via req.responseText forrobustness (i.e. any text response can be manipulated), rather than req.responseXml(which is more powerful but requires that you return valid XHTML or XML).

    function processStateChange() {

    if (req.readyState == 4) { // Complete

    if (req.status == 200) { // OK response

    //Split the text response into Span elements

    spanElements = _

    splitTextIntoSpan(req.responseText);

    //Use these span elements to update the page

    replaceExistingWithNewHtml(spanElements);

    } else {

    alert("Problem with server response:\n " _

    + req.statusText);

    }

    }

    }

    FirstPartners.Net email: [email protected] Page 10 of 13

  • 8/14/2019 ajax magic in structs

    11/13

  • 8/14/2019 ajax magic in structs

    12/13

    indexOf("

  • 8/14/2019 ajax magic in structs

    13/13

    or part) need to be sent to the browser. By setting flags in either the web serversession orActionForm the JSP page knows which sections need to be rendered. .

    Within the JSP, use Struts or JSTL tags to decide if we need to render asection of HTML or not.

    An updated version of this project, with Ajax enabled, can be downloaded here struts-Ajax.zip

    Conclusion

    Ajax techniques promise to completely revolutionise how we build and use web applications. This art-

    icle showed a simple technique to add Ajax behaviour to existing Struts applications. It allows us to re-

    use our existing investment, not only in code but also in developer skills. As a nice by product, it alsoallows us to write cleaner, more reusable, Java Struts applications.

    Resources

    Sample code for this article

    Definition of Ajax

    Article: Using Ajax to catch Javascript errors

    Ajax and DWR (Java.net Article)

    BEA Ajax article

    IBM article on using Ajax with Webservices

    O'Reilly Article - Ruby on Rails

    DWR - Direct Web Remoting Project

    Struts Framework Project

    JSF - Java Server Faces Project

    FirstPartners.Net email: [email protected] Page 13 of 13

    http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://www.adaptivepath.com/publications/essays/archives/000385.phphttp://www.adaptivepath.com/publications/essays/archives/000385.phphttp://www.xml.com/pub/a/2005/05/11/Ajax-error.htmlhttp://www.xml.com/pub/a/2005/05/11/Ajax-error.htmlhttp://today.java.net/pub/a/today/2005/08/25/dwr.htmlhttp://today.java.net/pub/a/today/2005/08/25/dwr.htmlhttp://dev2dev.bea.com/pub/a/2005/08/Ajax_introduction.htmlhttp://dev2dev.bea.com/pub/a/2005/08/Ajax_introduction.htmlhttp://www-128.ibm.com/developerworks/webservices/library/ws-Ajax1/http://www-128.ibm.com/developerworks/webservices/library/ws-Ajax1/http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_Ajax.htmlhttp://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_Ajax.htmlhttps://dwr.dev.java.net/https://dwr.dev.java.net/http://struts.apache.org/http://struts.apache.org/http://java.sun.com/j2ee/javaserverfaces/http://java.sun.com/j2ee/javaserverfaces/mailto:FirstPartners.Netmailto:[email protected]://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://sourceforge.net/project/showfiles.php?group_id=99476&package_id=158438http://www.adaptivepath.com/publications/essays/archives/000385.phphttp://www.xml.com/pub/a/2005/05/11/Ajax-error.htmlhttp://today.java.net/pub/a/today/2005/08/25/dwr.htmlhttp://dev2dev.bea.com/pub/a/2005/08/Ajax_introduction.htmlhttp://www-128.ibm.com/developerworks/webservices/library/ws-Ajax1/http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_Ajax.htmlhttps://dwr.dev.java.net/http://struts.apache.org/mailto:FirstPartners.Netmailto:[email protected]://java.sun.com/j2ee/javaserverfaces/