Ed Burns's complete blog can be found at: http://weblogs.java.net/blog/edburns/
Monday, November 23, 2009
While speaking at the Globalcode Developer's conference in Rio de Janeiro, I met a dynamic and intelligent student by the name of Thiago Diogo. Thiaogo presented his group's work on student project to provide a real, mission critical distributed application for his university, Universidade Federal Fulminense. They chose JSF 1.2 and Seam as a part of their stack.
One idea Thiaogo shared with me was a memcached JSF component. We
kicked the idea around and I mentioned it would be pretty easy to invent
a JSF component that acted like a <span> tag that
simply meant, “the rendered output of any JSF components inside of
me should come from memcached, if possible”. I don't have time to
start on this idea right now, so I thought I'd share it out here in my
blog in case anyone else wanted to pick it up, or if anyone else has
already done this! When I get time, I'll try adding it to the Mojarra
sandbox components, but in the meantime, anyone can have at it!
Technorati Tags: edburns
Thursday, October 15, 2009

The following topics and more will be covered in detail in my upcoming book with Neil Griffin, JavaServer Faces 2.0: The Complete Reference. Please enjoy this early access content!
One challenging aspect of designing JSF 2.0 was how to standardize Facelets. We wanted to standardize only the minimum amount that would still allow developers get the job done. Initially, we did not include binary custom tag handlers in the standard because most users of Facelets were simply using it to declare pages of existing UI components. Andy Schwartz and others advocated for the inclusion of a custom tag handler feature in the standard but I didn't want to just standardize what Jacob had initially done.
While Jacob's initial work for custom tag handlers was certainly effective, EG discussions with Ken Paulsen, creator of the JSFTemplating View Declaration Language led the EG to conclude that the standardization work for some of Facelets would best be left to JSF 2.1. In particular, Ken and EG member Imre Oßwald came up with something they called View Abstract Syntax Tree that would handle deeper aspects of Faces templating that they felt solved some of the flaws in the implementation of Facelets. Rather than overspecify, we came up with a simpler solution that still enables the most common usecases for custom tag handlers.
First, let's take a look at the custom.taglib.xml file. The manner
and location for this file is exactly the same as before. In this
example, (available in the Mojarra
svn repo), the file lives at
WEB-INF/classes/META-INF/custom.taglib.xml.
- <?xml version="1.0" encoding="UTF-8"?>
- <facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd" - version="2.0">
- <namespace>http://mojarra.dev.java.net/custom</namespace>
- <tag>
- <tag-name>custom1</tag-name>
- <component>
- <component-type>javax.faces.Input</component-type>
- <renderer-type>javax.faces.Text</renderer-type>
- <handler-class>com.sun.faces.facelets.custom.CustomComponentHandler1</handler-class>
- </component>
- </tag>
- </facelet-taglib>
The java code for this class is shown next. At right, you see the stack trace for a breakpoint set on line 8.
- package com.sun.faces.facelets.custom;
- import javax.faces.view.facelets.ComponentConfig;
- import javax.faces.view.facelets.ComponentHandler;
- public class CustomComponentHandler1 extends ComponentHandler {
- public CustomComponentHandler1(ComponentConfig config) {
- super(config);
- }
- }
The preceding code does nothing. But it's a start. Particurlarly useful is that ComponentConfig argument. This gives you access to a whole bunch of useful stuff. Note also that extends javax.faces.view.facelets.ComponentHandler. There are handlers for all the kinds of tags in JSF: converter, validator, component, and behavior.
In many cases, the only reason people were doing custom Facelet tags
was so they could be notified when the component is built. To get this
in JSF 2.0, just override the onComponentCreated()
method, as shown in the next class.
- package com.sun.faces.facelets.custom;
- import javax.faces.component.UIComponent;
- import javax.faces.view.facelets.ComponentConfig;
- import javax.faces.view.facelets.ComponentHandler;
- import javax.faces.view.facelets.FaceletContext;
- public class CustomComponentHandler2 extends ComponentHandler {
- public CustomComponentHandler2(ComponentConfig config) {
- super(config);
- }
- @Override
- public void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent) {
- super.onComponentCreated(ctx, c, parent);
- }
- @Override
- public void onComponentPopulated(FaceletContext ctx, UIComponent c, UIComponent parent) {
- super.onComponentPopulated(ctx, c, parent);
- }
- }
The stack traces for onComponentCreated and
onComponentPopulated are here
and here,
respectively.
If you really must have access to the apply method, and
indeed override it, you can still do so. However, to preserve a clean
separation between interface and implementation there is a little extra
syntatic sugar you must endure. Sorry. Here's the code for a custom
tag handler that overrides apply() and
createMetaRuleset(). The stack trace for
apply() is shown at left, while the one for
createMetaRuleset() is available here.
- package com.sun.faces.facelets.custom;
- import java.io.IOException;
- import javax.faces.component.UIComponent;
- import javax.faces.view.facelets.ComponentConfig;
- import javax.faces.view.facelets.ComponentHandler;
- import javax.faces.view.facelets.FaceletContext;
- import javax.faces.view.facelets.MetaRuleset;
- import javax.faces.view.facelets.TagHandlerDelegate;
- public class CustomComponentHandler3 extends ComponentHandler {
- public CustomComponentHandler3(ComponentConfig config) {
- super(config);
- }
- @Override
- public void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent) {
- super.onComponentCreated(ctx, c, parent);
- }
- @Override
- public void onComponentPopulated(FaceletContext ctx, UIComponent c, UIComponent parent) {
- super.onComponentPopulated(ctx, c, parent);
- }
- @Override
- protected TagHandlerDelegate getTagHandlerDelegate() {
- final TagHandlerDelegate parent = super.getTagHandlerDelegate();
- TagHandlerDelegate result = new TagHandlerDelegate() {
- @Override
- public MetaRuleset createMetaRuleset(Class type) {
- return parent.createMetaRuleset(type);
- }
- @Override
- parent.apply(ctx, comp);
- }
- };
- return result;
- }
- }
As mentioned previously, there are handlers for all the different
kinds of JSF artifacts that may appear in a Facelet page. The syntax in
the .taglib.xml file is rather similar for all of them, but
the one for the validator is shown next.
- <tag>
- <tag-name>validator</tag-name>
- <validator>
- <validator-id>javax.faces.Required</validator-id>
- <handler-class>com.sun.faces.facelets.custom.CustomValidatorHandler</handler-class>
- </validator>
- </tag>
Finally, here's the code for this custom validator.
- package com.sun.faces.facelets.custom;
- import java.io.IOException;
- import javax.faces.component.UIComponent;
- import javax.faces.view.facelets.FaceletContext;
- import javax.faces.view.facelets.MetaRuleset;
- import javax.faces.view.facelets.TagHandlerDelegate;
- import javax.faces.view.facelets.ValidatorConfig;
- import javax.faces.view.facelets.ValidatorHandler;
- public class CustomValidatorHandler extends ValidatorHandler {
- public CustomValidatorHandler(ValidatorConfig config) {
- super(config);
- }
- @Override
- protected TagHandlerDelegate getTagHandlerDelegate() {
- final TagHandlerDelegate parent = super.getTagHandlerDelegate();
- TagHandlerDelegate result = new TagHandlerDelegate() {
- @Override
- public MetaRuleset createMetaRuleset(Class type) {
- return parent.createMetaRuleset(type);
- }
- @Override
- parent.apply(ctx, comp);
- }
- };
- return result;
- }
- }
The callstacks for apply() and
createMetaRuleset() are here
and here
80% of the time, there is no need for any custom tag handlers. If you're doing your job right, the logic should be in the UIComponent, Validator, Converter, etc. However, for that extra 20% of the time, you can use the above practices to get the job done.
Technorati Tags: edburns
Thursday, October 8, 2009

