Poor Man's JSF Navigation By URL

Every wanted to access a JSF view by directly entering the view onto URL? This is a common request. In my case, I needed to link to specific places in my JSF app from a legacy non-JSF application. This is the type of thing you'd think would be straightforward, but JSF falls flat.

I scoured the web for solutions to this, and this is the simplest: implement a phase listener. In the interest of getting right to it, here it is:

public class RedirectPhaseListener implements PhaseListener {

    public RedirectPhaseListener() {
    }

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    public void afterPhase(PhaseEvent phaseEvent) {
    }

    public void beforePhase(PhaseEvent phaseEvent) {
        FacesContext ctx = phaseEvent.getFacesContext();
        HttpServletRequest request =
                (HttpServletRequest) ctx.getExternalContext().getRequest();

        String viewId = request.getParameter("viewId");

        if (viewId != null) {
            UIViewRoot page = ctx.getApplication().getViewHandler().createView(ctx, viewId);
            ctx.setViewRoot(page);
            ctx.renderResponse();

        }
    }
} 

The phase listener gets the request, and checks for a parameter. The parameter is the path to the view ID you want to visit. For example: /faces/someview.xhtml. With Facelets, these goto URLs end up looking funny, because the real view ID is in the URL also,

 /faces/home.xhtml?viewId=/faces/other.xhtml

Not nice, but it works. Other solutions I've seen try to get fancy by keeping a mapping a view+action result=new view. That's cleaner, and it's easy to do once you understand what's going on above.

Comments:

Or you could use seam if your project allows it. Much easier and much more expressive.

Posted by Fadzlan on May 06, 2009 at 01:08 AM PDT #

You can also check primefaces. it has xml-less navigation

http://www.rehberharitam.com/prime-showcase/optimus/source.jsf

Yigit.

Posted by yigit darcin on May 06, 2009 at 07:23 PM PDT #

Cool solution. It shows how relatively cleanly URL-based navigation can be added to JSF. What you are talking about here is addessability which is a fundamental aspect of HTTP's original design. It's not just legacy applications that benefit, but human users too. If done right this approach enables bookmarking and back/forward buttons to work as expected. The big limitation here is that many views in a non-trivial JSF application rely on session state from previous requests in the expected click path to that view. I do like this solution and I hope it encourages JSF developers to rely a lot less on session state.

Posted by Alain O'Des on May 06, 2009 at 08:44 PM PDT #

JSF also lets you create your own NavigationHandler and plug it in through faces-config.xml. This way, you could make your action methods return a string that is prefixed with url: ("url:MyPage.jsf") and have it navigate to the url. If there is no "url:" prefix, just delegate to the base navigation handler which will look up the navigation rule.

Posted by Geoffrey Longo on May 06, 2009 at 09:57 PM PDT #

Ignore my previous comment, I missed the part about coming from a non-JSF application.

Posted by Geoffrey Longo on May 06, 2009 at 10:04 PM PDT #

Perhaps I'm missing something, but I don't see what this accomplishes. Can you provide an example of the use case?

Posted by Kito D. Mann on May 13, 2009 at 08:15 AM PDT #

kito,

in JSF, the view ID is not determined by the URL. you can't hit http://foo.bar/../a.xhtml and go to view a.xhtml. it will go to whatever view JSF has internally set to be the current view.

it is common however to have a non-JSF app that needs to link to view a.xhtml directly. that's where this type of solution comes in. i understand there are JSF extension and JSF-like frameworks that allow this, but pure JSF does not.

Posted by jeff on May 13, 2009 at 08:22 AM PDT #

<p>Just wanted to say great job with the blog, today is my first visit here and I’ve enjoyed reading your posts so far<br />
<a href="http://www.buddyugg.com"><strong>uggs boots on sale</strong></a></p>

Share more uggs boots on sale on http://www.buddyugg.com

Posted by Brian on November 13, 2009 at 08:46 PM PST #

I have enjoyed reading, I will make sure and bookmark this page and be back to follow you.

Posted by furniture stores on December 06, 2009 at 02:09 PM PST #

Alain commented on my previous post that the solution there was problematic as it allowed access to arbitrary view which may depend on objects being set up in other views

Posted by links of london on December 13, 2009 at 02:01 PM PST #

jean style jean style jeans stylejeans style mens jean style mens jean style skinny jean style skinny jean style blue jeans style blue jeans style seven jeans style seven jeans style new jean style new jean style latest jean style latest jean style jeans styles jeans styles boy style jeans boy style jeans men jean style men jean style jean style 

Posted by jean style on December 17, 2009 at 02:17 PM PST #

The select items have object values. http://www.watchgy.com/ All is good. When I submit the form, I see "Validation Error: Value is not valid". My first reaction was that I didn't have any validation on the page, so how could a value be not valid? http://www.watchgy.com/tag-heuer-c-24.html
http://www.watchgy.com/rolex-submariner-c-8.html

Posted by rolex replica on December 29, 2009 at 12:03 AM PST #

Thanks very much, I like this very much.very good.

Posted by ball valves on December 30, 2009 at 03:00 PM PST #

Not very understand, can see clear. thnanks!

Posted by butterfly valves on December 30, 2009 at 03:02 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

jtb

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today