Eclipse-GWT-Java-MySQL-如何正确捕获异常
我终于完成了我的应用程序(Eclipse、GWT、Java、MySQL、Tomcat),它已经被上传到服务器上(我让其他人将应用程序上传到服务器上)。但是,服务器安装似乎有问题,我的代码没有返回任何错误 例如:创建新帐户时,会显示以下消息“您的帐户已创建。请与领导联系以将青年成员关联到该帐户”。但是数据库不会更新。似乎我没有正确捕获异常 我的代码是: 客户端呼叫:Eclipse-GWT-Java-MySQL-如何正确捕获异常,java,mysql,eclipse,tomcat,gwt,Java,Mysql,Eclipse,Tomcat,Gwt,我终于完成了我的应用程序(Eclipse、GWT、Java、MySQL、Tomcat),它已经被上传到服务器上(我让其他人将应用程序上传到服务器上)。但是,服务器安装似乎有问题,我的代码没有返回任何错误 例如:创建新帐户时,会显示以下消息“您的帐户已创建。请与领导联系以将青年成员关联到该帐户”。但是数据库不会更新。似乎我没有正确捕获异常 我的代码是: 客户端呼叫: AsyncCallback<User> callback = new CreationHandler<User&g
AsyncCallback<User> callback = new CreationHandler<User>();
rpc.createUser(textBoxAccount.getText(), textBoxPassword.getText(), null, null, null, callback);
客户端:
class CreationHandler<T> implements AsyncCallback<User> {
//Create the account.
public void onFailure(Throwable ex) {
Window.alert("RPC call failed - CreationHandler - Notify Administrator.");
}
public void onSuccess(User result) {
Window.alert("Your account has been created. Please contact a leader to associate youth members to it.");
}
}
这是带有建议错误处理的更新代码:
package org.AwardTracker.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.AwardTracker.client.BCrypt;
import org.AwardTracker.client.Account;
import org.AwardTracker.client.AccountAndCubs;
import org.AwardTracker.client.AccountCubAssociation;
import org.AwardTracker.client.AwardAward;
import org.AwardTracker.client.AwardDescription;
import org.AwardTracker.client.AwardStockDtls;
import org.AwardTracker.client.DBConnection;
import org.AwardTracker.client.SectionDetails;
import org.AwardTracker.client.Stock;
import org.AwardTracker.client.User;
import org.AwardTracker.client.ViewData;
import org.AwardTracker.client.YMATask;
import org.AwardTracker.client.YMAwards;
import org.AwardTracker.client.YMandAward;
import org.AwardTracker.client.YMAwardDetails;
import org.AwardTracker.client.YouthMember;
import org.AwardTracker.client.YouthMemberAwards;
import org.AwardTracker.client.YthMmbrSectDtls;
import org.AwardTracker.server.Base64Encode2;
public class MySQLConnection extends RemoteServiceServlet implements DBConnection {
//TODO
// •Use JNDI to bind the data source.
// •Close the connection as soon as its done in finally block.
// •Manage the connection in single class for whole application.
// •Initialise the data source at application start up single time.
// •Store the database configuration outside the JAVA code somewhere in properties file or web.xml.
// •Create an abstract class for AsyncCallback that will handle all the failures happened while performing any RPC calls.
// •Extend this abstract class for all RPC AsyncCallback but now you have to just provide implementation of onSuccess() only.
// •Don't handle any exception in service implementation just throw it to client or if handled then re-throw some meaning full exception back to client.
// •Add throws in all the methods for all the RemoteService interfaces whenever needed.
private static final long serialVersionUID = 1L;
private Connection conn = null;
private String url = "jdbc:mysql://localhost/awardtracker";
private String user = "awtrack";
private String pass = "************";
public MySQLConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pass);
} catch (Exception e) {
//NEVER catch exceptions like this
System.out.println("Error connecting to database - not good eh");
e.printStackTrace();
}
}
//Store and retrieve data used by Views within the application
//This allows us to securely pass parameters between Views.
private ViewData viewData = null;
public ViewData setViewData(String accountId, String accountLevel,
String ymId, String awId, String adGroup) {
viewData = new ViewData();
viewData.setaccountId(accountId);
viewData.setaccountLevel(accountLevel);
viewData.setymId(ymId);
viewData.setawId(awId);
viewData.setadGroup(adGroup);
return viewData;
}
public ViewData getViewData() {
return viewData;
}
public User authenticateUser(String accID, String userName, String pass, String level, String pack, Integer enabled, java.sql.Date archived) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
String stored_hash = null;
try {
ps = conn.prepareStatement(
"SELECT * " +
"FROM at_accounts " +
"WHERE acc_email_address = ?");
ps.setString(1, userName);
result = ps.executeQuery();
while (result.next()) {
user = new User(result.getString(1), result.getString(2), result.getString(3), result.getString(4), result.getString(5), result.getInt(6), result.getDate(7));
stored_hash = result.getString(3);
}
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for authenticateUser.");
e2.printStackTrace();
}
System.out.println("SQLException in authenticateUser.");
e.printStackTrace();
}
if (stored_hash != null) {
if (BCrypt.checkpw(pass, stored_hash)) {
} else {
user = null;
}
}else{
user = null;
}
return user;
}
//Disable or enable Account
public User disableUser(String user, Integer enabled) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"UPDATE at_accounts " +
"SET acc_enabled=? " +
"WHERE acc_email_address=?");
ps.setInt(1, enabled);
ps.setString(2, user);
ps.executeUpdate();
conn.commit();
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for createUser.");
e2.printStackTrace();
}
System.out.println("SQLException in createUser.");
e.printStackTrace();
}
return null;
}
public User duplicateUser(String userName, String pass, String level, String pack, java.sql.Date archived) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"SELECT * " +
"FROM at_accounts " +
"WHERE acc_email_address = ?");
ps.setString(1, userName);
result = ps.executeQuery();
while (result.next()) {
user = new User(null, result.getString(2), null, null, null, null, null);
}
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for duplicateUser.");
e2.printStackTrace();
}
System.out.println("SQLException in duplicateUser.");
e.printStackTrace();
}
return user;
}
public User createUser(String userName, String pass, String level, String pack, java.sql.Date archived) {
PreparedStatement ps = null;
String pw_hash = BCrypt.hashpw(pass, BCrypt.gensalt());
try {
ps = conn.prepareStatement(
"INSERT INTO at_accounts (acc_email_address, acc_password, acc_enabled) " +
"VALUES (?, ?, ?)");
ps.setString(1, userName);
ps.setString(2, pw_hash);
ps.setString(3, "1");
ps.executeUpdate();
conn.commit();
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for createUser.");
e2.printStackTrace();
}
System.out.println("SQLException in createUser.");
e.printStackTrace();
}
return null;
}
您没有将事务提交到数据库。为了便于
ps.executeUpdate()所做的更改
要成为永久,您需要在更新后调用
类似地,在catch
块中,应该调用,以避免将无用数据插入数据库
我看不到conn
的声明,所以我假设它是createUser
所属的任何类的成员变量。您可能需要考虑将<代码>连接< /代码>作为方法中的本地,这样您就不会忘记一旦它不再需要就关闭它(应该是您曾经提交的)。
最后,如果您使用java 7 +,您可以利用它来处理您的<代码> PraveRealdS> <代码> > <代码> RealtSt/<代码>和<代码>连接< /C> >(虽然您似乎没有使用<代码> ReultStuts任何东西,所以请考虑从方法中删除它)。
这里有两个例子说明了我的意思(一个用于Java 6及以下版本,另一个用于Java 7及更高版本,使用
try with resources
:
爪哇6-
爪哇7+ 在这两个示例中,我都删除了未使用的方法参数(如果您不使用它们,为什么要将它们放在那里?),并将返回类型更改为
void
。我这样做是因为在当前形式下,您的方法将始终返回null
(将User
对象初始化为null
,然后对其不做任何更改,然后在末尾返回它)
您还应该考虑使用日志框架来处理异常日志,而不是依赖于代码> PrtStActhTrace]()/代码>。请参阅关于为什么不推荐<代码> PrtStActhTrace]()/代码>的更多信息。
- 使用JNDI绑定数据源
- 在
块中完成连接后立即关闭连接finally
- 在单个类中管理整个应用程序的连接
- 在应用程序启动时一次性初始化数据源
- 将数据库配置存储在JAVA代码之外的属性文件或web.xml中的某个位置
GWT-如何正确捕获异常
- 为
创建一个抽象类,该类将处理执行任何RPC调用时发生的所有故障AsyncCallback
- 为所有RPC
扩展这个抽象类,但是现在您只需要提供AsyncCallback
onSuccess()的实现
- 不要在服务植入中处理任何异常,只需将其抛出到客户端,或者如果已处理,则重新将一些有意义的完全异常抛出回客户端
- 在所有
接口的所有方法中添加远程服务
抛出
// single class to handle all the AsyncCallback failure
public abstract class MyAsyncCallback<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable caught) {
// all the failure are catched here
// prompt user if needed
// on failure message goes to here
// send the failure message back to server for logging
}
}
// do it for all the RPC AsyncCallback
public class CreationHandler<T> extends MyAsyncCallback<T> {
//Create the account.
public void onSuccess(T result) {
// on success message goes to here
}
}
// use in this way
AsyncCallback<User> callback = new CreationHandler<User>();
//处理所有异步回调失败的单个类
公共抽象类MyAsyncCallback实现AsyncCallback{
@凌驾
失败时的公共无效(可丢弃){
//所有的失败都记录在这里
//如果需要,提示用户
//失败消息转到此处
//将失败消息发送回服务器进行日志记录
}
}
//对所有RPC异步回调执行此操作
公共类CreationHandler扩展了MyAsyncCallback{
//创建帐户。
成功时公开作废(T结果){
//关于成功的信息转到这里
}
}
//这样使用
AsyncCallback=new CreationHandler();
three是否记录了任何异常?您好,Braj,我已经向设置服务器的人员提出了这个问题,但尚未得到回复。我必须耐心等待,因为他在自己的时间内进行设置,这是对我们团队的一种帮助。您好,Glyn。我将一步一步地进行。我现在已将更改与新的错误处理一起发布。请检查下一步,我将把错误处理移到一个抽象类(需要向它传递参数,以便知道哪个类返回错误),查看log4j并将DB登录名移动到XML。你好,Glyn。你好,JoinK,谢谢。我已经在上面输入了修改后的代码。这是正确的/你的意思吗?你好,Glyn。你好,JonK,我已经用你的错误处理更新了上面的代码。如果这是正确的,那么我将按照Braj的建议将所有错误处理移到一个类中。然后我将查看使用log4j并将连接移动到XML.alives、Glyn.Hi JonK,当测试此项时,用户成功创建,但是生成了一个错误,当自动提交为yes时您无法提交。因此,我删除了“conn.commit();”行。这是正确的做法还是应该关闭自动提交(这是什么地方)你好,格林。格林-你可能应该关闭自动提交是的。演示如何关闭。好的,谢谢你的帮助。我认为我正在做的其他事情是正确的。你好,格林
package org.AwardTracker.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.AwardTracker.client.BCrypt;
import org.AwardTracker.client.Account;
import org.AwardTracker.client.AccountAndCubs;
import org.AwardTracker.client.AccountCubAssociation;
import org.AwardTracker.client.AwardAward;
import org.AwardTracker.client.AwardDescription;
import org.AwardTracker.client.AwardStockDtls;
import org.AwardTracker.client.DBConnection;
import org.AwardTracker.client.SectionDetails;
import org.AwardTracker.client.Stock;
import org.AwardTracker.client.User;
import org.AwardTracker.client.ViewData;
import org.AwardTracker.client.YMATask;
import org.AwardTracker.client.YMAwards;
import org.AwardTracker.client.YMandAward;
import org.AwardTracker.client.YMAwardDetails;
import org.AwardTracker.client.YouthMember;
import org.AwardTracker.client.YouthMemberAwards;
import org.AwardTracker.client.YthMmbrSectDtls;
import org.AwardTracker.server.Base64Encode2;
public class MySQLConnection extends RemoteServiceServlet implements DBConnection {
//TODO
// •Use JNDI to bind the data source.
// •Close the connection as soon as its done in finally block.
// •Manage the connection in single class for whole application.
// •Initialise the data source at application start up single time.
// •Store the database configuration outside the JAVA code somewhere in properties file or web.xml.
// •Create an abstract class for AsyncCallback that will handle all the failures happened while performing any RPC calls.
// •Extend this abstract class for all RPC AsyncCallback but now you have to just provide implementation of onSuccess() only.
// •Don't handle any exception in service implementation just throw it to client or if handled then re-throw some meaning full exception back to client.
// •Add throws in all the methods for all the RemoteService interfaces whenever needed.
private static final long serialVersionUID = 1L;
private Connection conn = null;
private String url = "jdbc:mysql://localhost/awardtracker";
private String user = "awtrack";
private String pass = "************";
public MySQLConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pass);
} catch (Exception e) {
//NEVER catch exceptions like this
System.out.println("Error connecting to database - not good eh");
e.printStackTrace();
}
}
//Store and retrieve data used by Views within the application
//This allows us to securely pass parameters between Views.
private ViewData viewData = null;
public ViewData setViewData(String accountId, String accountLevel,
String ymId, String awId, String adGroup) {
viewData = new ViewData();
viewData.setaccountId(accountId);
viewData.setaccountLevel(accountLevel);
viewData.setymId(ymId);
viewData.setawId(awId);
viewData.setadGroup(adGroup);
return viewData;
}
public ViewData getViewData() {
return viewData;
}
public User authenticateUser(String accID, String userName, String pass, String level, String pack, Integer enabled, java.sql.Date archived) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
String stored_hash = null;
try {
ps = conn.prepareStatement(
"SELECT * " +
"FROM at_accounts " +
"WHERE acc_email_address = ?");
ps.setString(1, userName);
result = ps.executeQuery();
while (result.next()) {
user = new User(result.getString(1), result.getString(2), result.getString(3), result.getString(4), result.getString(5), result.getInt(6), result.getDate(7));
stored_hash = result.getString(3);
}
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for authenticateUser.");
e2.printStackTrace();
}
System.out.println("SQLException in authenticateUser.");
e.printStackTrace();
}
if (stored_hash != null) {
if (BCrypt.checkpw(pass, stored_hash)) {
} else {
user = null;
}
}else{
user = null;
}
return user;
}
//Disable or enable Account
public User disableUser(String user, Integer enabled) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"UPDATE at_accounts " +
"SET acc_enabled=? " +
"WHERE acc_email_address=?");
ps.setInt(1, enabled);
ps.setString(2, user);
ps.executeUpdate();
conn.commit();
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for createUser.");
e2.printStackTrace();
}
System.out.println("SQLException in createUser.");
e.printStackTrace();
}
return null;
}
public User duplicateUser(String userName, String pass, String level, String pack, java.sql.Date archived) {
User user = null; // necessary unless you do something in the exception handler
ResultSet result = null;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(
"SELECT * " +
"FROM at_accounts " +
"WHERE acc_email_address = ?");
ps.setString(1, userName);
result = ps.executeQuery();
while (result.next()) {
user = new User(null, result.getString(2), null, null, null, null, null);
}
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for duplicateUser.");
e2.printStackTrace();
}
System.out.println("SQLException in duplicateUser.");
e.printStackTrace();
}
return user;
}
public User createUser(String userName, String pass, String level, String pack, java.sql.Date archived) {
PreparedStatement ps = null;
String pw_hash = BCrypt.hashpw(pass, BCrypt.gensalt());
try {
ps = conn.prepareStatement(
"INSERT INTO at_accounts (acc_email_address, acc_password, acc_enabled) " +
"VALUES (?, ?, ?)");
ps.setString(1, userName);
ps.setString(2, pw_hash);
ps.setString(3, "1");
ps.executeUpdate();
conn.commit();
}
catch (SQLException e) {
try {
conn.rollback();
}
catch (SQLException e2) {
System.out.println("Error rolling back transaction for createUser.");
e2.printStackTrace();
}
System.out.println("SQLException in createUser.");
e.printStackTrace();
}
return null;
}
public void createUser(String userName, String pass) {
PreparedStatement ps = null;
Connection conn = null;
String pw_hash = BCrypt.hashpw(pass, BCrypt.gensalt());
try {
// Acquire a Connection here rather than using a member variable
// NOTE: See Braj's answer for a better way of doing this
// using his ConnectionUtil class.
conn = DriverManager.getConnection(
"jdbc:mysql://localhost/awardtracker", "awtrack",
"**************");
ps = conn.prepareStatement(
"INSERT INTO at_accounts (acc_email_address, acc_password,"
+ " acc_enabled) "
+ "VALUES (?, ?, ?)");
ps.setString(1, userName);
ps.setString(2, pw_hash);
ps.setString(3, "1");
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e2) {
System.out.println("Error rolling back transaction.");
e2.printStackTrace();
}
System.out.println("SQLException createUser 1.");
e.printStackTrace();
} finally {
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
System.out.println("SQLException createUser 3.");
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("Error closing Connection.");
e.printStackTrace();
}
}
}
}
private static final String INSERT_STATEMENT =
"INSERT INTO at_accounts (acc_email_address, acc_password, "
+ "acc_enabled) VALUES (?, ?, ?)";
public void createUser(String userName, String pass) {
String pw_hash = BCrypt.hashpw(pass, BCrypt.gensalt());
// NOTE: See Braj's answer for a better way of getting Connections.
try (Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost/awardtracker", "awtrack",
"**************");
PreparedStatement ps = conn.prepareStatement(INSERT_STATEMENT);) {
try {
ps.setString(1, userName);
ps.setString(2, pw_hash);
ps.setString(3, "1");
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e2) {
System.out.println("Error rolling back transaction.");
e2.printStackTrace();
}
System.out.println("SQLException createUser 1.");
e.printStackTrace();
}
} catch (SQLException e) {
System.out.println("Error connecting to DB.");
e.printStackTrace();
}
}
// single class to handle all the AsyncCallback failure
public abstract class MyAsyncCallback<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable caught) {
// all the failure are catched here
// prompt user if needed
// on failure message goes to here
// send the failure message back to server for logging
}
}
// do it for all the RPC AsyncCallback
public class CreationHandler<T> extends MyAsyncCallback<T> {
//Create the account.
public void onSuccess(T result) {
// on success message goes to here
}
}
// use in this way
AsyncCallback<User> callback = new CreationHandler<User>();