繁体   English   中英

如何在jsf中使用会话过滤器进行登录表单

[英]How to use session filters in jsf for login form

我在代码中做了以下修改: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);
        }
    }

但是它没有从登录表单的数据库中获取数据。请提供有关如何使用会话过滤器的建议。

您正在将登录过滤器和JSF托管Bean的职责混合在一个类中。 这是不对的。 将他们分成2个班级。

一类过滤器:

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

    // ...

}

@WebFilter批注会将过滤器映射到/secured/*的URL模式,您可以将其更改为受保护页面的任何通用路径,例如/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上输入UNIQUE 更改DAO以仅返回一个User而不是List<User> 最后,如下更改DAO方法:

public User find(String username, String password) throws SQLException {
    // ...
}

只需执行SELECT ... FROM ... WHERE username=? AND password=md5(?) SELECT ... FROM ... WHERE username=? AND password=md5(?) 如果在数据库中找不到匹配项,则返回null 如果在数据库中找到匹配项,则返回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);
}

好了,在日志中,您看到该错误发生在LoginAction.java的第89行。 可能这条线

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

我的猜测是

列出结果= UserDAO.getUser(用户名);

由于找不到用户名,因此没有结果。 因此结果将为null。 而且,如果它为null,则不能执行result.get(0)。

在result == null上添加检查。 然后,您知道用户名或密码不正确。

您的意思是“以及如何使用会话过滤器进行登录”。 您想实现什么?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM