我在代码中做了以下修改: 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>
我的web.xml是:
<?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>
但是在运行我的应用程序时,我正在获取输出,但它没有检查数据库中的用户名并转到下一页非常有价值。由于这一点,我在LoginAction.java和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);
}
}
但它没有从登录表单的数据库获取数据。请提供建议如何操作并使用会话过滤器。
答案 0 :(得分:3)
您在单个类中混合了登录过滤器和JSF托管bean的职责。这个不对。将它们分成2个班级。
一个过滤类:
@WebFilter("/secured/*")
public class LoginFilter implements Filter {
// ...
}
@WebFilter
注释会将过滤器映射到/secured/*
的网址格式,您可以将其更改为受保护网页的任何常见路径,例如/app/*
,/private/*
等
一个支持bean类:
@ManagedBean
@RequestScoped
public class LoginBacking {
// ...
}
不要成功@ApplicationScoped
。在整个应用程序的生命周期中,它的属性将在所有用户之间共享。另外,不要将HTTP请求,响应,会话和JSF上下文作为bean的属性。它使您的代码线程安全。换句话说,禁止所有以下属性:
public static HttpSession session;
HttpServletRequest req;
HttpServletResponse resp;
FacesContext context;
至于你的具体问题,从DAO检索User
并检查登录的方式很奇怪。 DAO根据用户名返回List<User>
。是否有多个用户具有相同登录名的可能性?然后,您的数据库数据模型中存在另一个严重问题。在登录名上加上UNIQUE
。更改DAO只返回User
而不是List<User>
。最后更改DAO方法如下:
public User find(String username, String password) throws SQLException {
// ...
}
只需执行SELECT ... FROM ... WHERE username=? AND password=md5(?)
即可。如果在DB中找不到匹配项,请返回null
。如果在DB中找到匹配项,请返回User
。
if (resultSet.next()) {
user = new User();
user.setId(resultSet.getLong("id"));
// ...
}
此外,你在这里犯了另一个错误:
if(uname == username && pwd == password)
您要按==
比较字符串。那只会通过参考而不是价值来比较它们。如果一个字符串由servlet容器创建,另一个字符串由JDBC驱动程序创建,那么永远不会评估true
。您更愿意使用equals()
方法。但是,如果您只是检查userDAO.find()
是否返回null
,则完全没必要检查。
总而言之,您的整个login()
方法可以简化如下:
public String login() {
User user = userDAO.find(username, password);
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 null;
}
}
不要忘记相应地更改doFilter()
方法:
if (req.getSession().getAttribute("user") == null) {
resp.sendRedirect(req.getContextPath() + "/login.xhtml");
} else {
chain.doFilter(req, resp);
}
答案 1 :(得分:0)
好吧,在日志中,您会看到LoginAction.java第89行发生错误。可能这一行
String uname = result.get(0).getUsername();
我猜是
列出结果= UserDAO.getUser(用户名);
没有结果,因为找不到用户名。所以结果将是= null。当它为null时,你不能做result.get(0)。
添加结果检查== null。然后你知道用户名或密码不正确。
你是什么意思 “以及如何使用会话过滤器进行登录。” 你想要达到什么目标?