DWR Presentation
-
Upload
singhmanav77 -
Category
Documents
-
view
69 -
download
1
Transcript of DWR Presentation
![Page 1: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/1.jpg)
Ajax for Java developers… but without the suckage
![Page 2: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/2.jpg)
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.)
![Page 3: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/3.jpg)
Open with a joke!
![Page 4: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/4.jpg)
Cool, we can all go home now…
![Page 5: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/5.jpg)
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
![Page 6: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/6.jpg)
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
![Page 7: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/7.jpg)
That horse was askin’ for it!
![Page 8: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/8.jpg)
Oh the humanity!
![Page 9: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/9.jpg)
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)
![Page 10: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/10.jpg)
An RIA (and a real looker of an ET!)
![Page 11: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/11.jpg)
Another RIA
![Page 12: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/12.jpg)
One more for good measure
![Page 13: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/13.jpg)
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
![Page 14: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/14.jpg)
Build or buy?
![Page 15: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/15.jpg)
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
![Page 16: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/16.jpg)
RPC mystified
(someone told me lots of pictures in a slideshow is a good idea, even superfluous ones like this!)
![Page 17: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/17.jpg)
DWR’s brand of RPC
![Page 18: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/18.jpg)
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
![Page 19: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/19.jpg)
DWR In a nutshell
![Page 20: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/20.jpg)
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>
![Page 21: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/21.jpg)
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>
![Page 22: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/22.jpg)
The basics, part 2a
![Page 23: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/23.jpg)
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; }
}
![Page 24: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/24.jpg)
The basics, part 4
Some client-side code to call it:
![Page 25: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/25.jpg)
<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>
![Page 26: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/26.jpg)
Mmmm… pudding… AGHHAGGAGHAGAGA
(note to self: need to spell-check Homer Simpson biological drooling sound above)
math
![Page 27: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/27.jpg)
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
![Page 28: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/28.jpg)
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!”); }});
![Page 29: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/29.jpg)
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
![Page 30: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/30.jpg)
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
![Page 31: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/31.jpg)
(anyone not impressed can leave their geek credentials at the door on the way out)
debugging
![Page 32: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/32.jpg)
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!
![Page 33: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/33.jpg)
Security-security-security-security… Security-security-security-security!
![Page 34: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/34.jpg)
Threats aren’t always as cute as this
![Page 35: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/35.jpg)
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
![Page 36: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/36.jpg)
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>
![Page 37: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/37.jpg)
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
![Page 38: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/38.jpg)
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
![Page 39: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/39.jpg)
Beans, beans, they’re good for your heart, part 1
package app;
public class SearchVO {
private String acctNum;
public void setAcctNum(String acctNum) { this.acctNum = acctNum; }
public String getAcctNum() { return this.acctNum; }
}
![Page 40: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/40.jpg)
Beans, beans, they’re good for your heart, part 2
package app;
public class Account {
private String acctNum; private String shareholder; private Integer balance;
public void setAcctNumber(String acctNum) { this.acctNum = acctNum; } public String getAcctNum() { return this.acctNum; } public void setShareholder(String sh) { this.shareholder = sh; } public String getShareholder() { return this.shareholder; } public void setBalance(Integer balance) { this.balance = balance; } public Integer getBalance() { return this.balance; }
}
![Page 41: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/41.jpg)
Beans, beans, they’re good for your heart, part 3
package app;
public class Processor {
public Account getAccount(SearchVO searchVO) {
Account account = new Account(); account.setAcctNum(searchVO.getAcctNum()); account.setShareholder("Tapping, Amanda"); account.setBalance(new Integer(25986)); return account;
}
}
![Page 42: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/42.jpg)
Beans, beans, they’re good for your heart, part 4
<?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>
<convert converter="bean" match="app.SearchVO" /> <convert converter="bean" match="app.Account" />
<create creator="new“ javascript=“Processor”> <param name="class" value="app.Processor" /> </create>
</allow>
</dwr>
![Page 43: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/43.jpg)
Beans, beans, they’re good for your heart, part 5
Here thar be JavaScript too:
![Page 44: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/44.jpg)
<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>
![Page 45: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/45.jpg)
(* yes, that is indeed a cheap Watchmen reference!)
account
![Page 46: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/46.jpg)
![Page 47: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/47.jpg)
![Page 48: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/48.jpg)
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
![Page 49: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/49.jpg)
I hate it when a plan doesn’t come together
![Page 50: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/50.jpg)
Error handling in DWR
• Can handle errors globally or on a per-call basis
• Warnings – Things you can usually ignore…dwr.engine.setWarningHandler(<function>)
• Errors - When DWR can tell you what went wrong (ex: server shuts down in the middle of servicing an AJAX request)…dwr.engine.setErrorHandler(<function>);
• Exceptions - Thrown from server and propagated to client. Must handle exceptions per-call…
![Page 51: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/51.jpg)
Error Handling: The Next Generation™
Processor.getAccount(accountSearchVO, { callback : function(inAccount) { dwr.util.setValue("divAccountDetails", "Account Number: " + inAccount.acctNumber + "<br>" + "Shareholder Name: " + inAccount.shareholder + "<br>" + "Current Balance: " + inAccount.balance, { escapeHtml : false } ); }, errorHandler : function(errMsg, exception) { alert(dwr.util.toDescriptiveString(exception, 4)); }});
![Page 52: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/52.jpg)
Making sense of exceptions
• Exceptions by default are not marshaled:<convert match="java.lang.Exception" converter="exception"> <param name="include" value="message,lineNumber" /></convert><convert match="java.lang.StackTraceElement" converter="bean" />
![Page 53: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/53.jpg)
(I feel so cheap for making that Lost in Space reference... UNCLEAN! UNCLEAN!)
error
![Page 54: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/54.jpg)
Are you part of the “XML is uncool” crowd?
• DWR also supports annotations:@RemoteProxypublic class WordsOfWisdom { @RemoteMethod public String getWisdom() { return “<insert something wisdom-y here>”; }}
• That’s not quite all there is to it:<servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DWRServlet</servlet-class> <init-param><param-name>classes</param-name> <param-value>app.WordsOfWisdom</param-value> </init-param></servlet>
![Page 55: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/55.jpg)
Using HTTP objects
• Sometimes a POJO isn’t enough (session):WebContext wc = WebContextFactory.get();HttpSession session = wc.getSession();
• But there’s a better way:Server:Public class Remote { public void myCallableMethod(String param, HttpSession session) { }}
Client:Remote.myCallableMethod(“test”, { callback : function(resp) { alert(resp); } });
• Reduced coupling to DWR… Syntax is cleaner… Less work (always good)• “Automagic” stuff isn’t usually good… Must call data meta-object
approach, so client-side code is arguably more verbose (slightly)
![Page 56: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/56.jpg)
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
![Page 57: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/57.jpg)
Reading from other URLs
• Read response from a URL and return as string from a method:
public class URLReader { public String read() throws ServletException, IOException { return WebContextFactory.get().forwardToString(“/another.jsp”); }}
• Allows you to continue to use all the capabilities you’re used to in JSP
• JSP becomes a (powerful) templating technology only
• Ties you to DWR• Can only do forwards, so only the same context
![Page 58: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/58.jpg)
Look out, here comes the Spring bandwagon!
• Can delegate to Spring for bean instantiation:dwr.xml:<create creator="spring" javascript="HelloHuman"> <param name="beanName" value="HelloHuman" /> <param name="location" value="spring-beans.xml" /></create>
spring-beans.xml:<?xml version="1.0" encoding="UTF-8"?>
<beans> <bean id="HelloHuman" class="app.HelloHuman" /></beans>
![Page 59: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/59.jpg)
(awww, taking it APART is so much more fun!)
alltogether
![Page 60: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/60.jpg)
When forward isn’t cool enough: Reverse Ajax
![Page 61: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/61.jpg)
If pro is the opposite of con, then isn’t 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…
![Page 62: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/62.jpg)
The three horsemen of the apocalypse, part 1: Piggybacking
Obviously not real “push”, but a decent approximation and often times “good enough”. Least resource-intensive (passive method).
![Page 63: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/63.jpg)
The three horsemen of the apocalypse, part 2: Polling
Also not real “push”, but closer than piggybacking. Medium resource utilization (active method, but controllable).
![Page 64: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/64.jpg)
Introducing New and Improved Comet!
(WARNING!! TRADEMARK INFRINGEMENT ALERT!!)
![Page 65: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/65.jpg)
The three horsemen of the apocalypse, part 3a: Let’s try this Comet thing again
As close to real “push” as you’re going to get with HTTP. It’s nothing but a hack… but an extremely clever one! (true active method)
![Page 66: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/66.jpg)
The mechanics of reverse Ajax: Piggybacking
• To activate piggybacking:
DO NOTHING!
• You can automatically piggyback on any incoming request
![Page 67: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/67.jpg)
The mechanics of reverse Ajax: Polling
• To activate polling, add to client code:dwr.engine.setActiveReverseAjax(true);
• Then, add to DWR servlet config in web.xml:<init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value></init-param><init-param> <param-name>org.directwebremoting.extend.ServletLoadMonitor</param-name> <param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value></init-param><init-param> <param-name>timeToNextPoll</param-name> <param-value>1000</param-value></init-param>
![Page 68: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/68.jpg)
The mechanics of reverse Ajax: Comet
• To activate comet, add to client code:dwr.engine.setActiveReverseAjax(true);
• Then, add to DWR servlet config in web.xml:<init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value></init-param>
![Page 69: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/69.jpg)
What about the J in JUG?!?
• From the server, do something like:Util.setValue("divRAResponse", "Hello!", true);
• All users currently viewing the page Ajax calls are sourced from will see “Hello!” in <divRAResponse>.
![Page 70: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/70.jpg)
When you don’t want to talk to just anyone
• To do something for a single user:ScriptBuffer script = new ScriptBuffer();script.appendScript(“doSomething();");WebContext wc = WebContextFactory.get();ScriptSession scriptSession = wc.getScriptSession();scriptSession.addScript(script);
• The doSomething() Javascript function will be executed in the browser of the user belonging to the session associated with the request being serviced.
![Page 71: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/71.jpg)
Running in the background
• You can spawn a background thread, and then do reverse Ajax from it
• Just need to cache the WebContext object
• Applies to communication with a single user as well as all users
• Careful! Spawning threads in a servlet contanier is bad, m’kay?
![Page 72: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/72.jpg)
(except in the case of UFOs apparently)
ra_*
![Page 73: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/73.jpg)
![Page 74: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/74.jpg)
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 don’t believe me? Ok, here you go:
![Page 75: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/75.jpg)
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);});
![Page 76: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/76.jpg)
Poor man’s web services
• DWR supports JSON, JSON-P (so-called REST-based web services)
• Allows cross-domain access to DWR remotable classes
• Allows non-DWR clients to interact with DWR-exposed remotables
• Not perfect (manual Ajax, parameter naming, etc), but still very nice!
Server:public class Demo { public String sayHi(String name) { return “Hi there, “ + name; }}
Command Line:$ wget http://localhost/app/dwr/jsonp/Demo/sayHi?param0=Frank&callback=jsfunc
-> jsfunc(“Hi there, Frank”);
![Page 77: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/77.jpg)
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”);
![Page 78: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/78.jpg)
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);
![Page 79: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/79.jpg)
Tie-ins with Dojo and others
• Dojo data stores
• Server-side manipulation of Dijits
• Deep Tibco General Interface (nearly full control of the entire UI from the server)
![Page 80: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/80.jpg)
Reverse Ajax upgrades
• More scalable (maybe), more robust API
// Broadcast to all users currently viewing index.html page.Browser.withCurrentPage(“index.html”, new Runnable() { public void run() { Window.alert(“Hello”); }});
// Broadcast to everyone connected to DWR, regardless of current page.Browser.withAllSessions(…);
// Broadcast to a filtered subset of users.Browser.withFiltered(scriptSessionFilter, …);
// Broadcast to a specific user.Browser.withSession(sesssionID, …);
![Page 81: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/81.jpg)
Reverse Ajax upgrades continued
• The server-side API is more robust, allowing for easier manipulation of the client from server code:
Element e = doc.createElement(“p”);ScriptSessions.addFunctionCall(“document.body.appendChild”, e);
ScriptSessions.addScript(“alert(‘Hello Zark!’);”);
Document.setCookie(new Cookie(“name”, “value”));
String[] opts = new String[] { “Kruger”, “Myers”, “Vorhees” };Util.addOptions(“li”, opts);
Effect.fade(“someID”);
![Page 82: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/82.jpg)
In conclusion
• DWR kicks more arse than anything that has ever kicked arse before (and that’s only a slight exaggeration!)- simple, robust, powerful, secure*
• In short: if you’re 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!
![Page 83: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/83.jpg)
If you don’t use DWR, you might be as dumb as her
(at least she has looks… and BTW, mad props to Mario for not cracking up big-time!)
![Page 84: DWR Presentation](https://reader034.fdocuments.in/reader034/viewer/2022052205/543e9b03afaf9f215e8b4855/html5/thumbnails/84.jpg)
(And if you’d like to contact me after the show I’d be… err, surprised actually… but if you do: [email protected])