【问题标题】:Tomcat6 and MySQL issuesTomcat6 和 MySQL 问题
【发布时间】:2011-12-24 10:16:30
【问题描述】:

我有一个新安装的带有 Tomcat6 的 Ubuntu 11.10 服务器。我正在使用 Eclipse Indigo 制作一个从我的 MySQL 服务器中提取数据的 Java Servlet。我已将最新的 Connector/J (mysql-connector-java-5.1.18-bin.jar) 放在我的服务器 CATALINA_HOME/lib 目录中。在 Eclipse 中,我创建了一个动态 Web 项目,然后创建了一个 servlet。 servlet 的 Java 代码是:

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

/**
 * Servlet implementation class TestServlet
 */
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#HttpServlet()
 */
public TestServlet() {
    super();
    // TODO Auto-generated constructor stub
}

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    Context initCtx = null;
    try {
        initCtx = new InitialContext();
    } catch (NamingException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    Context envCtx = null;
    try {
        envCtx = (Context) initCtx.lookup("java:comp/env");
    } catch (NamingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    DataSource ds = null;
    try {
        ds = (DataSource) envCtx.lookup("jdbc/TestDB");
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    Connection conn = null;
    try {
        conn = ds.getConnection();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Statement stat = null;
    try {
        stat = conn.createStatement();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ResultSet rs = null;
    try {
        rs = stat.executeQuery("SELECT * FROM users");
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        while(rs.next()) {
            System.out.println("in");
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

我的 WEB-INF/web.xml 中有以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>TestServlet</display-name>
  <resource-ref>
    <description>TestDB</description>
    <res-ref-name>jdbc/TestDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>TestServlet</display-name>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
  </servlet-mapping>
</web-app>

我必须在 META-INF 中创建 context.xml,但这里是我的 META-INF/context.xml 的上下文

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="myuser" password="mypass" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/test1"/>
</Context>

我导出到战争,部署到我的 tomcat 服务器。当我浏览到 servlet 时,出现以下错误:

java.lang.NullPointerException
TestServlet.doGet(TestServlet.java:67)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

TestServlet.java 的第 67 行是 conn.createStatement();线。抱歉,我的代码很乱,我使用了单独的 try catch 块,因为当我执行一次大的 try catch 时没有收到此错误,尽管它仍然没有连接到 MySQL 数据库。我确定我在这里错过了一个相当简单的步骤,但我似乎无法在任何地方找到它,我对 Tomcat 和 Servlet 有点陌生。非常感谢。

【问题讨论】:

  • 我意识到上面发布的代码正在执行system.out.println("in")而不是printwriter,错误是一样的,我在提出这个问题时匆匆忙忙的那部分代码,应该是无关紧要的。
  • 检查以确保您的 context.xml 实际正在部署;如果您使用的是 WTP 插件,则需要启用模块上下文的发布。
  • 那么是否有来自 getConnection() 的堆栈跟踪?
  • 验证您是否也在服务器上使用正确的用户名和密码创建了数据库“test1”。这是您在资源的 url 中指向的数据库。
  • 也许我应该指定。我正在 Windows 机器上使用 Eclipse 进行开发。我正在将我的项目导出为 .war,其中确实包含 context.xml 文件,并且 tomcat 确实会分解该文件并据我所知适当地放置 context.xml 文件。 @DaveNewton,如果我没有通过“在服务器上运行”部署代码,是否仍然可以发布模块上下文?出于测试目的,我在我的 windows 机器上设置了一个 tomcat 服务器,将 context.xml 中的主机 url 更改为我的 mysql 服务器的 ip,通过“作为服务器运行”在本地部署,代码运行完美。

标签: java mysql eclipse tomcat servlets


【解决方案1】:

问题出在我的/etc/mysql/my.conf 上。我已将绑定地址设置为服务器的 IP 地址,这导致 Tomcat 无法连接。为什么Tomcat不能但PHP可以超出我的范围,但无论如何。我将绑定地址更改为 0.0.0.0,一切都很好。

【讨论】:

  • 在任何给定时间,都有多个接口处于活动状态。其中之一是“lo”; 127.0.0.1地址绑定的环回接口。另一个是“eth0”或“wlan0”(linux)或“本地局域网连接”或“无线网络连接”(windows)。当您为 MySQL 设置绑定地址时,实际上是在说“仅使用具有此地址的接口”。 0.0.0.0 地址表示绑定到“所有接口”。
  • 为什么在给定 localhost 的情况下 PHP 会成功连接到 mysql 服务器?
  • PHP MySQL 客户端很“聪明”。当您告诉它使用 localhost 时,它实际上连接到本地命名管道 (windows) 或 unix 域套接字 (linux)。看这里的第一个注释:php.net/manual/en/function.mysql-connect.php
【解决方案2】:

根据Tomcat 6 context docs

上下文元素可以明确定义:

  • 仅当 $CATALINA_BASE/conf/[enginename]/[hostname]/ 中不存在应用程序的上下文文件时,应用程序文件内 /META-INF/context.xml 的单个文件中。如果 Web 应用程序被打包为 WAR,那么 /META-INF/context.xml 将被复制到 $CATALINA_BASE/conf/[enginename]/[hostname]/ 并重命名以匹配应用程序的上下文路径。此文件一旦存在,如果将具有较新 /META-INF/context.xml 的新 WAR 放置在主机的 appBase 中,它将不会被替换。

尝试删除 Tomcat 的 conf 目录中的副本,然后查看您的 context.xml 文件是否被拾取。

【讨论】:

  • 我刚刚通过将context.xml中的localhost更改为服务器的实际IP地址取得了成功。我不知道为什么 localhost 和 127.0.0.1 对我不起作用,问题一定出在 MySQL 用户权限上。感谢您的帮助。
  • @tdramble 哦;嗯。诡异的。好的,我将删除此答案以避免将人们赶走。您应该将其添加为答案,然后接受它,以便其他人知道解决方案是什么!
  • 我刚刚提交了我的答案,我会在允许的情况下在 2 天内接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多