2012-04-27 53 views
0

我已經做了我的代碼如下修改: ConnectionPool.java:如何使用會話過濾器的JSF登錄表單

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); 
     } 
    } 

但它不是從數據庫的登錄獲取數據form.Please提出建議如何做到這一點,並通過使用會話過濾器。

回答

3

您在一個類中混合登錄過濾器和JSF託管bean的職責。這個不對。將它們分成兩節課。

一個過濾器類:

@WebFilter("/secured/*") 
public class LoginFilter implements Filter { 

    // ... 

} 

@WebFilter註釋將過濾地圖上/secured/*的URL模式,您可以在例如更改爲您的安全網頁的任何公共路徑/app/*/private/*

而且一個支撐類:

@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) 

你被==比較字符串。這隻會通過參考而不是價值來比較它們。這將從不評估true如果一個字符串由servlet容器創建,另一個字符串由JDBC驅動程序創建。您寧可使用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); 
} 
0

那麼,在日誌中,您會看到LoginAction.java的第89行出現錯誤。也許這行

String uname = result.get(0).getUsername(); 

我的猜測是,

列表結果= UserDAO.getUser(用戶名);

沒有結果,因爲找不到用戶名。所以結果將是= null。當它爲空時,你不能做result.get(0)。

添加檢查結果== null。然後你知道用戶名或密碼錯誤。

這是什麼意思 「以及如何使用會話過濾器進行登錄。」 你想實現什麼?

+0

當用戶登錄時,它使用會話過濾器並檢查該用戶的會話,並基於該會話重定向到登錄頁面或其他用戶歡迎頁面。 – spt 2012-04-27 09:35:23

+0

我收到以下錯誤:'java.util.concurrent.ExecutionException:org.apache.catalina.LifecycleException:未能啓動組件[StandardEngine [Catalina] .StandardHost [localhost] .StandardContext [/ SessionFilter示例]]由:org.apache.catalina.LifecycleException:無法啓動組件[StandardEngine [Catalina] .StandardHost [localhost] .StandardContext [/ SessionFilter示例]]原因:java.lang.IllegalArgumentException:無效 LoginFilter in filter mapping'Please give建議重新使用它。 – spt 2012-04-30 09:12:06