November 12th, 2008 by Lincoln Baxter III

Make JSF intuitive, with bookmarkable and pretty URLs

What makes Pretty URLs in JSF so hard, and so slow?

Speed up development, reduce bandwidth, enhance user experience. This article gives a brief overview of JSF navigation, some of the problems, and potentially how to solve them by enabling bookmarkable, pretty URLs. Put simply… in my view, out of the box, JSF is a web framework designed for web-applications, not designed for web-sites. PrettyFaces addresses most of these issues.

Target audience for this article:

  1. The reader is familiar with JSF navigation.
  2. The reader is attempting to create a JSF app with bookmarkable “pretty” URLs. E.g.: …/mysite/archives/2008/11/11/
  3. The reader is familiar with HTTP request/response at a basic level.

The difference between a web-application / web-site

When I think of a web-site, I think of a group of pages having:

  • Multiple points of entry
  • Navigation via <a href> or <form> HTML elements.
  • Mostly stateless; the application may care who you are, but usually does not care where you came from, or where you have been.

When I think of a web-application, I think of a group of pages having:

  • One or only a few points of entry (login page, etc. No direct links.)
  • Navigation via page-flows.
  • Mostly stateful; the application cares who you are and where you have been.
So when I say that JSF was designed for applications, I mean that without extension, normal, mostly-stateless web-behavior can be more difficult to implement than stateful web-behavior. The problem here, however, is that if a web-site is “stateless,” JSF forces you to behave in a stateful way. Here’s why.

<h:form> – the root of the problem

Forms in JSF are rendered by the <h:form> component, and each form must post back to the viewId from which it was rendered (aptly named a postback.) Once the form has been submitted back to the requested URL, JSF will determine which page the user should see next, and either render that view, or redirect the client’s browser to a new URL.
  • An example view Id: …/mysite/faces/articles/viewArchives.jsf
There are a few existing frameworks to get our bookmarkable URLs, but all suffer from a troubling set of problems:
  1. Restfaces – solely intended to manage Pretty/Bookmarkable JSF navigation
  2. PrettyUrlPhaseListener – a small utility provided in the sandbox for Mojarra Scales
  3. UrlRewriteFilterCannot process unordered query-parameters reliably: ‘?foo=1&bar=2’ vs. ‘?bar=2&foo=1’
And most serious solutions have heavyweight configurations with a steep learning-curve.

Problems:

  • When you submit a form, the JSF view ID is shown in the URL bar instead of the Pretty URL. This occurs for validation and also standard navigation without server-side redirects.
  • When form validation occurs, the view ID is again shown in the URL bar. This causes contextual information contained in the URL to be lost. The information must instead be rendered as hidden form input fields, and re-submitted with the form. The developer must now manually process these values and reload them in every action method. The other option is to make your managed beans “session” scoped, which causes other problems.
  • Mulitple requests to preserve the URL mean wasted bandwidth, longer client wait times, and higher CPU utilization.

A proposed solution

It’s simple, really… Modify JSF to submit the form to the pretty URL (/mapped/page) instead of the view Id (/faces/page.jsf)
  • An example PrettyFaces URL: …/mysite/archives/2008/11/11/
(Read through the presentation to see why PrettyFaces, a new OpenSource library by OcpSoft, may be a good alternative)

—-

How to make JSF bookmarkable like a web-site, not behave like an application.

Bookmarkable JSF: Pretty4JSF
View SlideShare presentation or Upload your own. (tags: jsf url)

—-

Conclusion:

When the form is submitted to the pretty URL instead of the JSF view ID, you gain performance, save resources, and make life for the developer easier; parameter values are not lost, and do not need to be coded into the form or session scoped beans. Try PrettyFaces, an opensource solution by OcpSoft. (Check the project homepage, here).
Lincoln Baxter, III

About the author:

Lincoln Baxter, III is the Chief Editor of Red Hat Developers, and has worked extensively on JBoss open-source projects; most notably as creator & project lead of JBoss Forge, author of Errai UI, and Project Lead of JBoss Windup. This content represents his personal opinions, not those of his employer.

He is a founder of OCPsoft, the author of PrettyFaces and Rewrite, the leading URL-rewriting extensions for Servlet, Java EE, and Java web frameworks; he is also the author of PrettyTime, social-style date and timestamp formatting for Java. When he is not swimming, running, or playing competitive Magic: The Gathering, Lincoln is focused on promoting open-source software and making technology more accessible for everyone.

Posted in JSF, OpenSource, Uncategorized

17 Comments

  1. suraj says:

    Hi,
    Great post i am looking for this kind of post for JSF application.I have few JSF application which is not based on Seam but there is performance issue so this post fulfill all my need.Thanks one again.

  2. Mom says:

    hey lincoln — way cool! if i understood more of it, even more cool!! : )

  3. Ophir Radnitz says:

    Hi,
    Do you have a Maven artifact deployed anywhere?
    Thank you,
    Ophir

  4. Derek says:

    Ophir,

    Thanks for the comment. As of right now we don’t have any Maven Artifacts created, but we will let you know when we do.

  5. Onur AKTAS says:

    It is amazing.. I am impatiently waiting for the new release which handles & supports passed parameters with GET method.

  6. Lincoln says:

    @Onur – It’s almost ready! Just a few more days and it should be released as part of version 1.2, which includes a few new features.

  7. Lincoln says:

    PrettyFaces 1.2 is released, and includes the new managed parameters facility.

  8. Onur AKTAS says:

    Congratulations Lincoln, good job.

  9. Lincoln says:

    Thank you! Please let me know your feedback, as I’m always trying to make a better product.

  10. I would also appreciate a Maven build in the public repository.

  11. Adam says:

    Great job. Lack of java doc for component. it would be very userful ;). Docs for tags and java classes.

  12. vinay says:

    Lincoln , JSF 2.0 has come up with bookmarked URL’s . Will that solve the url issues with JSF applications ?

    1. Lincoln says:

      JSF 2 enables simple bookmarking with query-parameters. If you want full control of the URL, path-parameters, navigation, page actions, and rewriting, then you should use PrettyFaces.

  13. vinay says:

    Lincoln
    We are halfway through JSF2 and spring webflow 2. It might give me some flexibility but not to the same extent as pretty faces gives.
    I will keep on updating the blog with my findings for other users to benefit.
    Thanks for creating this wonderful utility.

  14. vinay says:

    Lincoln
    I am able to create book mark url. If my url was
    http://www.skill-guru.com/skill/login/login.faces
    it is now
    http://www.skill-guru.com/skill/login

    How do I get rid of application name skill ?
    I want the url to be
    http://www.skill-guru.com/login

  15. Lincoln says:

    Hi Vinay,

    You need to deploy your app as the ROOT application. It’s different depending on which server you use.

    Could you ask future questions in the support forums? http://ocpsoft.com/forums/

    Thanks,
    Lincoln

  16. Vlad says:

    In the documentation it sais that
    // Redisplay the current page via redirect.
    return “pretty:”

    using

    Delete this item.

    This dose NOT work… I tried even on a basic example using ocpsoft-pretty-faces-1.1.3.jar

    is there anything wrong with it ?

Leave a Comment




Please note: In order to submit code or special characters, wrap it in

[code lang="xml"][/code]
(for your language) - or your tags will be eaten.

Please note: Comment moderation is enabled and may delay your comment from appearing. There is no need to resubmit your comment.