This discussion is archived
9 Replies Latest reply: Jan 8, 2013 2:38 PM by gimbal2 RSS

JSF 2.0 page navigation vs direct page access

lfd Newbie
Currently Being Moderated
I've been experimenting with JSF for some time now and I still don't understand the page navigation part. I know that in JSF, if you aren't using the redirect option in navigation that the URL is one page behind the page you are on.

I've seen articles where people say you should put your pages in a directory under WEB-INF to protect against directly accessing the page. I don't understand how you can create an application that is multiple pages using that option, because won't you run into the problem of having a form with an action URL of WEB-INF/somepage.xhtml?

I've also read articles that say the way to fix this is to add security-constraints to web.xml that prevent "direct access" to pages, when you want your user to follow a page flow, such as start on page1.xhtml, then page2.xthml, then end on page2.xhtml. If page3.xhtml depends on page2.xhtml, the articles I've read say that a security constraint prevents users from simply requesting page3.xhtml out of sequence.

And what happens if the page you are on encounters an error or the session times out, which page handles that? The one you're on, or the one from before that forwarded you to the page you're on?

In this example, should page2.xhtml and page3.xhtml go in the root of the webapps directory, or in a directory under WEB-INF?
Webapps
  index.xhtml
  page1.xhtml
  page2.xhtml
  page3.xhtml
  WEB-INF
    faces-config.xml
    web.xml
    page-directory
      page2.xhtml
      page3.xhtml
  • 1. Re: JSF 2.0 page navigation vs direct page access
    gimbal2 Guru
    Currently Being Moderated
    lfd wrote:
    I've seen articles where people say you should put your pages in a directory under WEB-INF to protect against directly accessing the page. I don't understand how you can create an application that is multiple pages using that option, because won't you run into the problem of having a form with an action URL of WEB-INF/somepage.xhtml?
    That statement alone proves you know little about how JSF really ticks, or how a servlet environment works. The whole deal behind putting the resources in the WEB-INF is so you can't navigate directly to the xhtml page and fetch the content, as in as a web resource (like an image, CSS or JS file). That is something you don't ever -want- to happen; all navigation must happen through the JSF servlet so it produces a rendered version of the page. Any URL you can navigate to is what you configure in your web.xml that should be mapped to the JSF servlet, it has absolutely nothing to do with the xhtml files.

    Me: I don't bother with it. I just map *.xhtml to the JSF servlet and things just work.
  • 2. Re: JSF 2.0 page navigation vs direct page access
    lfd Newbie
    Currently Being Moderated
    I understand "why" people put resouces in WEB-INF.

    My question was related to the URL that is generated when page1 (at the root of myapp) forwards to page2 (located in WEB-INF), and page2 has a command button that when clicked, forwards to page3 (also in WEB-INF).

    How does the command button on page2 not have a URL action of http://localhost/myapp/WEB-INF/page3.xhtml ?
  • 3. Re: JSF 2.0 page navigation vs direct page access
    Kayaman Guru
    Currently Being Moderated
    lfd wrote:
    How does the command button on page2 not have a URL action of http://localhost/myapp/WEB-INF/page3.xhtml ?
    Because URLs can be mapped in so many ways. It doesn't need to follow the actual directory structure.
    For example, mapping *.xhtml to files in /WEB-INF/ and other file extensions to /resources/, the URLs could still be the form /myapp/page3.xhtml and /myapp/mypic.png, even though the actual files are in different directories on the server.
    Of course, just mapping *.xhtml to the FacesServlet (as mentioned previously) takes care of everything, even if they aren't in WEB-INF folder.
  • 4. Re: JSF 2.0 page navigation vs direct page access
    lfd Newbie
    Currently Being Moderated
    Thanks Kayaman,

    I must have something else wrong, because when I click the command button on page2.xhtml, it tries to forward me to the WEB-INF directory as part of the URL.
    web.xml
    
      <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
      </servlet-mapping>  
    
    
    faces-config.xml
    
       <navigation-rule>
        <description>index page</description>
        <from-view-id>index.xhtml</from-view-id>
        <navigation-case>
          <from-outcome>pg1sucess</from-outcome>
          <to-view-id>WEB-INF/templates/page2.xhtml</to-view-id>
        </navigation-case>
        <navigation-case>
          <from-outcome>error</from-outcome>
          <to-view-id>index.xhtml</to-view-id>
        </navigation-case>
      </navigation-rule>
      
      <navigation-rule>
        <description>page2</description>
        <navigation-case>
          <from-outcome>pg2sucess</from-outcome>
          <to-view-id>WEB-INF/templates/page3.xhtml</to-view-id>
        </navigation-case>
      </navigation-rule>
  • 5. Re: JSF 2.0 page navigation vs direct page access
    gimbal2 Guru
    Currently Being Moderated
    I wonder. This used to be possible with jsp resources, especially because JSPs are ultimately translated into servlets making it possible to forward to them server side. But Facelets is a different beast entirely. I can't really find any proof that the "hiding in the WEB-INF" trick is possible when using Facelets pages. This stackoverflow thread seems to indicate that it is in fact not possible:

    http://stackoverflow.com/questions/3512234/jsf-files-inside-web-inf-directory-model-2-pattern
  • 6. Re: JSF 2.0 page navigation vs direct page access
    lfd Newbie
    Currently Being Moderated
    Good information gentlemen.

    I was using a security-constraint, but I thought i might be able to just place everything beyond my index.xhtml page in WEB-INF, apparently not.

    I originally had page2.xhtml and page3.xhtml in the root of the webapp, and was using facelets templates located in WEB-INF/templates, which was working before I tried to move everything under WEB-INF.

    I admit I struggle with this framework beyond a single page naviation and done workflow.

    In my example, since JSF uses forwards in navigation, and the URL is always one page behind the actual page, and if I use a security-constraint to restrict GET access to page2.xhtml and page3.xhtml, then how do I handle issues such as the session timing out while the user sits on page3.xhtml? A refresh of page3.xhtml by the user will redispaly page2.xhtml without any information, just empty components.
  • 7. Re: JSF 2.0 page navigation vs direct page access
    gimbal2 Guru
    Currently Being Moderated
    A session timeout should actually net a view expiry exception.

    You do know that JSF 2.0 made page navigation that bit easier by not requiring you to do the XML configuration? There is now a convention built in plus some new components to add GET enabled requests to the JSF lifecycle (notably h:button and h:link). If you have an action method that returns the following:
    public String doSomething(){
      return "something";
    }
    then JSF will by default want to render a view 'something.xhtml' when you don't define any navigation rules. If you want to make that a redirect you can do this:
    public String doSomething(){
      return "something?faces-redirect";
    }
    (of course this is a prime target to turn into a utility method on a backing bean base class).

    Navigation rules are still necessary when you want to put views in a subdirectory, but at least this way you can greatly simplify general cases. Other than that I can only say: research research research because this material is vital to understand if you want to be productive using the framework; navigation and the 6 JSF lifecycle phases are two items you should put on the top of your list to hammer out until you really get it. A good JSF book will help you immensely there. Balusc's blog is also a good source of deeper understanding:

    http://balusc.blogspot.com/

    Most of his articles are on JSF 1.2 but most of the information still applies.

    Oh and its no surprise that you're a bit confused - this framework is not easy to pick up especially when you don't know any other web frameworks. If you keep running into a wall you should consider checking out something else like Wicket or Play framework. It might just be that JSF simply isn't the tool for the job you're trying to do.
  • 8. Re: JSF 2.0 page navigation vs direct page access
    lfd Newbie
    Currently Being Moderated
    Yes, I've noticed that JSF is touted as the "enterprise platform" for Java on the web, but I don't know of anyone using JSF or see it much in Job postings. And it onlly takes four clicks on "next" in this forum to go back five months worth of posts.

    It seems as though facelets templates don't even know when a session expires, because they just render model content, and if the model is null, the view still renders empty components. People must be using filters for handling requests in JSF more than I know.

    The book I'm reading says: return "something?faces-redirect=true";

    I appreciate the help..and the links thanks.
  • 9. Re: JSF 2.0 page navigation vs direct page access
    gimbal2 Guru
    Currently Being Moderated
    lfd wrote:
    Yes, I've noticed that JSF is touted as the "enterprise platform" for Java on the web, but I don't know of anyone using JSF or see it much in Job postings. And it onlly takes four clicks on "next" in this forum to go back five months worth of posts.
    Its certainly the framework used in all enterprise related jobs I've had so far including the current one. But there are so many to choose from, take your pick. Note that JSF becomes a whole lot better once you bolt on an extension framework, like Primefaces.
    It seems as though facelets templates don't even know when a session expires,
    Faces templates are just templates, they don't do anything. Its faces itself that needs to know. Generally I'm not bothered by it because applications tend to be guarded through authentication; as soon as the session expires you're no longer logged in and will be kicked to the login screen.
    because they just render model content, and if the model is null, the view still renders empty components. People must be using filters for handling requests in JSF more than I know.
    Filters perhaps, or a phase listeners which is more JSF-ey.
    The book I'm reading says: return "something?faces-redirect=true";
    It was a test! ;) Good that you have a book. It will still take plenty of digging through forum posts to fill in the blanks though. Luckily it is a widely used framework, whatever you will run into, someone else has seen it before.
    I appreciate the help..and the links thanks.
    You're welcome.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points