The image on the left is a screengrab I
took when I was reviewing content for my upcoming book, with Neil
Griffin, JavaServer Faces 2.0: The
Complete Reference. I consider this little snippet an atonment for
the HTTP violations of JSF versions past (before I was spec lead).
Sorry about that.
For the record, the article referred to in the book is at <http://www.theserverside.com/tt/articles/article.tss?l=RedirectAfterPost>.
Technorati Tags: edburns
| Attachment | Size |
|---|---|
| jsf2-prg.png | 102.27 KB |
Tuesday, September 22, 2009
Ed
has developed a 50 minute audio-visual presentation recounting his
experience in writing the book. This presentation includes audio clips
from the programmers themselves, including subtitles for those for whom
English is not their native language, together with insight to tie it
all together.
Ed has given this presentation at numerous international developer conferences and user groups around the world, including JAX in Germany, Jazoon in Switzerland, The Developer's Conference in São Paulo, Brazil and the Rich Web Experience in U.S.A..
See the presentation online now!
Audio and Video from Ed's presentation at Jazoon 2009 is available at Parleys.com, at the URL: <http://purl.oclc.org/NET/RidingTheCrest/Show>. Unfortunately, the subtitles did not come through on this presentation, but those viewing the presentation live do see them.
Technorati Tags: edburns
Thursday, September 3, 2009

