Servlet - MySQL错误

时间:2014-04-24 12:10:10

标签: java mysql servlets

我尝试使用以下代码将数据输入MySQL数据库。任何帮助都将非常感激,因为我无法解决为什么会有异常。请求参数由HTML表单提供,并且根本不存在任何问题,数据通过就好了。这个问题似乎发生在servlet完成之后,可能在DAO或连接管理器中的某个地方。非常感谢!

相关Servlet代码:

            UserRegistrationBean user = new UserRegistrationBean();
            user.setUsername(request.getParameter("Username"));
            user.setPassword(request.getParameter("Password"));
            user.setEmail(request.getParameter("Email"));

            user = UserDAO.register(user);

            if (user.getExists() == true) {

                ErrorMessage = "The user name you entered has already been registered!";

                request.setAttribute("ErrorMessage", ErrorMessage);

                request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);

                return;

            }

UserDAO的:

public static UserRegistrationBean register(UserRegistrationBean bean) {

    Statement stmt = null;    

    String username = bean.getUsername();    
    String password = bean.getPassword();  
    String email = bean.getEmail();

    String searchQuery = "SELECT * FROM tblusers WHERE Username='"
                        + username
                        + "'";

    String insertQuery = "INSERT INTO tblUsers (Username, Password, Email) VALUES ('" 
                        + username + 
                        "', '" 
                        + password + 
                        "', '" 
                        + email +
                        "')";

    try {

        currentCon = ConnectionManager.getConnection();
        stmt = currentCon.createStatement();

        //check if user exists

        ResultSet searchRs = stmt.executeQuery(searchQuery);

        //User name is available
        if (searchRs.next() == false) {

            bean.setExists(false);

        } 

        //User name is not available
        else if (searchRs.next() == true) {

            bean.setExists(true);

        }

        if (bean.getExists() == true) {

            //Return error and prevent registration

            bean.setSuccess(false);

            return bean;

        }

        else {

            stmt.executeUpdate(insertQuery);

            bean.setSuccess(true);

        }

    }

    catch(Exception ex) {

        //exception available here

    }

    return bean;

}

的ConnectionManager:

public class ConnectionManager {

    static Connection connection;
    static String url;

    public static Connection getConnection() {

        try {

            String url = "jdbc:odbc:" + "localhost:3306"; 

            Class.forName("com.mysql.jdbc.Driver");

            try {

            connection = DriverManager
                      .getConnection("jdbc:mysql://localhost:3306/the_atrium_beauty?"
                          + "user=System&password=sYstem~9");

        }

            catch (SQLException ex) {

                //Stack trace available here
                //ex.printStackTrace();

            }

        }

        catch(ClassNotFoundException e) {

            //Exception check available here
            //System.out.println(e);

        }

        return connection;

    }
}

尝试Catch Block:

catch(Throwable exception) {

            String errorMessage = exception.getMessage();
            Throwable errorCause = exception.getCause();
            String errorLocation = this.getServletName();

            request.setAttribute("ErrorMessage", errorMessage);
            request.setAttribute("ErrorCause", errorCause);
            request.setAttribute("ErrorLocation", errorLocation);

            request.getRequestDispatcher("/WEB-INF/errorDisplay.jsp").forward(request, response);

        }

错误显示JSP:

<body>

    <% final String errorMessage = (String)request.getAttribute("ErrorMessage"); %>
    <% final Throwable errorCause = (Throwable)request.getAttribute("ErrorCause"); %>
    <% final String errorLocation = (String)request.getAttribute("ErrorLocation"); %>

    <h1>An Error Occurred...</h1>

    <p>

        <%= errorMessage %><br><br>

        <%= errorCause %><br><br>

        <%= errorLocation %>

    </p>

</body>

堆栈追踪:

java.lang.NullPointerException
    at com.atrium.userServlets.UserRegistrationServlet.doPost(UserRegistrationServlet.java:231)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

2 个答案:

答案 0 :(得分:1)

我认为你的问题在于此处(为了便于阅读而略微浓缩代码):

ResultSet searchRs = stmt.executeQuery(searchQuery);

//User name is available
if (searchRs.next() == false) {
    bean.setExists(false);
} 

//User name is not available
else if (searchRs.next() == true) {
    bean.setExists(true);
}

if (bean.getExists() == true) {
    //Return error and prevent registration
    bean.setSuccess(false);
    return bean;
}

next() ResultSet的内部光标移至下一行。这意味着后续对next()的调用不能保证返回相同的结果

所以这个:

if (searchRs.next() == false) {

以后几行可能不会返回相同的东西:

else if (searchRs.next() == true) {

这意味着通过此代码存在潜在的途径,其中 条件都不是真的。具体来说,如果next()的第一次调用返回true而第二次调用返回false,则两个分支都不会执行。

有很多方法可以解决这个问题。我个人会这样做:

// Check the true condition first, no need for == true
if (searchRs.next()) {
    // User already exists
    bean.setExists(true);
    bean.setSuccess(false);

    // Returning the bean object isn't strictly necessary because of side-effects
    return bean;
} else {
    // User doesn't already exist
    bean.setExists(false);
    stmt.executeUpdate(insertQuery);

    // You'll need to commit the transaction for it to work properly:
    currentCon.commit();
    bean.setSuccess(true);

    return bean;
}

基本上,由于此上下文中的boolean比较只能有两个结果,因此您可以使用if {} else {}代替if {} else if {}

注意:我假设getExists()的返回类型为Boolean而不是boolean(因为boolean不能{ {1}})。考虑到这一点,我认为由于上述问题,您没有初始化null后面的变量,所以它仍然设置为默认值,对象为getExists()

由于对null的更改为side effects,您实际上不需要从方法返回,对对象的更改也应该在方法外部可见。


对于你的异常处理,如果你没有报告它就不会吞下它,那将是非常有用的。据推测,调用方法需要知道一些不寻常的错误,所以不要抓住什么也不做,而是做这样的事情:

bean

其中try { // Your database access code here } catch (SQLException e) { // You don't want to persist any dud data, so rollback the connection currentCon.rollback(); // Propagates the exception upward to the calling method throw new RegistrationException("Error registering user", e); } 是您自己创建的自定义异常类(您应该至少定义一个以RegistrationExceptionString作为参数的构造函数。您还必须修改方法签名以声明异常:

Throwable

这会强制调用方法重新抛出(从而进一步传播)异常或处理它。

答案 1 :(得分:0)

您使用的是非常旧的type-1 sun.jdbc.odbc.JdbcOdbcDriver,这对所有数据库都很常见,并且它也存在许多问题。所以我的建议是使用特定于数据库的驱动程序并相应地更改连接URL。

对于Ex:

如果您使用的是mysql,请使用

// this will load the MySQL driver, each DB has its own driver
      Class.forName("com.mysql.jdbc.Driver");
      // setup the connection with the DB.
      connect = DriverManager
          .getConnection("jdbc:mysql://<ip>/<db name>?"
              + "user=<username>&password=<password>");