Ajaxian Faces with David Geary
David wrote both Graphic Java Swing and Core JavaServer Faces (with Cay Horstmann). Both of these were best sellers on Java component frameworks. Not only that, but he's fun to talk to and lives just south of me in Colorado.
Agenda: Ajaxian Faces Essentials, Roadmap, Form Completion, Realtime Validation, Ajaxian Components, Ajax with Shale and Prototype.
Enterprise Java and Ajax: you invoke a URL from the client (XHR), then handle the URL on the server. This handling is usually done by a servlet, filter or a JSF phase listener. These return HTML or XML to the client. Then the client merges the response into the DOM on the client.
JSF and Ajax: JSF is an excellent framework for Ajax. Why? Because of its component model: GET and POST requests are supported and it has custom components and renderers. Furthermore, JSF has lifecycle and event handlers - phase listeners and allows complete control over the lifecycle.
Common Ajaxian use cases: form completion, realtime validation, polling (progress indicators, realtime search, etc.), ajax components and frameworks. In this talk, we'll be covering JSF (POSTs and GETs), JSF and JavaScript, how to control the JSF lifecycle, JSF client ids vs. component ids, accessing view state, and many other things.
Arm yourself with tools: Firefox with the Web Developer Toolbar. Most helpful features: outlining block elements and DOM inspector. Debuggers on client and server: IDEA on the server, Venkman on the server.
Good Resources: Java EE Blueprints, Ajax Magazine and MSDN.
JSF and JavaScript: The HTML component tags have all the event handlers built-in: onclick, onblur, onfocus, etc.
<h:form id="form"> <h:inputText id="name"/> ... </h:form>
In the above example, the component id is "name" and the client id is "form:name". To do minimal Ajax with JSF, you can use a non-Faces object to handle the Ajax requests with a servlet or filter. All you really need to know is how to reference client ids vs. the ids you code into your view templates.
Realtime validation: to do this, you need access to the view state. Ajax will fire a component's validators, invoke a phase listener (after the Restore View phase), POST a request with XHR and utilize client-side state handling. A typical component tree for a form consists of a UIViewRoot, an HtmlOuputText (instructions for form) an HtmlForm and an HtmlPanelGrid that contains all of the input components.
The JSF Lifecycle: Restore View -> Apply Request Values -> Process Validations -> Update Model -> Invoke Application -> Render Response. You have to do a post with JSF, otherwise the view state won't be available.
To register a phase listener, you merely declare it in your faces-config.xml file. There's a PhaseListener interface that defines 3 methods: getPhaseId(), beforePhase() and afterPhase(). In this example, getPhaseId() returns PhaseId.RESTORE_VIEW and beforePhase() isn't implemented; afterPhase() is used. David then checks for an "ajax" parameter. If it's sent in the request, he grabs the component to validate and invokes all its validators. One of the nice things about JSF is you can modify your client-side components on the server-side. You can also use JavaScript on the client-side to grab the hidden client-side state-saving field and send it with an Ajax request to maintain state.
JSF Ajax Components: To create JSF Ajax components, you'll want to put your JavaScript into a separate file. In the component's renderer, you'll write a <script> tag that uses a JSF page as its "src" element. Then you use a PhaseListener that looks for the URI invoked by "src" and handle it appropriately. Now David is showing us how you need to create a component, a Tag and a Renderer to create an Ajax component. The Tag and the Renderer write out JavaScript functions that do the magic stuff. Finally, you'll need to create a JavaScript file that contains the functions to be called. At this point, ragged on Geary a bit for creating a simple component with 3 Java classes + a .js file.
Rather than writing all this low-level JavaScript code yourself, you can simplify development with JSF and Ajax by using Struts Shale. Features of Shale include.
- Web flow
- Remote method calls
- Tiger extensions
- Integration with: Spring, Tiles, JNDI
- View controllers
- Testing framework
- HTML views (a.l.a. Tapestry and Facelets)
David gave a quick preview of Shale and showed how much easier it makes Ajax. Basically, you give a specialized URL on your client - and using a syntax of "dynamic/managedBeanName/method", it calls that method on the server. Pretty cool stuff, but doesn't seem a whole lot different from what DWR offers for JSF. "Shale is a proving ground for JSF 2.0, hopefully all its add-ons will make it into the next version of the spec." When David says stuff like this, I'm tempted to use Shale in AppFuse for its JSF support - especially since Shale can work with any JSF implementation (1.1 RI, MyFaces or 1.2 RI).
As usual, this was a good talk by David. He's always entertaining and fun to harass.
Posted by John on May 13, 2006 at 10:29 AM MDT #
Posted by Jacob on May 13, 2006 at 02:43 PM MDT #
Posted by Rick Hightower on May 15, 2006 at 06:58 PM MDT #