wood burning stoves 2.0*
The moose likes JSF and the fly likes JSF, Facelets losing context after reload Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "JSF, Facelets losing context after reload" Watch "JSF, Facelets losing context after reload" New topic
Author

JSF, Facelets losing context after reload

Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Hi everyone =)

Recently I started working with JSF and its sub-frameworks and have accumulated a nice list of questions while trying to solve some common problems. One of them is why my webapp loses context every time I try to reload a page.

For example I have a directories structure similar to this:and a link in my main app persistent menu:with navigational rooles defined in the faces-config.xml:
So the first time my webapp loads I see the start page. There I click my link in the menu and load myPage. All normal pages are loaded using the mentioned above template. At this step the context is of the start page (host/myWebApp/*) as it should be.
Then while being on the myPage if I click the link again the page reloads itself correctly but all the static stuff like styles and scripts are gone since the context changes to host/myWebApp/pages/*.

Any ideas why this happens?
Thanks in advance...


Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?
willCodeForFood("Java,PHP,C#,XML,VBS,XHTML,CSS,JavaScript,SQL"); //always looking for job opportunities in AU/NZ/US/CA/Europe :P
Samuel March
Ranch Hand

Joined: Oct 28, 2009
Posts: 39
Try something like that to p/directory level. Normal jsp and usebean declaration would solve that overall.





...did you have the fish?!............................ No.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

I thought about this solution but I would really love to avoid showing my webapp's internals to everyone...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

Technically, the "context" is the part of the URL that's the same for every page in the app. So for a Tomcat URL of http://myhost.com:8080/myapp/users/page1.jsf, the context would be "myapp". It doesn't have to be a single level, but it usually is. The context URL is therefore "http:/myhost.com:8080/myapp"

From the sound of it, you're using relative URLs for your scripts and stylesheets. So you'd either have to adjust the relative references on the lower-level pages, or you'd need to make absolute references. If you're using a tiling mechanism such as Facelets, the absolute reference is almost unavoidable.

Incidentally, RichFaces does provide some tags to get around that for scripts and stylesheets. Failing that, however, you just need to formulate your pages the hard way.

In straight JSP, the pageContext variable can be used to get the context URL. Maybe I'm just dense, but I can't get that to work right in JSP, so I made a request-scope bean whose sole purpose is to provide the context:



I can then code links in the form: "#{contextBean.contextPath}/styles/style.css".

Customer surveys are for companies who didn't pay proper attention to begin with.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Thanks, man. Yeah, facelets is strange. Won't even talk about how much time I've spent trying to get it work under JBoss 5.1, the official release fails there, only the unofficial beta works correctly, and I do not even remember where I found it.

Since I actually use richfaces I should correct the both, facelets templates and the resources links.

Thanks again =)
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Mmm, I'm not sure I understand how to maintain the context with static urls in nav rules.

An interesting observation btw: Each time I load a page it shows me not the current but the previous path.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

Don't worry about that. In JSF, the URL is more of a "session handle" than an absolute indication of the page to be displayed.

That can lead to problems, since those URLs are not only not bookmarkable, they also fail to allow for URL-filtered container security. However, there are various ways to handle that.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

The problem is I really really do not want to get out of the context since it's not just about a bunch of scripts and styles I am concerned. My main worries are about tons of graphics references and the shown url. And I really do not want to make every damn reference dynamic and alter the url string with some bogus javascript.

Where lies the initial problem? If it's facelets, I could abandon the thing, it's been more pain than help for me anyways. But what alternatives do I have then? Will Tiles solve the issue, or it's JSF itself I have to blame?

At the moment the only reliable solution I see to this mess is to get all the pages out of their corresponding dirs and put them into the web root. And I'd hate to do that as well... It could be ok if there were about 10 pages, but I'm afraid I'm going to have more than 100. The example I drew in my first post is just a model, the real structure is much much uglier.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

I'm not sure what you mean "get out of the context", but no, losing Facelets isn't really going to help, and personally, I've never managed to love Tiles at all.

Relative URLs are relative to the page primary URL. Always. So you have 2 choices when you descend into the URL "directory" structure.

1. Factor the relative difference between your root and your descendent pages into the URLs on the descendent pages. Like I said, Facelets, or for that matter and sort of "include"system - including Tiles - has a problem with that, since it's the URL of the base document that counts, and that's not constant - it's a context plus whatever subdirectories you're currently loading from.

2. Turn the URLs into absolute URLs. The bad way is to literally code the whole URL from http/server:port/context on down in your URL references. A better way is to put the context into a JSF managed bean and let it compute it based on where you deployed the app. This makes things a lot easier to test, by the way, since you don't have to find all the hard-coded references to the test server and fix them up before going to production (and vice versa).

And, of course, the third way is to simply flatten out the site, forget about subdirectories and put everything in the root. For me, that's a no-go, since I use the "directory" names to zone the app for different security options. The admin functions are all in the "admin" subdirectory, for example. That gives ,me srtonger security, since the container itself will refuse to dispatch requests to admin URLs unless you can play in the admin security role.

There's no Javascript, bogus or otherwise involved here. and the URLs are "dynamic" only in the sense that they're all the same, but they're the same based on where you deployed the webapp. The technique I illustrated - and which I'm using in just about every app I write these days -is no different than the way to do a value reference in a forms tag. It's straight EL backed by bog-standard JSF and the only thing even remotely tricky about it is that since JSF is intended to be independent of HTTP, you have to reach into the JSF context in order to get the HTTP context path.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Any idea how and where should I put it, considering my example above? When I try to set absolute path in navigational rules it becomes related and fails, of course, since "http://" thing appears in the middle of url string.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

OK, let me back up and try again. I've never been sure we're talking about the same thing here.

What I've been covering is what you'd code in a commandLink tag, a <link> reference to a stylesheet, or some similar reference.

I'm beginning to suspect that what you mean by "context" is the URL that displays in the user's navigation control.

JSF is different from most other webapp systems in that the URL in the navigation control doesn't directly reference the resources being displayed. A URL is a Uniform Resource Locator, and despite what a lot of people think, it's not a pointer to a specific place in a filesystem. It may be used as a basis for locating things within a WAR's filesystem, and it does look like a filesystem path, but it's actually just a logical handle that's decoded in whatever manner the webapp (or in this case, the JSF controller applet) sees fit.

JSF uses a technique called "postback" to maintain a conversation within and between JSF views (the term "page" is not entirely accurate. I prefer View, as in MVC).

So the upshot is that what's displayed in the URL control could just as well be a random quote from T.S. Elliot, for all the difference it makes most of the time.

You can force the returned URL to track the source JSF page page a little more closely by using the <redirect/> element for selected items in faces-config. But it's extra overhead, and I don't guarantee it will be exactly what you want. To make bookmarkable JSF web pages, I highly recommend an add-on called PrettyFaces from ocpsoft. It's open-source, easy to install, and easy to configure.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Sorry for becoming pain in the ash with this.

And thanks for your help.

Let's simplify the terms and arguments. I'm looking for solution for 2 issues:
1. To make all resources (images, styles, scripts, etc.) be displayed on every page based on the template.
2. Show the URL with application base only (htpp://host/webapp) without sub-routes and maybe even without session ids.

And yes, in (2) I'm talking about the url string in a browser. What really happens with the external or faces contexts I don't care as soon as these 2 are solved.

Any recommendations?

Btw, I know what url and context are
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15958
    
  19

Akaine Harga wrote:Sorry for becoming pain in the ash with this.

And thanks for your help.

Let's simplify the terms and arguments. I'm looking for solution for 2 issues:
1. To make all resources (images, styles, scripts, etc.) be displayed on every page based on the template.
2. Show the URL with application base only (htpp://host/webapp) without sub-routes and maybe even without session ids.

And yes, in (2) I'm talking about the url string in a browser. What really happens with the external or faces contexts I don't care as soon as these 2 are solved.

Any recommendations?

Btw, I know what url and context are


OK. I'm either hopelesly confused (it happens) or do #1 every day using the techniques I described.

On #2 You're doomed. That control belongs to the client's web browser not to you or the web server. You can't put arbitrary text in it and expect it to work. If you don't like the URLs returned by JSF, you'll just have to invent your own system. In J2EE, the context just points you to the webapp. You have to provide additional data to target the incoming URL and data to a specific servlet/jsp within that webapp such as the FacesServlet. That's the function of servlet mapping in web.xml. If you have a "welcome" element in web.html, a bare context URL will be rewritten by the appserver to target the welcome URL, but that's about as close as you can get.
Akaine Harga
Ranch Hand

Joined: Nov 03, 2009
Posts: 79

Tim Holloway wrote:On #2 You're doomed. That control belongs to the client's web browser not to you or the web server. You can't put arbitrary text in it and expect it to work. If you don't like the URLs returned by JSF, you'll just have to invent your own system. In J2EE, the context just points you to the webapp. You have to provide additional data to target the incoming URL and data to a specific servlet/jsp within that webapp such as the FacesServlet. That's the function of servlet mapping in web.xml. If you have a "welcome" element in web.html, a bare context URL will be rewritten by the appserver to target the welcome URL, but that's about as close as you can get.

Yep, I know. Just too bad JSf can't maintain the Faces servlet context visually. Before I started to use MVC framework I wrote my own servlet controllers and made things my way. Now it's just impossible unless trying to create my own JSF distro which I'm sure I won't have time for.

The #1 I solved putting all the stuff inside CSSs and parametrized links, looks somewhat ugly but works at least.

Btw, don't know why I haven't though this from the beginning: Since the webapp is not supposed to be bookmarked from the inside I could just use a frameset loading all the stuff inside a secondary full windowed frame, while the parent frame would have the base url. Personally I hate frames, but in this case that could be a real option.
Horacio Tovar
Greenhorn

Joined: Aug 30, 2009
Posts: 2
Hi, I am trying to do a web application using JSF, Facelets in Netbeans 6.7. but I am having a problem:

Why I am getting wrong <a href= /> path ?

It is very simple, straight forward web application.
When run, it shows the template-client.xhtml perfectly . The navigation menu is shows ok, but they don't work. However, if I enter in the browser address



it goes perfect to the right page and the navigation between About, Products and Home works perfect. But once I click on Home, the menu start to give me errors. Looks like the path is wrong again.

folders structure:

test3



My code:



web.xml:



forward.jsp:



template-client.xhtml:




template.xhtml:



about.xhtml:



products.xhtml:
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JSF, Facelets losing context after reload
 
Similar Threads
java.lang.IllegalStateException: using sendRedirect()
Navigation Problem - URL not updated
My navigation problem
Error after navigation
JSF with Facelets - Using "h:commandLink" inside header of the layout