My previous entry dove under the covers for JSF 2.0 and examined composite
component metadata. This one is far less esoteric and shows how to
handle the ViewExpiredException using a new JSF feature,
the ExceptionHandler, contributed by Pete Muir a JSF
Expert Group representative from JBoss.
JSF throws a ViewExpiredException when a postback is
made to a view and, for whatever reason, that view cannot be restored.
Usually this is due to a session timeout, but a custom state management
solution could also cause this exception to be thrown. The default
behavior in JSF2 is to show the Facelets error page saying View
Expired. The default page is illustrated at right.
One way to fix this is to declare an <error-page>
element in your web.xml, as shown here.
- <error-page>
- <exception-type>javax.faces.application.ViewExpiredException</exception-type>
- <location>/faces/viewExpired.xhtml</location>
- </error-page>
This works well enough. You can even put JSF components on the error
page if you put the proper Faces Servlet mapping in the
<location> element, as shown above. If you want to
do some application level manipulation in response to the exception,
you'll want something different, however. In this case, a custom
ExceptionHandler is just the trick. I cover this in much
more detial in my upcoming book, JavaServer Faces 2.0: The Complete
Reference, and the example shown in this blog entry is neatly
integrated into the chapter 10 sample app. Consider this blog entry an
appetizer. So delete that old web.xml (it's not needed if you have JSF2
and Servlet 3, which you get in Glassfish V3) and let's go.
First, we need to install a custom ExceptionHandler.
This is done using the tried and true JSF decorator pattern. In this
case, we place the following into the faces-config.xml.
There's no annotation for this because it's relatively uncommon, and we
expect advanced users to use the feature. Therefore, the EG tradeoff
was to not add yet another "scan for this annotation" clause to the
spec.
- <factory>
- <exception-handler-factory>com.sun.faces.ViewExpiredExceptionExceptionHandlerFactory</exception-handler-factory>
- </factory>
Here's the code for the class.
- package com.sun.faces;
- import javax.faces.context.ExceptionHandler;
- import javax.faces.context.ExceptionHandlerFactory;
- public class ViewExpiredExceptionExceptionHandlerFactory extends ExceptionHandlerFactory {
- private ExceptionHandlerFactory parent;
- public ViewExpiredExceptionExceptionHandlerFactory(ExceptionHandlerFactory parent) {
- this.parent = parent;
- }
- @Override
- public ExceptionHandler getExceptionHandler() {
- ExceptionHandler result = parent.getExceptionHandler();
- result = new ViewExpiredExceptionExceptionHandler(result);
- return result;
- }
- }
The interesting things happen on lines 15 - 20. This method is
called once per request must return a new ExceptionHandler
instance each time it's called. I know the method name should be
createExceptionHandler, but we stuck with
"get" for consistence with other JSF methods. On line 17, we call the
real ExceptionHandlerFactory and ask it to create the
instance, which we then wrap in our custom
ViewExpiredExceptionExceptionHandlerFactory class. This is
where the real interesting stuff happens.
- package com.sun.faces;
- import java.util.Iterator;
- import java.util.Map;
- import javax.faces.FacesException;
- import javax.faces.application.NavigationHandler;
- import javax.faces.application.ViewExpiredException;
- import javax.faces.component.UIViewRoot;
- import javax.faces.context.ExceptionHandler;
- import javax.faces.context.ExceptionHandlerWrapper;
- import javax.faces.context.FacesContext;
- import javax.faces.event.ExceptionQueuedEvent;
- import javax.faces.event.ExceptionQueuedEventContext;
- public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper {
- private ExceptionHandler wrapped;
- public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) {
- this.wrapped = wrapped;
- }
- @Override
- public ExceptionHandler getWrapped() {
- return this.wrapped;
- }
- @Override
- public void handle() throws FacesException {
- for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
- ExceptionQueuedEvent event = i.next();
- ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
- if (t instanceof ViewExpiredException) {
- ViewExpiredException vee = (ViewExpiredException) t;
- FacesContext fc = FacesContext.getCurrentInstance();
- Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
- NavigationHandler nav =
- fc.getApplication().getNavigationHandler();
- try {
- // Push some useful stuff to the request scope for
- // use in the page
- requestMap.put("currentViewId", vee.getViewId());
- nav.handleNavigation(fc, null, "viewExpired");
- fc.renderResponse();
- } finally {
- i.remove();
- }
- }
- }
- // At this point, the queue will not contain any ViewExpiredEvents.
- // Therefore, let the parent handle them.
- getWrapped().handle();
- }
- }
On line 15, you see we take advantage of the
javax.faces.context.ExceptionHandlerWrapper convenience
class. JSF has lots of these wrapper classes and when you use them, you
need only override the getWrapped() method to return the
instance of the class you're wrapping, which is often simply passed to
the constructor, as shown on lines 19 - 21. Once you override
getWrapped(), you need only override those methods you're
interested in. In this case, we want to override only
handle(), which we do on lines 29 - 57.
We iterate over the unhandler exceptions using the iterator returned
from getUnhandledExceptionQueuedEvents().iterator(), as
shown on line 30. The ExeceptionQueuedEvent is a
SystemEvent (also described in detail in my book) from which we can get the
actual ViewExpiredException, which I do on line 35. I know
I'm going to be ultimately showing a JSF page so I want to extract some
information from the exception and place it in request scope, so I can
access it via EL in the page. I do this on line 37.
On lines 45 and 46, I leverage the JSF implicit navigation system and
cause the server to navigate to the "viewExpired" page. This assumes,
of course, that there is a viewExpired.xhtml page out
there. Naturally, you could parameterize this howevere you like,
context-param, annotation, whatever. Line 46 causes the intervening
lifecycle phases to be skipped.
Note that we have a try-finally block here, and in the finally block,
on line 49, we call remove() on the iterator. This is an
important part of the ExceptionHandler usage contract. If
you handle an exception, you have to remove it from the list of
unhandled exceptions. That way, we know it's safe to call
getWrapped().handle() on line 55.
Finally, let's see my cheesy viewExpired.xhtml page in
action, shown at left.
This page is not much more visually appealing than the default one, but that's not JSF's fault! The one in the JSF2 book will look nicer. Here's the source for this cheesy one.
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core">
- <h:head>
- </h:head>
- <h:body>
- <h:form>
- <p>To protect your security, we have taken the liberty of logging you
- out. Those who sacrifice liberty for security deserve to have
- their views expired.</p>
- </h:form>
- </h:body>
- </html>
Note that we show the data from the exception on line 15.
This entry showed you how to programmatically intercept the
ViewExpiredException and do something nice with it. If you
have any other state that you can show in the page, it's easy to include
it in the Facelets view.
Technorati Tags: edburns