I have done the following modifications in my code:
ConnectionPool.java:
package com.dao;
import java.sql.*;
import javax.sql.DataSource;
import javax.naming.InitialContext;
public class ConnectionPool
{
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
private ConnectionPool()
{
try
{
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:/comp/env/jdbc/fabula");
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Get an instance of the connection pool
* @return ConnectionPool
*/
public static ConnectionPool getInstance()
{
if (pool == null)
{
pool = new ConnectionPool();
}
return pool;
}
/**
* Get a connection
* @return Connection
*/
public Connection getConnection()
{
try
{
return dataSource.getConnection();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
return null;
}
}
/**
* Free a connection
* @param c
*/
public void freeConnection(Connection c)
{
try
{
c.close();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
}
}
DBUtil.java:
package com.dao;
import java.sql.*;
public class DBUtil
{
public static void closeStatement(Statement s)
{
try
{
if (s != null)
s.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
public static void closePreparedStatement(Statement ps)
{
try
{
if (ps != null)
ps.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
public static void closeResultSet(ResultSet rs)
{
try
{
if (rs != null)
rs.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
UserDAO.java:
package com.dao;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import com.entities.User;
import com.dao.DBUtil;
public class UserDAO
{
/**
* Get a specific user from the data store
* @param userName
* @return collection of User objects
*/
public static User getUser(String userName)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
User usersList = new User();
String query = "SELECT * FROM users " +
"WHERE username = ?";
System.out.println("Query:"+query);
try
{
ps = connection.prepareStatement(query);
ps.setString(1, userName);
rs = ps.executeQuery();
System.out.println("Query1:"+query);
while (rs.next())
{
User user = new User();
user.setUsername(rs.getString("username"));
user.setUserId(Integer.valueOf(rs.getString("userid") ) );
user.setPassword(rs.getString("password") );
System.out.println("username1:"+rs.getString("username"));
System.out.println("password1:"+rs.getString("password"));
}
return usersList;
}
catch (SQLException e){
e.printStackTrace();
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
/**
* Get all users from the data store
* @return collection of User objects
*/
public static List <User> getAllUsers()
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
List <User>usersList = new ArrayList<User>();
String query = "SELECT * FROM users ";
try
{
ps = connection.prepareStatement(query);
rs = ps.executeQuery();
while (rs.next())
{
User user = new User();
user.setUsername(rs.getString("username"));
user.setUserId(Integer.valueOf(rs.getString("userid")));
user.setPassword(rs.getString("password") );
usersList.add(user);
}
return usersList;
}
catch (SQLException e){
e.printStackTrace();
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
}
User.java:
package com.entities;
public class User {
private String username;
private String password;
private int userId;
public User()
{}
public User(int userId, String name, String password) {
super();
this.userId = userId;
this.username = name;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String name) {
this.username = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
LoginFilter.java:
package com.filter;
import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
@WebFilter("/WebContent/user.xhtml")
public class LoginFilter implements Filter
{
HttpServletRequest req;
HttpServletResponse resp;
DataSource ds;
InitialContext ctx;
FilterConfig config;
FacesContext context;
@Override
public void init(FilterConfig filterConfig){
System.out.println("Instance created of " + getClass().getName());
try {
ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/fabula");
} catch (NamingException e) {
e.printStackTrace();
}
this.config = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (req.getSession().getAttribute("username") == null) {
resp.sendRedirect(req.getContextPath() + "/login.xhtml");
}
else
{
chain.doFilter(req, resp);
}
}
@Override
public void destroy() {
}
}
LoginAction.java:
package com.service;
import javax.faces.application.FacesMessage;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import com.dao.UserDAO;
import com.entities.User;
@ManagedBean
@RequestScoped
public class LoginAction
{
UserService userService = new UserService();
private String username;
private String password;
private User selectedUser;
FacesContext context;
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 User getSelectedUser()
{
if(selectedUser == null){
selectedUser = new User();
}
return selectedUser;
}
public void setSelectedUser(User selectedUser)
{
this.selectedUser = selectedUser;
}
public String login()
{
User user = UserDAO.getUser(username);
FacesContext context = FacesContext.getCurrentInstance();
if (user != null)
{
context.getExternalContext().getSessionMap().put("user", user);
return "user?faces-redirect=true";
}
else
{
context.addMessage("username", new FacesMessage("Invalid UserName and Password"));
return "login";
}
}
}
UserService.java:
package com.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.entities.User;
public class UserService {
private static final Map<Integer, User> USERS_TABLE = new HashMap<Integer, User>();
public Integer create(User user)
{
if(user == null)
{
throw new RuntimeException("Unable to create User. User object is null.");
}
Integer userId = this.getMaxUserId();
user.setUserId(userId);
USERS_TABLE.put(userId, user);
return userId;
}
public Collection<User> getAllUsers()
{
return USERS_TABLE.values();
}
public User getUser(Integer userId)
{
return USERS_TABLE.get(userId);
}
public Collection<User> searchUsers(String username)
{
String searchCriteria = (username == null)? "":username.toLowerCase().trim();
Collection<User> users = USERS_TABLE.values();
Collection<User> searchResults = new ArrayList<User>();
for (User user : users)
{
if(user.getUsername() != null && user.getUsername().toLowerCase().trim().startsWith(searchCriteria))
{
searchResults.add(user);
}
}
return searchResults;
}
public void update(User user)
{
if(user == null || !USERS_TABLE.containsKey(user.getUserId()))
{
throw new RuntimeException("Unable to update User. User object is null or User Id ["+user.getUserId()+"] is invalid." );
}
USERS_TABLE.put(user.getUserId(), user);
}
protected Integer getMaxUserId()
{
Set<Integer> keys = USERS_TABLE.keySet();
Integer maxId = 1;
for (Integer key : keys)
{
if(key > maxId)
{
maxId = key;
}
}
return maxId;
}
}
Login.xhtml:
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="refresh" content="${pageContext.session.maxInactiveInterval};url=sessionexpired.jsp"/>
<title>User login</title>
</h:head>
<h:body>
<div id="wrapper">
<h:form>
<div><h:messages ></h:messages></div>
<div id="entrypermission">
<label class="lbl"> User Name: </label><h:inputText id="user" value="#{loginAction.username}" label="Username" require="true"></h:inputText>
<label class="lbl"> Password: </label><h:inputSecret id="pass" value="#{loginAction.password}" label="Password" required="true"></h:inputSecret>
<h:outputText value=" "/><h:commandButton type="submit" value="Log In" action="#{loginAction.login}"></h:commandButton>
</div>
</h:form>
</div>
</h:body>
User.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
</h:head>
<h:body>
<center>
<h1>Welcome to the user</h1>
</center>
</h:body>
</html>
</html>
And my web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>UserInfo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>com.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>*.xhtml</url-pattern>
</filter-mapping>
<resource-ref>
<description>MySQL Datasource example</description>
<res-ref-name>jdbc/fabula</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
</web-app>
But while running my application i am getting the output, but it is not checking the username from the database and going to next page for very value.Due to this I have done the modifications in LoginAction.java and UserDAo.java.
LoginAction.java:
String pwd = "";
String uname = "";
List<User> result;
public String login()
{
//List<User> result=UserDAO.getUser(username);
//User user = UserDAO.getUser(username);
String username = getUsername();
FacesContext context = FacesContext.getCurrentInstance();
if (username != null)
{
result=UserDAO.getUser(username);
if(result.size() >0)
{
uname = result.get(0).getUsername();
pwd = result.get(0).getPassword();
}
context.getExternalContext().getSessionMap().put("user", username);
return "user?faces-redirect=true";
}
else
{
context.addMessage("username", new FacesMessage("Invalid UserName and Password"));
return "login?faces-redirect=true";
}
}
UserDAO.java:
public static List<UserForm> getUser(String userName)
{
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
List <UserForm>usersList = new ArrayList<UserForm>();
String query = "SELECT * FROM users " +
"WHERE username = ?";
System.out.println("Query:"+query);
try
{
ps = connection.prepareStatement(query);
ps.setString(1, userName);
rs = ps.executeQuery();
System.out.println("Query1:"+query);
while (rs.next())
{
UserForm user = new UserForm();
user.setUsername(rs.getString("username"));
user.setUserId(Integer.valueOf(rs.getString("userid") ) );
user.setPassword(rs.getString("password") );
usersList.add(user);
System.out.println("username1:"+rs.getString("username"));
System.out.println("password1:"+rs.getString("password"));
}
return usersList;
}
catch (SQLException e){
e.printStackTrace();
return null;
}
finally
{
DBUtil.closeResultSet(rs);
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
But it is not getting the data from database for the login form.Please give suggestions how to do it and by using session filters.
You’re mingling the responsibilities of a login filter and a JSF managed bean in a single class. This is not right. Split them over 2 classes.
One filter class:
The
@WebFilterannotation will map the filter on an URL pattern of/secured/*, you can change it to whatever common path of your secured pages e.g./app/*,/private/*, etc.And one backing bean class:
Do NOT make it
@ApplicationScoped. Its properties would going to be shared among all users throughout the entire application’s lifetime. Also do NOT make the HTTP request, response, session and JSF context a property of the bean. It makes your code threadunsafe. In other words, all the following properties are forbidden:As to your concrete problem, the way how you retrieve the
Userfrom the DAO and check the login is quite strange. The DAO returns aList<User>based on username. Is there really the possibility that there’s more than one user with the same login name? Then you’ve another serious problem in your database datamodel. Put anUNIQUEon the loginname. Change the DAO to return just aUserinstead ofList<User>. Finally change the DAO method as follows:Just execute
SELECT ... FROM ... WHERE username=? AND password=md5(?). If no match is found in DB, returnnull. If a match is found in DB, returnUser.Further you’re making another mistake here:
You’re comparing strings by
==. That would only compare them by reference, not by value. This will never evaluatetrueif the one string is created by servlet container and the other string is created by JDBC driver. You rather want to useequals()method. But that check is after all completely unnecessary if you just check ifuserDAO.find()returnsnullor not.All with all, your entire
login()method can be simplified as follows:Don’t forget to change the
doFilter()method accordingly: