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

curl可正常上传至IONOS FTPS,但Apache Commons FTPSClient实现失败求助

解决Apache Commons FTPSClient连接IONOS HiDrive FTPS上传失败的问题

结合你用curl --ftp-ssl -T test.txt ftp://username:password@ftp.hidrive.ionos.com/public/test.txt成功的情况,你的Java代码需要补充以下关键配置,才能和curl的行为对齐:

1. 采用显式FTPS模式(放弃隐式模式)

IONOS HiDrive的FTPS服务默认使用显式模式(端口21),你设置isImplicit=true时用的是隐式FTPS(默认端口990),这会导致连接被服务器直接重置。必须初始化FTPSClient为显式模式:

FTPSClient ftpsClient = new FTPSClient(false); // false对应显式FTPS,和curl的--ftp-ssl行为一致

2. 强制启用数据通道加密(执行PBSZ和PROT命令)

curl默认会自动发送PBSZ 0和PROT P命令加密数据传输通道,但Apache Commons FTPSClient不会默认执行这两步。服务器拒绝PORT/PASV操作,核心原因就是数据通道未加密,权限校验不通过。登录成功后必须添加这两行:

ftpsClient.execPBSZ(0); // 保护缓冲区大小设为0(PROT为P时的强制要求)
ftpsClient.execPROT("P"); // 将数据通道设置为私有加密模式

3. 正确配置被动模式与文件类型

  • 开启本地被动模式:ftpsClient.enterLocalPassiveMode();,和curl默认的被动模式行为一致,适配服务器的防火墙策略。
  • 设置文件传输类型为二进制:ftpsClient.setFileType(FTP.BINARY_FILE_TYPE);,避免ASCII转换导致的文件损坏或上传失败。

完整可运行代码示例

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;

import java.io.FileInputStream;
import java.io.IOException;

public class HiDriveFTPSUpload {
    public static void main(String[] args) {
        String server = "ftp.hidrive.ionos.com";
        int port = 21;
        String username = "your_username";
        String password = "your_password";
        String localFilePath = "test.txt";
        String remoteFilePath = "/public/test.txt";

        FTPSClient ftpsClient = new FTPSClient(false);
        try {
            // 连接服务器
            ftpsClient.connect(server, port);
            int replyCode = ftpsClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                throw new IOException("服务器连接失败,回复码:" + replyCode);
            }

            // 登录
            if (!ftpsClient.login(username, password)) {
                throw new IOException("登录失败,服务器回复:" + ftpsClient.getReplyString());
            }

            // 启用数据通道加密(关键步骤)
            ftpsClient.execPBSZ(0);
            if (!ftpsClient.execPROT("P")) {
                throw new IOException("设置数据通道加密失败:" + ftpsClient.getReplyString());
            }

            // 配置被动模式与文件类型
            ftpsClient.enterLocalPassiveMode();
            ftpsClient.setFileType(FTP.BINARY_FILE_TYPE);

            // 上传文件
            try (FileInputStream inputStream = new FileInputStream(localFilePath)) {
                boolean uploadSuccess = ftpsClient.storeFile(remoteFilePath, inputStream);
                if (uploadSuccess) {
                    System.out.println("文件上传成功");
                } else {
                    throw new IOException("上传失败,服务器回复:" + ftpsClient.getReplyString());
                }
            }

            // 退出登录并断开连接
            ftpsClient.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpsClient.isConnected()) {
                try {
                    ftpsClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

额外注意事项

  • 若遇到证书校验问题(测试环境可临时忽略),可以给FTPSClient设置自定义TrustManager,但生产环境建议导入服务器的CA证书进行合法校验。
  • 确保远程路径/public/test.txt的权限正确(curl能成功则权限无问题,核心还是代码配置遗漏)。

内容的提问来源于stack exchange,提问作者Markus S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:15:06