Java - 通信链路故障

时间:2010-09-01 01:21:49

标签: java mysql jdbc

我刚刚与我的主持人谈过我的网页,他们说他们允许JDBC连接。

无论如何,您可以在http://mystikrpg.com/mysqltest/mysqltry.html

查看此页面

这是我的错误:

**** Looking for database...
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1118)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:343)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2308)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2122)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:774)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:375)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:289)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at test.init(test.java:38)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: java.security.AccessControlException: access denied (java.net.SocketPermission [0:0:0:0:0:0:0:1]:4464 connect,resolve)
    at com.mysql.jdbc.StandardSocketFactory.unwrapExceptionToProperClassAndThrowIt(StandardSocketFactory.java:407)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:268)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:292)
    ... 16 more
java.lang.NullPointerException
    at test.init(test.java:69)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Exception: java.lang.NullPointerException

这是代码:

我做错了什么?

//package mysqltest;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;
import java.awt.TextArea.*;
import java.sql.*;
import java.util.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import java.net.*;
import java.applet.*;

public class test extends JApplet
{
    public JTextArea c;
    public void init()
    {
        c = new JTextArea();
        add(c);
        c.append("**** Looking for database...");
        Connection conn = null;
        Properties props = new Properties();
        String url = "jdbc:mysql://localhost:3306/";
        String dbName = "mystik";
        String driver = "com.mysql.jdbc.Driver";
        String userName = "root";
        String password = "";
        String loggedusername = getParameter("name");
        boolean online = false;
        try
        {
            Class.forName(driver).newInstance();
            online = true;
            if (online)
            {
                // if user loads applet online
                conn = DriverManager.getConnection("jdbc:mysql://localhost:4464/jsfdan_mystikdan", "jsfdan_muser", "test");
            }
            else
            {
                // for localhost - testing purposes props.put("user", "root");
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mystik", props);
            }
            c.append("\nConnected to the database");
            c.append("\nGetting stats for: " + loggedusername);
            PreparedStatement statement = conn.prepareStatement( "select * from `user` where `username` = '"+loggedusername+"'");
            ResultSet result = statement.executeQuery();
            // just a dumb mysql statement! while(result.next())
            {
                c.append("\nUsername: "+result.getString(2)+ "\nLevel: "+result.getString(6)+"\nEXP: "+result.getString(8)+"\n");
            }
            PreparedStatement updateEXP = conn.prepareStatement( "update`user` set `exp` = '666' where `username` = '"+loggedusername+"'");
            updateEXP.executeUpdate();
            ResultSet xresult = statement.executeQuery();
            while(xresult.next())
            {
                c.append("\nUsername: "+xresult.getString(2)+ "\nLevel: "+xresult.getString(6)+"\nEXP: "+xresult.getString(8)+"\n");
            }

            c.append("\nDisconnected from database");
        }
        catch (Exception e)
        {
            System.out.println(c.getText());
            e.printStackTrace();
        }finally {
            try {
            conn.close();
        }catch(SQLException dan) {dan.printStackTrace(); }
        }
    }
}

2 个答案:

答案 0 :(得分:3)

引用您的代码:

  // if user loads applet online
  conn = DriverManager.getConnection("jdbc:mysql://localhost:4464/jsfdan_mystikdan", "jsfdan_muser", "test");

applet是在用户机器上运行的程序,浏览器位于该程序中。因此,localhost指的是此阶段用户的计算机。有可能大多数用户没有在他们自己的机器上运行MySQL,即使它们是,它也不会是你的applet所经历的那个并且它无论如何都会离开applet的沙盒环境。

编辑(在评论中讨论后):

从讨论和之前相关问题中的评论来看,您似乎试图从分布在可能位于任何地方的客户端的应用程序(applet)直接连接到MySQL服务器,这通常是错误的方法。

  • 您担心在示例中发布您的用户名/密码。与您广泛分发applet时可能发生的情况相比,这只是一个小问题:任何人都可以轻松查看应用程序发送到MySQL服务器的流量并获取用户名/密码。
  • 大多数MySQL服务器都被阻止外部访问,主要是因为与整个应用程序的访问要求相比,它们不能自行提供合​​适的访问控制。情况并非总是如此,但INSERT / SELECT / UPDATE操作的访问控制本身通常太粗糙,无法代表整个应用程序的功能目的。

对于使用数据库的大多数服务,用户管理和访问控制是在应用程序级别完成的,而不是在数据库级别完成的。当您使用为整个应用程序创建数据库和用户帐户的共享提供程序时,即使您需要多个用户,也会出现这种情况。

典型的解决方法是开发客户端将调用的另一项服务(通常是Web服务),为您希望客户端对数据执行的各种操作提供合适的身份验证和使用上下文。

我不确定您的托管服务是否允许您运行Java服务,但更便宜的托管服务提供商倾向于让您运行PHP,Perl和/或Python服务,因此您可以使用其中一种语言编写服务并拥有applet是与他们交谈的客户。

解释如何编写Web服务可能超出了这个问题/答案的范围。一般来说,您可能会遇到3个类别:REST风格的Web服务(它是一种架构风格,由资源和表示的概念引导),XML-RPC(错误地称为“REST”,您发送片段的地方XML的一些网页,它将调用一个函数/方法并给你一些结果;你可能也可以用JSON和SOAP做同样的事情(你可能会得到更多的工具,但也可能更臃肿)取决于你的舒适度)。关于哪个更好,但是一直在进行辩论,但是你需要调查并选择你认为对你的应用更好的东西。它可能取决于您可以在主机上部署的内容。

答案 1 :(得分:0)

NPE是因为Connection conn从未被初始化 - 这就是爆炸。

我建议您使用数据库连接工具(例如MySQL Workbench)来建立从您的系统到mystikrpg.com的正确网址;一旦你有了正确的URL,就可以把它放在applet中。

正如@Bruno指出的那样,applet在本地运行。