【问题标题】:Tomcat6 Java Servlet serving mysql commands?Tomcat6 Java Servlet 服务于 mysql 命令?
【发布时间】:2012-01-31 15:22:50
【问题描述】:

我玩 Java 和 mysql 已经有一段时间了。但我第一次将它与 Tomcat 一起使用。命令是否相同,因为据我所知,它的命令不起作用。

到目前为止,我已经将它连接起来,我知道这是因为它使我的 mysql 连接最大化,所以我必须关闭 Tomcat。

这是我的连接代码和drop table实验:

public void connect() throws SQLException, NamingException{

    Context initCtx = new InitialContext();
    Context envCtx = (Context) initCtx.lookup("java:comp/env");
    DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
    con = ds.getConnection();

    dropTables("DROP TABLE test;");

    con.close();
}


public void dropTables(String query) throws SQLException{

    Statement st = (Statement)con.createStatement();        
    st.executeUpdate(query);

}

一旦我取消注释 dropTables,我就会得到 HTTP 500。

有什么想法吗?

TIA

这是错误:

SEVERE: Servlet.service() for servlet myServlet threw exception
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingStatement cannot be cast to com.mysql.jdbc.Statement
    at myServlet.dropTables(myServlet.java:90)
    at myServlet.connect(myServlet.java:82)
    at myServlet.doPost(myServlet.java:50)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:431)
    at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:384)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665)
    at java.lang.Thread.run(Thread.java:662)

【问题讨论】:

  • HTTP 500 是内部服务器错误,这可能意味着存在未处理的异常。你有堆栈跟踪吗?
  • 它是否向您显示任何异常或其他更详细的错误信息? Tomcat 服务器日志说明了什么?
  • 我猜 NullPointerException 或 SQLException 正在关闭您的容器。检查您的 catalina.out 以获取证据。
  • 您的查询抛出异常,您应该在更高级别捕获它并记录它。然后在此处发布错误,以便我们可以实际帮助您。
  • 贴出stacktrace,或许能提供一些线索。

标签: java mysql apache tomcat


【解决方案1】:
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingStatement 
cannot be cast to com.mysql.jdbc.Statement

您在dropTables(...) 方法中使用了com.mysql.jdbc.Statement,但是在con.createStatement() 上这样做,不能单独为MySQL 安全地强制转换。想象一下,如果您(有一天)更改命名查找以返回 Oracle 数据库连接。或许现在你可以明白为什么演员表本质上是不安全的了。

使用通用的java.sql.Statement。仔细检查您的导入并摆脱 MySQL 导入。当您需要支持的“下一个”数据库出现时,这样做会使您的代码更容易处理。

【讨论】:

  • 泛型 java sql 语句是什么意思?我的导入看起来像: import java.io.IOException;导入 java.io.OutputStreamWriter;导入 java.net.URLDecoder;导入java.sql.Connection;导入java.sql.ResultSet;导入java.sql.SQLException;导入 javax.sql.DataSource;导入 javax.servlet.ServletInputStream;导入 javax.servlet.http.HttpServlet;导入 javax.servlet.http.HttpServletRequest;导入 javax.servlet.http.HttpServletResponse;导入 com.mysql.jdbc.Statement;导入 javax.naming.Context;导入 javax.naming.InitialContext;导入 javax.naming.NamingException;
  • 所以只需 import java.sql.Statement 并删除 import com.mysql.jdbc.Statement
【解决方案2】:

您的代码在dropTables 方法中引发了异常。例外是停止执行 connect 方法并阻止您关闭连接。这可以防止连接返回到连接池,从而导致连接用完。它也导致了 500 错误。

您可以通过将dropTables 更改为此来修复您的ClassCastException

public void dropTables(String query) throws SQLException{
    con.createStatement().executeUpdate(query);
}

另外,我建议您将 JDBC 代码包含在 try-catch-finally 块中,如下所示:

try{
    dropTables("DROP TABLE test;");
} catch (Exception e){
    e.printStackTrace();
} finally {
    con.close();
}

【讨论】:

    【解决方案3】:

    当使用连接池(包括 DBCP)时,JDBC 类将封装原生 JDBC 驱动程序类,因此您不能将 Connection、PreparedStatement、Statement 和 ... 强制转换为驱动程序的特定类,为什么要这样做?

    某些实现具有访问本机类的方法(例如本机 Oracle 连接),但您的代码将依赖于您使用的连接池。

    只要使用标准的 JDBC 接口就可以了。

    【讨论】:

      猜你喜欢
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 2011-11-11
      • 2013-09-02
      • 1970-01-01
      • 2011-05-16
      相关资源
      最近更新 更多