问题
I'm trying to connect to PostgreSQL server from java app engine. On my local machine code works perfectly, but when I deploy code to appengine, I get this exception:
Uncaught exception from servlet
java.lang.NullPointerException
at com.google.appengine.runtime.Request.process-3a02a4d7b73299fa(Request.java)
at java.util.Hashtable.put(Hashtable.java:432)
at java.util.Properties.setProperty(Properties.java:161)
at org.postgresql.Driver.loadDefaultProperties(Driver.java:121)
at org.postgresql.Driver.access$000(Driver.java:46)
at org.postgresql.Driver$1.run(Driver.java:88)
at java.security.AccessController.doPrivileged(AccessController.java:63)
at org.postgresql.Driver.getDefaultProperties(Driver.java:85)
at org.postgresql.Driver.connect(Driver.java:231)
at java.sql.DriverManager.getConnection(DriverManager.java:579)
at java.sql.DriverManager.getConnection(DriverManager.java:221)
at guestbook.PostgreServlet.doGet(PostgreServlet.java:49)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.tools.appstats.AppstatsFilter.doFilter(AppstatsFilter.java:141)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
at java.lang.Thread.run(Thread.java:722)
I am using postgresql-9.2-1003.jdbc4.jar and I have this jdbc as library and also inside my "war/WEB-INF/lib" folder. My java code is here:
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PostgreServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
Connection conn = null;
String result = "";
try {
conn = DriverManager.getConnection("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/xxxxx", "xxx", "xxxx");
if(conn == null){
pw.println("Connection null");
return;
}
ResultSet rs = conn.createStatement().executeQuery(
"SELECT * FROM pg_catalog.pg_tables");
while (rs.next()) {
result += rs.getString("tablename") + "<br>";
}
pw.println(result);
} catch (SQLException e) {
e.printStackTrace();
}
finally {
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
回答1:
Google don't allow jdbc out, only http out.
Look at Google Secure Data Connector (which is deprecated, but works until 2015).
Connections out from the Google App Engine are only HTTP based!
Google Cloud SQL
There is some functionality in Google Cloud SQL that you might wanna look at: https://developers.google.com/cloud-sql/
JDBC over HTTP
There are solutions to reach databases over http (e.g. http://vjdbc.sourceforge.net/ http://sourceforge.net/projects/sqlgateway/ etc)
The URLFetch API
App Engine applications can communicate with other applications or access other resources on the web by fetching URLs. An app can use the URL Fetch service to issue HTTP and HTTPS requests and receive responses. The URL Fetch service uses Google's network infrastructure for efficiency and scaling purposes. https://developers.google.com/appengine/docs/python/urlfetch/
Socket API
App Engine supports regular outbound Java sockets such as java.net.Socket and java.net.DatagramSocket. There is currently no support for sockets via java.nio.SocketChannel or other java.nio classes. Sockets are only available for paid apps! (another way to use outbounds, mentioned by Peter Knego) https://developers.google.com/appengine/docs/java/sockets/
But I would not recommend (accessing external databases easily over internet, with public IPs) , this solution are no-no for me, it is a high security issue - my opinion!
回答2:
Connecting to PostgreSQL from GAE Can be done!
You have to use this jdbc -
postgresql-8.3-607.jdbc2ee.jar
and you must have Sockets enabled
But still, thank you all for your suggestions and answers
回答3:
You forgot to load the driverclass (org.postgresql.Driver). Please add the driver jar into your application lib folder.
try {
Class.forName("org.postgresql.Driver"); //You forgot to load the driver
conn = DriverManager.getConnection("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/xxxxx", "xxx", "xxxx");
if(conn == null){
pw.println("Connection null");
return;
}
ResultSet rs = conn.createStatement().executeQuery(
"SELECT * FROM pg_catalog.pg_tables");
while (rs.next()) {
result += rs.getString("tablename") + "<br>";
}
pw.println(result);
} catch (SQLException e) {
e.printStackTrace();
}
来源:https://stackoverflow.com/questions/18763090/connecting-to-postgresql-in-java-app-engine