编辑:此问题已通过检查 Google 开发者控制台上的日志文件得到解决。该错误不是在连接数据库时出现的,而是因为我使用 JDK 1.8 而不是 1.7 进行编译。事实证明,即使我告诉 Eclipse 在项目中使用 JDK 1.7,它仍然使用 1.8,因为我的 Eclipse 配置文件中有以下行:
-vm
C:\Program Files\Java\jdk1.8.0_20\bin
当我将其更改为:
-vm
C:\Program Files\Java\jdk1.7.0_71\bin
一切都很完美。
原始问题:
我正在尝试从我授权的 Google App Engine 应用程序连接到 Google Cloud SQL 实例。我首先按照 https://cloud.google.com/appengine/docs/java/cloud-sql/#Java_Build_a_starter_application_and_database 上的指示进行操作。并稍微修改它们以与我的 Cloud SQL 实例配合使用(我没有实现留言簿数据库,我使用了我自己的数据库,它也只有一个包含三列的表)。我使用 MySQL Workbench 创建了 Cloud SQL 实例。
当我本地调试我的应用程序(在 localhost:8888 运行它)时,它与我的本地 MySQL 实例和 Google Cloud SQL 实例完美配合。但是,当我尝试将我的应用程序部署到 Google App Engine,它只是返回 500 服务器错误,我不知道出了什么问题(我对网络编程非常陌生)。我一直在整个网络上搜索此问题的解决方案,但尚未找到可以解决问题的方法。
这是我的 servlet 代码:
package com.rmpm;
import java.io.*;
import java.sql.*;
import javax.servlet.http.*;
import com.google.appengine.api.utils.SystemProperty;
@SuppressWarnings("serial")
public class Synaptic_rmpmServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String url = null;
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
try {
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test"; // Doesn't work
} else {
// Local MySQL instance to use during development.
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://173.###.##.###:3306/test"; // Connects to Google Cloud SQL instance when root password is provided
//url = "jdbc:mysql://127.0.0.1:3306/test"; // Connects to local MySQL instance
}
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
Connection conn = DriverManager.getConnection(url, "root", "");
try {
String pid = req.getParameter("projID");
String own = req.getParameter("owner");
String dur = req.getParameter("duration");
if (pid == "" || own == "" || dur == "") {
out.println(
"<html><head></head><body>You are missing either a projectID, owner name, or duration! Try again! " +
"Redirecting in 3 seconds...</body></html>");
}
else {
int duration = Integer.parseInt(dur);
String statement = "INSERT INTO project VALUES(?, ?, ?)";
PreparedStatement stmt = conn.prepareStatement(statement);
stmt.setString(1, pid);
stmt.setString(2, own);
stmt.setInt(3, duration);
int success = 2;
success = stmt.executeUpdate();
if (success == 1) {
out.println(
"<html><head></head><body>Success! Redirecting in 3 seconds...</body></html>");
} else if (success == 0) {
out.println(
"<html><head></head><body>Failure! Please try again! " +
"Redirecting in 3 seconds...</body></html>");
}
}
} finally {
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
resp.setHeader("Refresh", "3; url=/databaseIO.jsp");
}
}
我的databaseIO.jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="java.sql.*" %>
<%@ page import="com.google.appengine.api.utils.SystemProperty" %>
<html>
<body>
<%
String url = null;
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<my-project-id>:<my-instance-id>/test"; // Doesn't work
} else {
// Local MySQL instance to use during development.
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://173.###.##.###:3306/test"; // Connects to Google Cloud SQL instance when root password is provided
//url = "jdbc:mysql://127.0.0.1:3306/test"; // Connects to local MySQL instance
}
Connection conn = DriverManager.getConnection(url, "root", "");
ResultSet rs = conn.createStatement().executeQuery(
"SELECT * FROM project");
%>
<table style="border: 1px solid black">
<tbody>
<tr>
<th width="40%" style="background-color: #CCFFCC; margin: 5px">projectID</th>
<th style="background-color: #CCFFCC; margin: 5px">owner</th>
<th style="background-color: #CCFFCC; margin: 5px">duration</th>
</tr>
<%
while (rs.next()) {
String aPID = rs.getString(1);
String anOwner = rs.getString(2);
int aDur = rs.getInt(3);
%>
<tr>
<td><%= aPID %></td>
<td><%= anOwner %></td>
<td><%= aDur %></td>
</tr>
<%
}
conn.close();
%>
</tbody>
</table>
<br />
No more projects!
<p><strong>Add a project:</strong></p>
<form action="/sign" method="post">
<div>Project ID: <input type="text" name="projID"></input></div>
<br />
<div>Owner: <input type="text" name="owner"></input></div>
<br />
<div>Duration: <input type="text" name="duration"></input></div>
<br />
<div><input type="submit" value="Insert Project"></input></div>
</form>
</body>
</html>
根据我在网上阅读的内容,我认为在以根用户身份从我的授权 Google App Engine 应用程序连接到我的 Google Cloud SQL 实例时,我不需要密码。当我在 Debug模式下本地连接到 Google Cloud SQL 实例时,我确实提供了在 Google Developers Console 中设置的 root 密码,并且它运行良好。
我做了什么:
- 我已使用链接到我的 Google App Engine 应用程序的 Google 帐户登录 Eclipse。
- 我已经添加了
<use-google-connector-j>true</use-google-connector-j>
appengine-web.xml 文件中的行。 - 我已将 mysql-connector-java-5.1.33-bin.jar 复制到项目的 war/WEB-INF/lib 文件夹以及位于 D:\Program_Files\Eclipse\plugins\com.google 的 GAE SDK 目录.appengine.eclipse.sdkbundle_1.9.13\appengine-java-sdk-1.9.13\lib\impl(在线阅读类似问题说要这样做)。
- 我已授权我的 Google App Engine 应用连接到我的 Google Cloud SQL 实例。
- 我已授权我的本地网络连接到我的 Google Cloud SQL 实例。
- 我 100% 确定
<my-project-id>
和<my-instance-id>
JDBC url 中的字段正确。 - 我尝试在 JDBC 网址中使用 Google Cloud SQL 实例的 IP 地址,而不是项目 ID 和实例 ID。
我正在使用什么:
- Eclipse SE Luna (4.4.1) 以及 Google Plugin for Eclipse (4.4) 和 Google App Engine Java SDK (1.9.13)。我使用该插件从 Eclipse 直接部署到 Google App Engine。
- JDK 1.7
- Windows 8.1 64 位
如果您需要任何其他信息,请在此处发布,我会定期查看。
最佳答案
本地 mysql 将在您的代码上工作,我遇到了同样的问题,但是当我将 .GoogleDriver 更改为 .Driver 时,它开始工作
关于java - 在 Eclipse 中开发时无法从 Google App Engine 连接到 Google Cloud SQL 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26733307/