1

This is my fragment:

<ui:fragment rendered="#{}">
    <ui:include src="../includes/top.xhtml"/>
</ui:fragment>

My LoginController will redirect to the page home.html that extends MainController that have a boolean method showComponent so when I try to call this mainController.showComponent() I get a nullPointerException because, as I notice, Java loads the html first to see if it is calling any Java Class so when I try to access mainController(that is extended from HomeController, that was not yet called) I get this null pointer

. How to I check inside the fragment if the maisController is set?

Here is what I've tried so far

<ui:fragment rendered="#{not empty mainController ? true : false}">

It always returns true.

Here is my MainController class:

package com.erp3.gui.controllers;

import java.io.IOException;
import javax.faces.bean.ManagedBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

@ManagedBean
public class MainController {

    public LoginController loginController;
    public ExternalContext ec;

    public void checkUserSession() throws IOException {
        ec = FacesContext.getCurrentInstance().getExternalContext();
        loginController = (LoginController) ec.getSessionMap().get("loginController");
        loginController = (LoginController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("loginController");
        if (loginController == null || !loginController.getIsLoggedIn()) {
            ec.redirect(ec.getRequestContextPath() + "/views/login.html");
        }
    }

    public Boolean showComponent() {
        return this.loginController.getIsLoggedIn();
    }
}

My method showComponent() is returning a session object property from loginController

2 Answers2

2

It throws NullPointerException because loginController is apparently null. If it's another @ManagedBean, then you need to inject it as a manged property. This way you don't need to manually grab it from the session map. Also, you should give your MainController a valid bean scope. Without a scope, a new one will be created on every single EL expression #{mainController}.

@ManagedBean
@RequestScoped
public class MainController {

    @ManagedProperty("#{loginController}") // +getter+setter
    public LoginController loginController;

    @PostConstruct // Will be invoked directly after construction and managed property injection.
    public void checkUserSession() throws IOException {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        if (!loginController.getIsLoggedIn()) {
            ec.redirect(ec.getRequestContextPath() + "/views/login.html");
        }
    }

    public boolean isShowComponent() {
        return loginController.getIsLoggedIn();
    }

}

Then you can use it:

<ui:fragment rendered="#{mainController.showComponent}">

But why don't you just access #{loginController} directly?

<ui:fragment rendered="#{loginController.isLoggedIn}">

As to your question why #{not empty mainController ? true : false} always evaluates true is because JSF @ManagedBeans are never null. If one doesn't exist in EL scope, JSF will autocreate one.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • because it will be lost on the next request, won't it? don't I have to access the session object? –  Apr 26 '12 at 19:44
  • It's apparently in the session map, so it's available through the entire session. This is true when `LoginController` is actually a `@ManagedBean @SessionScoped`. – BalusC Apr 26 '12 at 19:45
  • Then it's apparently not a `@ManagedBean @SessionScoped`. Why not? – BalusC Apr 26 '12 at 19:46
  • yes...I forgot the `@SessionScoped` this annotation makes the class be accessible on the entire project? –  Apr 26 '12 at 19:48
  • Not exactly that. The `@ManagedBean` makes it a JSF managed bean. The `@SessionScoped` makes sure that there's only one instance during browser's session. Only an `@ApplicationScoped` ensures that there's only one instance during application's lifetime (which I think you actually mean with "entire project"). See for some background information also http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading/3106909#3106909 and http://stackoverflow.com/questions/7031885/how-to-choose-the-right-bean-scope/7031941#7031941. – BalusC Apr 26 '12 at 19:49
1

It seems that loginController is null when you call showComponent. Create method getLoginController:

public getLoginController() {
    (LoginController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("loginController");
}

public Boolean showComponent() {
    return getLoginController() != null && getLoginController().getIsLoggedIn();
}
Mikita Belahlazau
  • 15,326
  • 2
  • 38
  • 43