Reputation:
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
Upvotes: 1
Views: 2546
Reputation: 1108722
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 @ManagedBean
s are never null
. If one doesn't exist in EL scope, JSF will autocreate one.
Upvotes: 2
Reputation: 15434
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();
}
Upvotes: 1