gpt4 book ai didi

java - Servlet - MySQL 错误

转载 作者:行者123 更新时间:2023-11-29 03:01:17 25 4
gpt4 key购买 nike

我正在尝试使用以下代码将数据输入到 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;

}

用户DAO:

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;

}

连接管理器:

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;

}
}

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

最佳答案

我认为您的问题出在这里(为了便于阅读,稍微压缩了代码):

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 不能为 null)。考虑到这一点,我相信你没有初始化位于 getExists() 后面的变量,因为上面的问题,所以它仍然设置为默认值,对于对象来说是

因为bean 的变化是side effects ,您实际上不需要从方法中返回它,对对象的更改也应该在方法之外可见。


对于您的异常处理,如果您没有在不报告的情况下吞下它,它将(非常)有用。大概调用方法需要知道有什么不寻常的地方出错了,所以与其捕获然后什么也不做,不如做这样的事情:

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

其中 RegistrationException 是您自己创建的自定义异常类(您应该至少定义一个采用 StringThrowable 的构造函数作为参数)。您还必须修改方法签名以声明异常:

public static UserRegistrationBean register(UserRegistrationBean bean)
throws RegistrationException {

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

关于java - Servlet - MySQL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23268501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com