Professional Documents
Culture Documents
Oh the humanity!
Another RIA
Build or buy?
RPC mystified
(someone told me lots of pictures in a slideshow is a good idea, even superfluous ones like this!)
DWR In a nutshell
<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
(note to self: need to spell-check Homer Simpson biological drooling sound above)
Call syntax
Two ways basic:
MathDelegate.add(2, 2, function(serverResponse) { alert(serverResponse); });
debugging
(anyone not impressed can leave their geek credentials at the door on the way out)
Security-security-security-security Security-security-security-security!
By default, all methods are available In production you probably should always use the above paradigm
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
Converters
Converters marshal beans from Java to JavaScript, and vice-versa Out of the box: boolean, byte, short, int, long, float, double, char, java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double, java.lang.Character, java.lang.BigInteger, java.lang.BigDecimal, java.lang.String, arrays, collections and maps of most types, enum, java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp bean and object converters, most frequently used (object works with data members directly, bean uses accessors/mutators) You can of course create your own too
<html><head> <script type="text/javascript" src="dwr/interface/Processor.js"></script> <script type="text/javascript" src="dwr/engine.js"></script> <script type="text/javascript" src="dwr/util.js"></script> <script> function doSearch() { var accountSearchVO = { acctNum : document.getElementById("acctNum").value }; Processor.getAccount(accountSearchVO, { callback : function(inAccount) { dwr.util.setValue("divAccountDetails", "Account Number: " + inAccount.acctNum + "<br>" + "Shareholder Name: " + inAccount.shareholder + "<br>" + "Current Balance: " + inAccount.balance, { escapeHtml : false } ); }}); } </script> </head><body> Account Number: <input type="text" id="acctNum"> <input type="button" value="Get Account" onClick="doSearch();"><br><br> <div id="divAccountDetails"></div> </body></html>
account
dwr.util
General-purpose client utilities, mostly concerned with getting content into the DOM, in no way DWR-specific addOptions() Add elements to lists (ol, ul, select) addRows() Add rows to tables byId() Shortcut to document.getElementById() getText() Get text (not value) of an <option> element getValue()/getValues() Get value of virtually any HTML element (it deals with the specifics of what value means for each) removeAllOptions() Remove all <option> from a <select> or ol/ul element removeAllRows() Remove all rows from a table setValue()/setValues() The reverse of getValue() toDescriptiveString() Output an object in a useful way
error
(I feel so cheap for making that Lost in Space reference... UNCLEAN! UNCLEAN!)
Call batching
Can combine multiple operations in one:
dwr.engine.beginBath(); BatchCallClass.method1(callback1); BatchCallClass.method2(callback2); SomeOtherClass.method2(callback3); dwr.engine.endBath(); function callback1() { alert(callback1); } function callback2() { alert(callback2); } function callback3() { alert(callback3); }
One network request made Order of calls and callback execution is guaranteed Lets you keep code separated on the server while maximizing runtime efficiency
Allows you to continue to use all the capabilities youre used to in JSP JSP becomes a (powerful) templating technology only Ties you to DWR Can only do forwards, so only the same context
alltogether
If pro is the opposite of con, then isnt progress the opposite of congress?!?
Server-push Difficult to implement on your own (thank you DWR!) Passive and active modes gives you lots of flexibility Active mode (comet specfically) chews up threads on server and proxies Good in small-scale apps, use with extreme caution beyond that (depending on method) Special servers/extensions exist to alleviate scalability concerns (depending on method) Speaking of methods
Obviously not real push, but a decent approximation and often times good enough. Least resource-intensive (passive method).
Also not real push, but closer than piggybacking. Medium resource utilization (active method, but controllable).
The three horsemen of the apocalypse, part 3a: Lets try this Comet thing again
As close to real push as youre going to get with HTTP. Its nothing but a hack but an extremely clever one! (true active method)
DO NOTHING!
You can automatically piggyback on any incoming request
All users currently viewing the page Ajax calls are sourced from will see Hello! in <divRAResponse>.
The doSomething() Javascript function will be executed in the browser of the user belonging to the session associated with the request being serviced.
ra_*
Binary files
Can handle binary files (up and down) Can deal with byte[], java.awt.BufferedImage, java.io.inputStream or org.directwebtemoting.io.FileTransfer (gives access to filename, mime type and contents) Uploading: Easier than commons-fileupload or similar and can integrate with progress bar widgets Downloading: easier than creating a special PDF servlet or similar What, you dont believe me? Ok, here you go:
Server: public class Remote { public void recieveFile(byte[] f) { /* Do something with contents. */ } public FileTransfer getFile() { // buf if a ByteArayOutputStream with the contents of a PDF in it. return new FileTransfer(myFile.pdf, application/pdf, buf.toByteArray()); } } Client: <input type=file id=myFile> // Send file. var f = dwr.util.getValue(myFile); Remote.recieveFile(f); // Receive file. Remote.getFile(null, function(pdf) { dwr.engine.openInDownload(pdf); });
Varargs
Avoids wrapping arguments in an array, collection or VO Can break edge cases when mixing servlet parameters and regular parameters
Server: public class VarArgClass { public void meth(String arg) { /* Do something */ } } Client: VarArgClass.meth(Apollo, Starbuck, Boomer);
Overloaded methods
Prior to v3, overloaded methods were indeterminate (might get the right one, might not) Finally, in v3, true overloading support is present!
Server: public class Remoted { public void method(int num) { System.out.println(num: + num); } public void method(String str) { System.out.println(str: + str); } } Client: Remoted.method(I am a string); Remoted.method(42);
In conclusion
DWR kicks more arse than anything that has ever kicked arse before (and thats only a slight exaggeration!)- simple, robust, powerful, secure* In short: if youre a Java developer who does Ajax, and you do it with something other than DWR, you almost certainly want marijuana legalized! To sum it all up succinctly
* and the opposite sex will find you more attractive for using it!
(at least she has looks and BTW, mad props to Mario for not cracking up big-time!)
(And if youd like to contact me after the show Id be err, surprised actually but if you do: fzammetti@omnytex.com)