Java Servlet doGet调用数据库返回空对象问题求助
问题排查:Servlet调用DAO获取对象为空,但Main方法正常
我通过一个方法从数据库获取数据并返回封装该数据的Conta对象。Main方法调用此方法时,对象能正常填充数据;但在Java Servlet的doGet方法中调用该方法时,返回的对象为空,请求帮忙排查问题。
打印结果说明
- doGet方法中:返回的Conta对象为空,属性值未被正确填充
- main方法中:Conta对象数据正常填充,能输出正确的数值
doGet方法代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // TODO Auto-generated method stub Conta conta = ContaDAO.GetConta(2); double entrada = conta.getEntrada(); request.setAttribute("entrada", entrada); request.getRequestDispatcher("dashboard.jsp").forward(request, response); }
main方法代码
public static void main(String[] Args) { Conta conta = new Conta(); conta = ContaDAO.GetConta(2); double entrada = conta.getEntrada(); System.out.println(conta.getEntrada()); System.out.println(entrada); }
Conta类模型
public class Conta{ // 属性 protected int id; protected String nomeDaConta; protected double saldo; protected double gasto; protected double entrada; /*protected ArrayList<String> categoriaDeGasto = new ArrayList<String>(); protected ArrayList<String> categoriaDeEntrada = new ArrayList<String>();*/ public Conta() { super(); } // 注:需确保存在各属性的getter/setter方法,否则无法完成属性赋值 }
ContaDAO方法代码
public class ContaDAO { public ContaDAO() { super(); } public static Conta GetConta(int id){ PreparedStatement ps = null; ResultSet rs = null; Conta conta = new Conta(); Connection conexao; try { Class.forName("oracle.jdbc.driver.OracleDriver"); // 加载Oracle驱动后,获取数据库连接 conexao = DriverManager.getConnection( "jdbc:oracle:thin:@oracle.fiap.com.br:1521:ORCL", "RM552501", "270697"); String sqlGetConta = "SELECT DISTINCT CD_CONTA, NR_TOTAL_ENTRADA, NR_TOTAL_SAIDA FROM T_FINEASY_CONTA WHERE CD_CONTA = ? ORDER BY CD_CONTA"; ps = conexao.prepareStatement(sqlGetConta); ps.setInt(1, id); rs = ps.executeQuery(); while(rs.next()) { conta.setId(rs.getInt("CD_CONTA")); conta.setEntrada(rs.getInt("NR_TOTAL_ENTRADA")); conta.setGasto(rs.getInt("NR_TOTAL_SAIDA")); } DBConnection.closeconexao(conexao); DBConnection.closeconexaoPS(ps); DBConnection.closeconexaoRS(rs); }catch(ClassNotFoundException e){ e.printStackTrace(); }catch(SQLException e) { e.printStackTrace(); } return conta; } }
排查方向
JDBC驱动与类路径问题
- 检查Servlet容器(如Tomcat)的
WEB-INF/lib目录下是否存在Oracle JDBC驱动jar包。Main方法运行时驱动在本地classpath中,但Servlet容器的类路径独立,若缺失驱动会导致数据库连接失败。
- 检查Servlet容器(如Tomcat)的
网络与数据库权限问题
- 确认Servlet运行环境的网络能访问
oracle.fiap.com.br:1521,部分服务器存在防火墙限制,可能无法连接数据库。 - 检查数据库账号
RM552501是否允许Servlet所在IP地址访问,部分数据库会设置IP白名单限制。
- 确认Servlet运行环境的网络能访问
异常日志排查
- 查看Servlet容器的日志文件(如Tomcat的
logs/catalina.out),获取ClassNotFoundException或SQLException的具体错误信息,当前代码仅打印栈轨迹但未输出到容器日志,可能遗漏关键错误。 - 在
doGet方法中添加日志打印,输出conta对象的属性值,以及DAO方法中的异常详情。
- 查看Servlet容器的日志文件(如Tomcat的
资源关闭顺序问题
- DAO中资源关闭顺序错误:应先关闭ResultSet,再关闭PreparedStatement,最后关闭Connection。当前先关Connection会导致后续PS和RS关闭失败,可能引发资源泄漏或连接异常。调整顺序为:
DBConnection.closeconexaoRS(rs); DBConnection.closeconexaoPS(ps); DBConnection.closeconexao(conexao);
- DAO中资源关闭顺序错误:应先关闭ResultSet,再关闭PreparedStatement,最后关闭Connection。当前先关Connection会导致后续PS和RS关闭失败,可能引发资源泄漏或连接异常。调整顺序为:
数据类型匹配问题
- Conta类中
entrada和gasto是double类型,但DAO中用rs.getInt()获取数据,若数据库字段为NUMBER类型,建议改用rs.getDouble()避免类型转换错误或数据丢失。
- Conta类中
内容的提问来源于stack exchange,提问作者Drogo
相关产品推荐
相关产品推荐

