I'm implementing a JSF application in which the credentials that a user provides are validated by looking at a MySQL database table and, in case that they were found, an HTTP session between the client and the server starts and a "welcome" page is returned in response to his/her request. The "welcome" page contains a logout button, which does nothing (I checked the HTTP traffic to ensure it) when I click on it.
<h:commandButton value="Logout" type="submit" action="#{logoutBean.terminate}"/>
The logout button is related to a managed bean that handles the logout process (i.e. terminates the session and returns the start page). The function that terminates the session and return the start page is the following:
public String terminate() {
System.out.println("Here!"); //for debug
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =
(HttpSession) fc.getExternalContext().getSession(false);
try {
session.invalidate();
} catch(IllegalStateException isEx) {
isEx.printStackTrace();
}
return "index";
}
Even the message Here!
doesn't get viewed in the console.
To be more specific, let me post the full code below.
My welcome.xhtml page:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Admin's page</title>
</head>
<body>
<h2>Welcome admin!</h2>
<p>You are successfully logged in</p> <br/>
<h:commandButton value="Logout" type="submit" action="#{logoutBean.terminate}"/>
</body>
</html>
My LogoutBean.java file (handles the logout request):
package loginbean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
@ManagedBean(name="logoutBean")
@RequestScoped
public class LogoutBean {
private String errorMsg = null;
public LogoutBean() { }
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String terminate() {
System.out.println("Here!");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =
(HttpSession) fc.getExternalContext().getSession(false);
try {
session.invalidate();
} catch(IllegalStateException isEx) {
isEx.printStackTrace();
}
return "index";
}
}
My start page (index.xhtml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<h:outputText value="#{loginBean.errorMsg}"
rendered="#{loginBean.errorMsg != null}"
style="color:red;"/>
<h:form>
User Name: <h:inputText id="userName" value="# {loginBean.userName}"/>
<br/>
Password: <h:inputSecret id="password" value="#{loginBean.password}"/>
<br/>
<h:commandButton value="Submit" type="submit" action="#{loginBean.validate}"/>
<h:commandButton value="Reset" type="reset"/>
</h:form>
</body>
</html>
and my LoginBean.java (handles the login request)
package loginbean;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import java.sql.*;
@ManagedBean(name="loginBean")
@RequestScoped
public class LoginBean {
private String userName = null;
private String password = null;
private String errorMsg = null;
public LoginBean() {}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String validate() {
try {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dbname?useSSL=false",
"rootName", "aPassword");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select name, password from admins;");
// Look for the credentials into the table.
while (rs.next()) {
if (rs.getString("name").equals(userName)
&& rs.getString("password").equals(password)) {
errorMsg = "null";
// Start a session with the client.
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fc.getExternalContext().getSession(true);
System.out.println("Session ID = " + session.getId());
// Return the "welcome.xhtml" page.
return "welcome";
}
}
} catch(SQLException sqlEx) {
System.out.println("Error code: " + sqlEx.getErrorCode());
}
errorMsg = "Invalid user. Please try again";
return null;
}
}
I think there's no need to post my web.xml
, since it's pretty obvious for such an application.
Could someone help me to implement such a logout process correctly?