I’m creating a login example to have a look at JSF with Faces, I have a PHP background so I’m with a lot of difficulties.
This is how I’m working, based on some google searches.
I have a folder with 3 controllers:
MainController;
HomeController;
LoginController;
I’ll show each one bu without the get and set to make it easier to read.
MainController:
package com.erp3.gui.controllers;
import javax.faces.context.FacesContext;
public class MainController {
public LoginController loginController;
public MainController() {
this.checkUserSession();
}
public String checkUserSession() {
loginController = (LoginController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("loginController");
if (!loginController.getIsLoggedIn()) {
return "login.html";
} else {
return null;
}
}
}
HomeController:
package com.erp3.gui.controllers;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
public class HomeController extends MainController {
public String username;
public HomeController() {
super();
}
}
LoginController:
package com.erp3.gui.controllers;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
@ManagedBean
public class LoginController {
public Boolean isLoggedIn = false;
private String username;
private String password;
private FacesMessage msg;
public String login() {
if (this.getUsername().equals("daniel") && this.getPassword().equals("123")) {
this.isLoggedIn = true;
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("loginController", this);
return "home.html";
} else {
this.isLoggedIn = false;
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuário ou senha inválida.", username);
FacesContext.getCurrentInstance().addMessage(null, msg);
return "login.html";
}
}
public String logOut() {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("loginController");
return "login.html";
}
}
So, reading some pages I found this way of creating a session, don’t no if it is correct:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("loginController", this);
What happens is that on HomeController I check for session status, if false redirect to login.xhtml
Another thing, when I log in, I’m redirected to the home.xhtml but the url is still on login.xhtml and when I change it to home.xhtml it returns me this beautiful error:
Cant instantiate class: com.erp3.gui.controllers.HomeController.
I also would like to know that when I call my home.xhtml file, it loads the HomeController or Java simply loads the home.xhtml?
Navigation by returning string outcomes is only possible in real action methods which are invoked by
UICommandcomponents like<h:commandButton>, not in constructors.That exception is a general exception which basically tells that
new HomeController()failed. This should in turn have a root cause further down in the stacktrace. Perhaps aNullPointerExceptionbecauseloginControllerisnull? In any way, the root cause which is the bottommost exception in the stacktrace is the most important exception to look for. Keep this in mind.Both problems can be fixed the following way:
However, this approach has a technical problem. It is too late to send a redirect after the response is already committed. A bean can be constructed only at that moment when a part of the response has already been sent to the client. Rather look at container managed authentication or at least at servlet filters. But that’s another story.