0

I'working on a enterprise application that uses JSF 2.0, with Netbeans 7.0 and Glassfish 3.1 I have a managed bean that is ViewScoped. this is the declaration of the class:

@ManagedBean(name = "myBean")
@ViewScoped
public class MyMBean implements Serializable {

Inside its @PostConstruct, it has the following:

String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");    
if (id == null) {
    try {
        FacesContext.getCurrentInstance().getExternalContext().redirect("home.xhtml");
        FacesContext.getCurrentInstance().responseComplete();
    } catch (Exception e) { }
    return;
}

if I go to the page that uses this managed bean, and the id is null, everything works fine, and I get redirected to home page. The problem is that when I navigate to a different page that does NOT use this managed bean (lets say for example "otherpage.xhtml") the PostConstruct method is executed, and it shouldn't! And it gets worse: since the url of this other page doesn't have the "id" parameter, the bean tries to redirect to home page; and I get a IllegalStateException.

Any idea of why a viewscoped managed bean is constructed when navigating to a page that does not use it?

Edit: If in order to navigate to "otherpage.xhtml" I use the commandlink in "home.xhtml", 6 extra beans are created. But, if instead of using the link, I type the url in the browser; it works fine. No extra bean is created. Maybe there's something wrong in how I implemented the link. This is the code:

<h:form>
    <h:commandLink value="Go to other page" action="otherPage" />
</h:form>

And this is the navigation rule in faces-config:

 <navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>otherPage</from-outcome>
            <to-view-id>/views/otherPage.xhtml</to-view-id>
            <redirect/>
        </navigation-case>
</navigation-rule>

Is there anything wrong there?

Thanks! Damian

damian
  • 4,024
  • 5
  • 35
  • 53

1 Answers1

0

You surely have a #{myBean} somewhere in the view or one of its templates/include/tag/composite files, or as a @ManagedProperty of the beans referenced by the view. Putting a breakpoint in the (post)constructor and investigating the stacktrace should give enough insights who/what has triggered the bean's construction.


Unrelated to the concrete problem, the ExternalContext#redirect() already implicitly calls FacesContext#responseComplete(), you don't need to call it yourself. See also the method's javadoc.


Update: a <h:commandLink> submits its parent POST <form> to the current page (and thus creates all its related beans!) and then depending on the navigation outcome, it will forward/redirect to the result page. You shouldn't be using commandlinks/commandbuttons for plain page-to-page navigation. Use <h:link> instead.

<h:link value="Go to other page" outcome="views/otherPage" />

You can eventually also get rid of that <navigation-case>. If you really insist in keeping that navigation case, then use outcome="otherPage" instead.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • hey @BalusC take a look at the edit in the question. btw, I didn't find uses of the bean anywhere in that page – damian Nov 05 '11 at 19:47
  • thanks @BalusC that actually solvved part of the problem; but also I had to remove all the navigation cases from the faces-config (only kept 2 or 3 that were really necesarry) because otherwise beans were constructed anyways, even using h:link. I don't know why, but after removing the rules, everything started to work as expected. One remark: I had one navigation rule from-view-id = * and then a lot of navigation-case (one for each page). maybe that was wrong.. – damian Nov 09 '11 at 12:24