Ajax for Java developers… but without the suckage
Who is this jabronie? (aka: The Braggart Slide™) • Frank W. Zammetti • Developer/Lead/Architect/Whatever for PNC Global Investment Servicing • Author of four books (fifth coming soon) and a couple of articles, tech reviewer on a number of other books • Creator of Java Web Parts (APT most “famously”) and Struts-WS • Current lead of DataVision • One of the original developers of PocketHobbit • Contributor to other OSS projects (Struts, Commons, etc.)
Open with a joke! • We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true. – Robert Wilensky • The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents. – Nathaniel Borenstein • Well, thanks to the Internet, I'm now bored with sex. – Philip J. Fry • The Internet? Is that thing still around? – Homer Simpson • The ability to quote is a serviceable substitute for wit. – W. Somerset Maugham
Ajax (for those residing in rock abodes) • Asynchronous (almost always) • JavaScript (almost always) • XML (almost never) • All about out-of-band requests and partial page loads
The beating of a dead Equine • “Jesse” James Garrett, Adaptive Path, February 2005 • IT’S NOTHING NEW!! • It’s about the concepts, not technology • In some ways, it was the saviour of the Internet
That horse was askin’ for it!
Oh the humanity!
The big question: Why Ajax? • Richer, more responsive UIs (RIAs) • Reduced network utilization (careful!) • Revolution in the guise of evolution • It’s allows for a paradigm shift (once again, RIAs) • Ajax isn’t just a communication mechanism any more (RIA == Ajax these days)
An RIA (and a real looker of an ET!)
Another RIA
One more for good measure
About that “suckage” I spoke of • Ajax is hard to get right • Many people don’t like doing JavaScript • Requires a certain expertise that not every shop has • Puts the focus on HTTP
Build or buy?
The star of the show: DWR • Open-source, licensed under the ASL • Member of the Dojo Foundation • Java-only means no design compromises • Implemented as a servlet, works fine in any container • Minimizes JavaScript and deemphasizes servlet spec • Makes calls to server-side code from JavaScript look the same as local calls • Security is a core concept, not an afterthought • Robust error handling • Integration with many popular libraries and frameworks • To put it simply: its an RPC mechanism for the Java webapps
RPC mystified (someone told me lots of pictures in a slideshow is a good idea, even superfluous ones like this!)
DWR’s brand of RPC
Yeah, but what does it actually DO? • Auto-generates a JavaScript proxy “stub” for a server-side Java object • Handles marshalling of all inbound and outbound data • Handles instantiation and calling appropriate methods of the server-side object • Transparently handles all that icky Ajax stuff
DWR In a nutshell
The basics, part 1 • Just add some JARs (dwr.jar and commons- logging.jar) and a servlet entry: <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
The basics, part 2 • dwr.xml configures it: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd"> <dwr> <allow> <create creator="new“ javascript=“MathDelegate”> <param name="class" value="app.MathDelegate" /> </create> </allow> </dwr>
The basics, part 2a
The basics, part 3 • A server-side class to call on: package app; public class MathDelegate { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { return a / b; } }
The basics, part 4 Some client-side code to call it:
<html> <head> <script type="text/javascript" src="dwr/interface/MathDelegate.js"></script> <script type="text/javascript" src="dwr/engine.js"></script> <script> function $(inID) { return document.getElementById(inID); } function doMath() { MathDelegate[$("op").value]($("num1").value, $("num2").value, function(answer) { $("divAnswer").innerHTML = answer } ); } </script> </head> <body> <input type="text" id="num1" size="4"> <select id="op"> <option value="add">+</option><option value="subtract">-</option> <option value="multiply">*</option><option value="divide">/</option> </select> <input type="text" id="num2" size="4"> <input type="button" value="=" onClick="doMath();"> <span id="divAnswer" style="font-size:18pt;"> </span><br><br> </body> </html>
math Mmmm… pudding… AGHHAGGAGHAGAGA (note to self: need to spell-check Homer Simpson biological drooling sound above)
Interfaces and the engine, and more • dwr/interface/* are where the dynamically generated JavaScript proxy stubs corresponding to remotable server classes are served from • engine.js, the client-side engine behind DWR, is mostly static but with some dynamic elements • Optionally, there’s util.js • Note that all of this is served by the DWR servlet
Call syntax • Two ways… basic: MathDelegate.add(2, 2, function(serverResponse) { alert(serverResponse); }); • Call metadata object: MathDelegate.add(2, 2, { callback : function(serverResponse) { alert(serverResponse); }, errorHandler : function() { alert(“We’re boned!”); } });
Call syntax redux • In general, use the call metadata object paradigm • Allows for passing of additional information (error handlers, options) • Basic approach might be more readable if you really only need a callback
The lost art of debugging • Set debug servlet parameter to true • http://server:port/context/dwr • Lists all classes DWR can remote as well as test harnesses and even troubleshooting tips • YOU’LL WANT TO TURN THIS OFF IN PRODUCTION
debugging (anyone not impressed can leave their geek credentials at the door on the way out)
Yeah, neat, but what of performance? • Lots of reflection magic • Dynamic code generation • You’d think performance would be terrible, but you’d be wrong! • Interface files and util.js can be saved off and served from web server to take advantage of caching • That DOES NOT work for engine.js!
Security-security-security-security… Security-security-security-security!
Threats aren’t always as cute as this
Only what you want • Only classes listed in dwr.xml can be remoted • Further, you can limit access at the method level: <create creator="new"> <param name="class" value="app.MathDelegate" /> <include method="MyMethod" /> <!-- All others now excluded --> </create> • By default, all methods are available • In production you probably should always use the above paradigm
Only who you want • Can limit access to J2EE roles at the method-level: <create creator="new"> <param name="class" value="app.MathDelegate" /> <include method="MyMethod" /> <auth method="MyMethod" role="MyRole" /> </create>
Creators • Creators instantiate remotable objects • Out of the box: new, none, spring, jsf, struts, pageflow, ejb3 • Provides for integration with other libraries • Can trivially create your own • new and none are the most commonly used
Recommend
More recommend