尝试登录JSF Web应用程序时出现NullPointerException

时间:2015-01-04 17:00:21

标签: jsf

第一次海报为任何错误道歉。我有一个连接到Oracle数据库的Web应用程序,并且不知道为什么我在尝试登录时获得NPE:

StackTrace

enter image description here

它指向我的登录bean中的这个方法:

public String checkCredentials() {
    String outcome = "";

    User user = userHandler.findUserByUsername(username); <---NullPointerException
    if (username.equals(user.getUserName())
            && password.equals(user.getPassword())) {
        //clearFields();
        switch (user.getUserType()) {
            case "Super":
                outcome = "Super";
                break;
            case "Admin":
                outcome = "Admin";
                break;
            case "Teacher":
                outcome = "Teacher";
                break;
            case "Parent":
                outcome = "Parent";
                break;
            case "Student":
                outcome = "Student";
                break;
        }
    }
    if (outcome.isEmpty()) {
        clearFields();
        FacesMessage msg = new FacesMessage("Username and/or password not recognised.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    return outcome;
}

我在处理程序中测试了以下方法,以确保SQL提取正确的信息:

public User findUserByUsername(String username) {
    User u = null;

    DatabaseConnection con = ConnectionManager.getInstance().getConnection();
    con.prepareStatement(FIND_USER_BY_USERNAME);
    con.setStatementParameter(1, username);
    if (con.executePreparedStatement()) {
        u = prepareUser(con.getResultSet());
    }
    con.close();
    return u;
}

private User prepareUser(ResultSet rs) {
    User u = null;

    try {
        if (rs.next()) {
            u = new User(rs.getInt("UserId"),
                    rs.getString("fName"),
                    rs.getString("lName"),
                    rs.getString("userName"),
                    rs.getString("password"),
                    rs.getString("userType"),
                    rs.getInt("schoolID"));
        }
    } catch (SQLException sqle) {
        sqle.getMessage();
    }
    return u;
}

这是我的登录xhtml:

<h:body>
    <ui:composition template="/template.xhtml">
        <ui:define name="content">
            <h2>Login</h2>
            <h:messages class="error" />
            <h:form>
                <p>Username:
                    <h:inputText id="username" 
                                 maxlength="12" 
                                 required="true" 
                                 requiredMessage="Please enter your username" 
                                 title="Your username: "
                                 value="#{login.username}" />
                </p>
                <p>Password: 
                    <h:inputSecret id="password" 
                                   maxlength="15" 
                                   required="true" 
                                   requiredMessage="Please enter your password" 
                                   title="Your password: "
                                   value="#{login.password}" />
                </p>
                <p>
                    <h:commandButton type="submit" value="Log-in" action="#{login.checkCredentials()}"/>
                    <h:commandButton type="reset" value="Reset" />
                </p>
            </h:form>
        </ui:define>
    </ui:composition>
</h:body>

用户在表单中设置NPE点所使用的用户名,用户名和密码存在于我的数据库中,SQL字符串&#39; FIND_USER_BY_USERNAME&#39;在单独测试时拉出正确的用户。真的很欣赏正确方向的一点。

编辑: Login_UI:

package Beans;

import ActiveRecord.User;
import ActiveRecord.UserHandler;
import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

@Named(value = "login")
@SessionScoped
public class Login_UI implements Serializable {

    private String username;
    private String password;
    private String userType;
    private final transient UserHandler userHandler;

    public Login_UI() {
        clearFields();
        userHandler = new UserHandler();
    }

    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 getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public void clearFields() {
        username = "";
        password = "";
    }

    public String checkCredentials() {
        String outcome = "";

        User user = userHandler.findUserByUsername(username);
        if (username.equals(user.getUserName())
                && password.equals(user.getPassword())) {
            //clearFields();
            switch (user.getUserType()) {
                case "Super":
                    outcome = "Super";
                    break;
                case "Admin":
                    outcome = "Admin";
                    break;
                case "Teacher":
                    outcome = "Teacher";
                    break;
                case "Parent":
                    outcome = "Parent";
                    break;
                case "Student":
                    outcome = "Student";
                    break;
            }
        }
        if (outcome.isEmpty()) {
            clearFields();
            FacesMessage msg = new FacesMessage("Username and/or password not recognised.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
        return outcome;
    }
}

userHandler:

package ActiveRecord;

import Database.ConnectionManager;
import Database.DatabaseConnection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class UserHandler {

    private static final String FIND_USER_BY_USERNAME = "SELECT userID, fName, lName, "
            + "username, password, usertype, FK1_schoolID FROM UserInformation "
            + "WHERE UserName = ?";
    private static final String FIND_USER_BY_ID = "SELECT fName, lName, userName, "
            + "password, userType, FK1_schoolID FROM UserInformation "
            + "WHERE userID = ?";
    private static final String FIND_USER_BY_FNAME = "SELECT * FROM UserInformation "
            + "WHERE fName = ? "
            + "ORDER BY userID";
    private static final String FIND_USER_BY_LNAME = "SELECT * FROM UserInformation "
            + "WHERE lName = ? "
            + "ORDER BY userID";
    private static final String FIND_ALL_USERS = "SELECT * FROM UserInformation "
            + "ORDER BY userID";
    private static final String FIND_STUDENT_BY_ID = "SELECT StudentID, yearGroup, "
            + "overallMarks, FK2_UserID FROM Student WHERE StudentID = ? ";
    private static final String FIND_STUDENT_BY_YEARGROUP = "SELECT StudentID, yearGroup, "
            + "overallMarks, FK2_UserID FROM Student WHERE yearGroup = ? "
            + "ORDER BY studentID";
    private static final String FIND_ALL_STUDENTS = "SELECT * FROM Student "
            + "LEFT JOIN UserInformation ON Student.FK2_UserId = UserInformation.UserId "
            + "ORDER BY Student.studentId";

    private User prepareUser(ResultSet rs) {
        User u = null;

        try {
            if (rs.next()) {
                u = new User(rs.getInt("UserId"),
                        rs.getString("fName"),
                        rs.getString("lName"),
                        rs.getString("userName"),
                        rs.getString("password"),
                        rs.getString("userType"),
                        rs.getInt("schoolID"));
                System.out.println("Test: prepUser");
            }
        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return u;
    }

    private ArrayList<User> prepareUsers(ResultSet rs) {
        ArrayList<User> u = new ArrayList();

        try {
            while (rs.next()) {
                u.add(new User(rs.getInt("UserId"),
                        rs.getString("fName"),
                        rs.getString("lName"),
                        rs.getString("userName"),
                        rs.getString("password"),
                        rs.getString("userType"),
                        rs.getInt("schoolID")));
            }
        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return u;
    }

    private Student prepareStudent(ResultSet rs) {
        Student s = null;

        try {
            if (rs.next()) {
                s = new Student(rs.getInt("StudentId"),
                        rs.getInt("yearGroup"),
                        rs.getInt("overallMarks"),
                        rs.getInt("FK1_StudenttestID"),
                        rs.getInt("FK2_UserID"));
            }
        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return s;
    }

    private ArrayList<Student> prepareStudents(ResultSet rs) {
        ArrayList<Student> s = new ArrayList();

        try {
            while (rs.next()) {
                s.add(new Student(rs.getInt("StudentId"),
                        rs.getInt("yearGroup"),
                        rs.getInt("overallMarks"),
                        rs.getInt("FK1_StudenttestID"),
                        rs.getInt("FK2_UserID")));
            }
        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return s;
    }

    public User findUserById(int userId) {
        User u = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_USER_BY_ID);
        con.setStatementParameter(1, userId);
        if (con.executePreparedStatement()) {
            u = prepareUser(con.getResultSet());
        }
        con.close();
        return u;
    }

    public ArrayList<User> findUserByFirstName(String fName) {
        ArrayList<User> u = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_USER_BY_FNAME);
        con.setStatementParameter(1, fName);
        if (con.executePreparedStatement()) {
            u = prepareUsers(con.getResultSet());
        }
        con.close();
        return u;
    }

    public ArrayList<User> findUserByLastName(String lName) {
        ArrayList<User> u = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_USER_BY_LNAME);
        con.setStatementParameter(1, lName);
        if (con.executePreparedStatement()) {
            u = prepareUsers(con.getResultSet());
        }
        con.close();
        return u;
    }

    public User findUserByUsername(String username) {
        User u = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_USER_BY_USERNAME);
        con.setStatementParameter(1, username);
        if (con.executePreparedStatement()) {
            u = prepareUser(con.getResultSet());
        }
        con.close();
        return u;
    }

    public ArrayList<User> findAllUsers() {
        ArrayList<User> u = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_ALL_USERS);
        if (con.executePreparedStatement()) {
            u = prepareUsers(con.getResultSet());
        }
        con.close();
        return u;
    }

    public Student findStudentById(int studentId) {
        Student s = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_STUDENT_BY_ID);
        con.setStatementParameter(1, studentId);
        if (con.executePreparedStatement()) {
            s = prepareStudent(con.getResultSet());
        }
        con.close();
        return s;
    }

    public ArrayList<Student> findStudentByYearGroup() {
        ArrayList<Student> s = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_STUDENT_BY_YEARGROUP);
        if (con.executePreparedStatement()) {
            s = prepareStudents(con.getResultSet());
        }
        con.close();
        return s;
    }

    public ArrayList<Student> findAllStudents() {
        ArrayList<Student> s = null;

        DatabaseConnection con = ConnectionManager.getInstance().getConnection();
        con.prepareStatement(FIND_ALL_STUDENTS);
        if (con.executePreparedStatement()) {
            s = prepareStudents(con.getResultSet());
        }
        con.close();
        return s;
    }

    public boolean createUser(User u) {
        boolean userCreated = false;
        ArrayList<User> users = findAllUsers();
        boolean found = false;

        for (User x : users) {
            if (x.getUserName().equals(u.getUserName())) {
                found = true;
            }
        }
        if (!found) {
            try {
                u.insert();
                userCreated = true;
            } catch (Exception e) {
                e.getMessage();
            }
        }
        return userCreated;
    }

    public boolean deleteUser(User u) {
        boolean deleted = false;

        if (u != null) {
            try {
                u.delete();
                deleted = true;
            } catch (Exception e) {
                e.getMessage();
            }
        }
        return deleted;
    }
}

对所有编辑道歉,我发现问题只是不确定如何解决它,我的单例数据库连接应该创建一个包含5个可用连接的池DatabaseConnection con = ConnectionManager.getInstance()。getConnection();但在此调用期间,它返回一个空连接

package Database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DatabaseConnection {

    private static final String DATABASE_URL = "removed";
    private final ConnectionManager connManager;
    private Connection conn = null;
    private PreparedStatement stmt = null;
    private ResultSet rs = null;
    private int updateCount = -1;

    public DatabaseConnection(ConnectionManager connectionManager) throws SQLException {
        connManager = connectionManager;
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = DriverManager.getConnection(DATABASE_URL);
    }

    public void close() {
        connManager.releaseConnection(this);
    }

    public boolean prepareStatement(String sql) {
        boolean statementPrepared = false;

        try {
            stmt = conn.prepareStatement(sql);
            statementPrepared = true;

        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return statementPrepared;
    }

    public boolean executePreparedStatement() {
        boolean resultSetAvailable = false;

        try {
            resultSetAvailable = stmt.execute();
            updateCount = stmt.getUpdateCount();
            rs = stmt.getResultSet();
        } catch (SQLException sqle) {
            sqle.getMessage();
        }
        return resultSetAvailable;
    }

    public boolean setStatementParameter(int paramIndex, boolean paramValue) {
        boolean paramSet = false;

        if (stmt != null) {
            try {
                stmt.setBoolean(paramIndex, paramValue);
                paramSet = true;
            } catch (SQLException sqle) {
                sqle.getMessage();
            }
        }
        return paramSet;
    }

    public boolean setStatementParameter(int paramIndex, String paramValue) {
        boolean paramSet = false;

        if (stmt != null) {
            try {
                stmt.setString(paramIndex, paramValue);
                paramSet = true;
            } catch (SQLException sqle) {
                sqle.getMessage();
            }
        }
        return paramSet;
    }

    public boolean setStatementParameter(int paramIndex, int paramValue) {
        boolean paramSet = false;

        if (stmt != null) {
            try {
                stmt.setInt(paramIndex, paramValue);
                paramSet = true;
            } catch (SQLException sqle) {
                sqle.getMessage();
            }
        }
        return paramSet;
    }

    public int getUpdateCount() {
        return updateCount;
    }

    public ResultSet getResultSet() {
        return rs;
    }
}

package Database;

import java.sql.SQLException;
import java.util.ArrayList;

public class ConnectionManager {

    private static final ConnectionManager instance = new ConnectionManager();
    private final ArrayList<DatabaseConnection> available;
    private final ArrayList<DatabaseConnection> busy;

    private ConnectionManager() {

        available = new ArrayList();
        busy = new ArrayList();

        for (int i = 0; i < 5; i++) {
            try {
                available.add(new DatabaseConnection(this));
            } catch (SQLException sqle) {
                sqle.getMessage();
            }
        }
    }

    public static ConnectionManager getInstance() {
        return instance;
    }

    public DatabaseConnection getConnection() {
        DatabaseConnection connection = null;
        synchronized (this) {
            if (!available.isEmpty()) {
                connection = available.remove(0); <---This gets skipped over as available is never added to
                busy.add(connection);
            }
        }
        return connection;
    }

    public void releaseConnection(DatabaseConnection connection) {
        if (connection != null) {
            synchronized (this) {
                if (busy.remove(connection)) {
                    available.add(connection);
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

似乎错误在于您自定义构建的连接池。虽然自己创建一个很诱人,但它并不是很简单,因为当需要比预期更多的连接时,它很容易弄乱API,事务管理,池自动调整大小。我建议您使用其中一个已经存在的库,并完美地完成工作,例如C3PO。之后,您的ConnectionPool / CollectionManager单例可以像这样简单:

public class ConnectionPool {
    private static ComboPooledDataSource cpds;

    private static class ConnectionPoolHolder {
        private static final ConnectionPool INSTANCE = new ConnectionPool();
    }

    private ConnectionPool() {
        cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass(ServerConfig.JDBC_DRIVER_CLASS); //loads the jdbc driver
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        } 
        cpds.setJdbcUrl(ServerConfig.CONNECTION_STRING);
        cpds.setUser(ServerConfig.DB_USER);
        cpds.setPassword(ServerConfig.DB_PASS);

        // the settings below are optional -- c3p0 can work with defaults
        cpds.setMinPoolSize(ServerConfig.MIN_POOL_SIZE);
        cpds.setAcquireIncrement(5);
        cpds.setMaxPoolSize(ServerConfig.MAX_POOL_SIZE);
        cpds.setTestConnectionOnCheckin(true);
        cpds.setPreferredTestQuery("select 1");
        cpds.setTestConnectionOnCheckout(true);
        cpds.setIdleConnectionTestPeriod(9000);
    }

    public static ConnectionPool getInstance() {
        return ConnectionPoolHolder.INSTANCE;
    }

    public Connection getConnection() {
        try {
            return cpds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        } 
        return null;
    }
}
相关问题