Hostinger远程MySQL数据库Java连接被拒,求解决建议
Java连接Hostinger远程数据库提示Access Denied的解决建议
我在Hostinger部署了PHP开发的Web应用,尝试用Java应用连接该平台的数据库时出现“access denied”错误,但通过Navicat Premium借助SSH隧道能正常连接。以下是针对性的解决建议:
问题代码
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.xpos.database; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; /** * * @author Jamith */ public class DbConnect { static Connection con; private static final String dbHost = "########"; private static final String port = "####"; private static final String dbName = "########"; private static final String userName = "########"; private static final String password = "########"; public static void main(String[] args) throws ClassNotFoundException, SQLException { connect(); } public static void connect() throws ClassNotFoundException,SQLException{ Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://"+dbHost+":"+port+"/"+dbName,userName,password); } public static void pushToDB(String sql)throws ClassNotFoundException,SQLException{ if(con == null){ connect(); } con.createStatement().executeUpdate(sql); } public static ResultSet getFromDB(String sql)throws ClassNotFoundException,SQLException{ if(con == null){ connect(); } return con.createStatement().executeQuery(sql); } public static Connection getDBConnection()throws Exception{ if (con == null) { connect(); } return con; } }
核心原因
Hostinger默认限制数据库的公网直接访问,仅允许通过服务器内部(或SSH隧道转发)的连接,这也是Navicat通过SSH能连接但Java直接连接失败的核心原因。
解决建议
1. 采用SSH隧道连接(和Navicat逻辑一致)
这是最可靠的方案,有两种实现方式:
方式一:使用JSch库手动建立SSH隧道
先引入JSch依赖(Maven示例):
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency>
修改连接逻辑,先建立隧道再连接数据库:
public static void connect() throws ClassNotFoundException, SQLException, JSchException { // 1. 建立SSH隧道 JSch jsch = new JSch(); String sshUser = "你的Hostinger SSH用户名"; String sshHost = "你的Hostinger服务器公网IP"; int sshPort = 22; String sshPassword = "你的SSH密码"; // 或用私钥文件:jsch.addIdentity("私钥文件路径"); Session sshSession = jsch.getSession(sshUser, sshHost, sshPort); sshSession.setPassword(sshPassword); sshSession.setConfig("StrictHostKeyChecking", "no"); // 生产环境建议改为"ask"或手动添加密钥 sshSession.connect(); // 2. 转发数据库端口到本地 int localPort = 3307; // 本地未占用的端口 String dbInternalHost = "localhost"; // Hostinger数据库在服务器内部的地址 int dbInternalPort = 3306; // 服务器内部数据库端口 sshSession.setPortForwardingL(localPort, dbInternalHost, dbInternalPort); // 3. 通过本地转发端口连接数据库 Class.forName("com.mysql.cj.jdbc.Driver"); String jdbcUrl = "jdbc:mysql://localhost:" + localPort + "/" + dbName + "?serverTimezone=UTC"; con = DriverManager.getConnection(jdbcUrl, userName, password); }
方式二:使用MySQL 8.0+驱动内置的SSH支持
如果使用MySQL Connector/J 8.0.23及以上版本,可直接在JDBC URL中配置SSH参数,无需额外依赖:
public static void connect() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.cj.jdbc.Driver"); String sshHost = "你的Hostinger服务器公网IP"; String sshUser = "你的Hostinger SSH用户名"; String sshPassword = "你的SSH密码"; String jdbcUrl = String.format( "jdbc:mysql://localhost:%s/%s?serverTimezone=UTC&sshHost=%s&sshPort=22&sshUser=%s&sshPassword=%s", port, dbName, sshHost, sshUser, sshPassword ); con = DriverManager.getConnection(jdbcUrl, userName, password); }
注意:这里的localhost是服务器内部的数据库地址,不是本地主机。
2. 验证数据库用户权限
确保数据库用户允许从服务器本地(localhost)访问,可通过Navicat连接后执行以下SQL:
GRANT ALL PRIVILEGES ON `数据库名`.* TO '用户名'@'localhost'; FLUSH PRIVILEGES;
3. 修正JDBC URL参数
- 必须添加时区参数(如
?serverTimezone=UTC),避免MySQL 8.0驱动的时区校验错误 - 不要直接使用数据库的公网IP和端口,Hostinger默认不开放数据库的公网端口
内容的提问来源于stack exchange,提问作者Jamith Sheron
相关产品推荐
相关产品推荐

