Wednesday, July 29, 2009

What's cool in Java EE 6 -- JSF 2.0

Howdy -- been a while since I've been around here, but I've been fiddling with some of the new technologies in Java EE 6, and figured that this is as good a place as any to start to talk about them :)...

First off, I've been working with NetBeans 6.7 and Glassfish v3 Preview (look here for info on how to get the two to work together)... I have plenty of experience with NetBeans, but less with Glassfish -- ever since it took forever for JBoss 5 to come out, it has been my App Server of choice for 'fiddling' with technologies... it's really quite impressive, and seems to be one of the places for early access into new technologies...

Anyway, there is plenty of new stuff in EE 6, and one of the areas that shows a ton of improvement is JSF 2.0... Where to start?

So long, faces-config.xml!
Well the most obvious starting point has to be the Annotations... in old-school JSF, any sizable application needed to have every Managed Bean registered in an XML file, which is fine for the smaller examples, but quickly gets to the point of needing to use an appropriate tool to decipher and organize it... Thankfully, this has been replaced by a single (sometimes two) annotations directly on the class, like so:


@ManagedBean
@SessionScoped
public class LoginBean {
...
}


And no discussion of XML in JSF would be complete without mention of the navigation... not only was this too verbose, but it never struck me as an appropriate place to store navigation information -- after all, I already have my Managed Beans and XHTML pages (we've all been using Facelets for years now, right?) -- why do I need to look in a third place to configure what page an action in a page takes us? Again, manageable, but a bit smelly...

Once again, JSF 2.0 makes an improvement here by allowing us to return the names of our views directly from our Managed Beans -- so instead of returning "Success", and then having to indicate what that really means in another file that's too big as it is, I can just return "success.xhtml", and the page will be found for me (in fact, I believe a return of "success" would have the .xhtml added for me, but for some reason the explicit version seems more palatable to me)... and if I want this to be a redirect, it becomes "success.xhtml?faces-redirect=true" -- admittedly a bit awkward, but simple and easy to remember...

Bookmarks
Ok, this is the really big one -- frankly, I am stunned that it has taken, what -- 8 years for JSF to add this feature natively (I apologize if that number is wrong, I'm not up to looking up the JSF history right now)... in the past, I have created my links with standard html '<a href' tags and used a @PostConstruct tag in my Managed Bean to load whatever data I needed, but frankly it's a hack, and the fact that @PostConstruct operates in an undefined transactional state forces you to jump through hoops, not to mention that circumventing the JSF View lifecycle can be difficult at times... In fact, I was actually quite concerned in the later days of the spec development, because it appeared that this feature was not being taken seriously by the spec group -- that Ajax and skinning were more important features than perhaps one of the most basic features of any browser... blog entries by those with 'inside information' were coming out as late as early 2009 that seemed to gloss over the demand for bookmarkable features, but thankfully it made it in at the last moment... whew!

There are a couple of items that are important here, but the basic idea is that any page that can be bookmarked (and that requires info from the query string) uses three new tags -- f:metadata, to define metadata for a view, f:viewParam, which can take a parameter from the query string and store it in a variable (including conversion, validation, etc), and f:event, which can be used to register an event listener on the new PreRenderViewEvent -- it might look something like this:


<f:metadata>
<f:viewParam name="id" value="#{editBean.id}" />
<f:event type="preRenderView" listener="#{editBean.load()}"/>
</f:metadata>


Alternately, you could simply use the old c:set tag to set the variable in the page, however this appears to store a copy of the variable, which doesn't work out well if you are later editing or modifying it...

Finally, to create a link to your new-fangled page, there is also the new h:link tag, which follows the same direct navigation rules mentioned above, and that can support the f:param tag to easy include parameters -- easy peasy!

To Be Continued...
Ok, this turned out to be longer than expected -- I still want to talk about PDL, Events, Annotations for Converters and Validators, Bean Validation integration, Web Beans integration, and plenty more, but that will have to wait for a later date...

The bottom line is that yes, JSF is a viable web framework -- it has had its' problems historically, but the latest version seems to have addressed them quite effectively, and there are plenty of component libraries out there like RichFaces, IceFaces, etc., that can make your apps look and operate great... Hopefully it can shed some of its' poor reputation (much of it deserved, some of it not) -- it's definitely worth a look!

M