You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Java使用SSH访问远程树莓派4上的MariaDB服务器问题咨询

问题排查与修复方案

现有代码核心问题

  • SSH核心配置为空:sshUser、sshHost 两个参数均为空白值,需要填入树莓派对应的SSH登录用户名(默认通常为pi)、树莓派的可访问IP地址(同局域网下填本地IP,跨网填公网映射地址)
  • 私钥路径解析失败:JSch无法识别~作为用户目录的简写,jsch.addIdentity("~/.ssh/id_rsa")需要替换为本地id_rsa私钥文件的绝对路径,比如Windows环境为C:/Users/你的用户名/.ssh/id_rsa,macOS/Linux环境为/home/你的用户名/.ssh/id_rsa
  • 未关闭主机密钥校验:JSch默认会校验目标主机的SSH指纹,本地未提前存储树莓派指纹时会直接抛出连接异常,个人开发场景可在session.connect()前添加session.setConfig("StrictHostKeyChecking", "no");关闭校验
  • SQL语法错误:INSERT语句缺少VALUES关键字,且字段名错误使用单引号包裹(单引号仅用于标记字符串值,字段名需用反引号包裹或不加符号),同时直接拼接用户输入存在SQL注入风险,建议替换为PreparedStatement
  • 资源未释放:SSH会话、数据库连接、SQL执行对象用完后均未关闭,会长期占用树莓派连接资源,也会导致本地资源泄漏
  • JDBC连接参数缺失:高版本MariaDB需要在JDBC URL后添加时区、SSL配置,否则会出现连接报错

优化后代码示例

public void actionPerformed(ActionEvent event) {
    if(event.getSource() == submitButton){
        String name = userField.getText();
        String email = emailField.getText();
        String system = systemField.getText();
        String serial = serialField.getText();
        String date = dateField.getText();

        // 填入你自己的实际配置
        int localPort = 6000;
        String sshUser ="pi";
        String sshHost = "你树莓派的IP";
        String dbHost = "192.168.1.242";
        int dbPort = 3306;
        String dbUser = "root";
        String dbPassword = "wacky12";
        String driver = "com.mysql.cj.jdbc.Driver"; // 高版本MariaDB用这个驱动类

        Session session = null;
        Connection connection = null;
        PreparedStatement pstmt = null;
        try{
            JSch jsch = new JSch();
            // 替换成你自己的私钥绝对路径
            jsch.addIdentity("/home/你的用户名/.ssh/id_rsa");
            session = jsch.getSession(sshUser, sshHost, 22);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();
            // 固定用6000端口做转发,也可以保留0用随机端口
            int forwardedPort = session.setPortForwardingL(localPort, dbHost, dbPort);
            String url = "jdbc:mysql://localhost:" + forwardedPort + "?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
            Class.forName(driver);
            connection = DriverManager.getConnection(url, dbUser, dbPassword);
            // 用预编译语句避免SQL注入,且语法更规范
            String insert = "insert into LaptopReturns(`name`,`email`,`system`,`serial`,`date`) values(?,?,?,?,?)";
            pstmt = connection.prepareStatement(insert);
            pstmt.setString(1, name);
            pstmt.setString(2, email);
            pstmt.setString(3, system);
            pstmt.setString(4, serial);
            pstmt.setString(5, date);
            pstmt.executeUpdate();
            System.out.print("Done!");
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭所有资源,注意顺序
            try { if(pstmt != null) pstmt.close(); } catch (Exception e) {}
            try { if(connection != null) connection.close(); } catch (Exception e) {}
            try { if(session != null) session.disconnect(); } catch (Exception e) {}
        }
    }
}

SSH连接选型建议

  • 高频使用场景:如果你的程序提交数据的频率很高(比如每分钟多次操作),建议程序启动时就建立SSH连接,额外增加断连自动重连逻辑即可,避免每次操作都重复建立SSH连接的额外开销
  • 低频使用场景:如果提交操作频次很低(比如每日仅几次操作),建议点击按钮时按需建立连接,操作完成后立即关闭连接,减少树莓派后台空闲连接的资源占用

内容的提问来源于stack exchange,提问作者SierraArgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:48:01