Java实现ftp文件传输异常问题:SSH-2.0-OpenSSH_7.4

Jakcy Java 2021-10-15 116

报错信息

org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: SSH-2.0-OpenSSH_7.4
	at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:344)
	at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
	at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:438)
	at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:962)
	at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:950)
	at org.apache.commons.net.SocketClient._connect(SocketClient.java:244)
	at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)
	at com.yixing.syncdatapc.service.impl.ExportServiceImpl.MzBlWybl(ExportServiceImpl.java:128)
	at com.yixing.syncdatapc.service.impl.ExportServiceImpl.export(ExportServiceImpl.java:77)
	at com.yixing.syncdatapc.Main.lambda$null$0(Main.java:74)
	at java.lang.Thread.run(Thread.java:748)
org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: Protocol mismatch.

	at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:344)
	at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
	at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:523)
	at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:648)
	at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:622)
	at org.apache.commons.net.ftp.FTP.quit(FTP.java:904)
	at org.apache.commons.net.ftp.FTPClient.logout(FTPClient.java:1148)
	at com.yixing.syncdatapc.service.impl.ExportServiceImpl.MzBlWybl(ExportServiceImpl.java:158)
	at com.yixing.syncdatapc.service.impl.ExportServiceImpl.export(ExportServiceImpl.java:77)
	at com.yixing.syncdatapc.Main.lambda$null$0(Main.java:74)
	at java.lang.Thread.run(Thread.java:748)

原因是FTPClient不支持通过协议SSH2进行SFTP连接,使用另一种模式现实SFTP

<dependency>
	<groupId>com.jcraft</groupId>
	<artifactId>jsch</artifactId>
	<version>0.1.54</version>
</dependency>
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

@Slf4j
public class FtpUtil {

    private static ChannelSftp ftpClient = null;
    private static Session sshSession = null;

    /**
     * 连接服务器
     */
    public static ChannelSftp getConnect(String host, String port, String userName, String password)
            throws Exception {
        try {
            JSch jsch = new JSch();
            // 获取sshSession
            sshSession = jsch.getSession(userName, host, Integer.parseInt(port));
            // 添加s密码
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            // 开启sshSession链接
            sshSession.connect();
            // 获取sftp通道
            ftpClient = (ChannelSftp) sshSession.openChannel("sftp");
            // 开启
            ftpClient.connect();
            log.debug("连接sftp服务器成功");
        } catch (Exception e) {
            log.error("连接sftp服务器异常:", e);
            throw new Exception("连接sftp服务器异常");
        }
        return ftpClient;
    }

    /**
     * 下载文件
     *
     * @param ftp_path    服务器文件路径
     * @param save_path   下载保存路径
     * @param oldFileName 服务器上文件名
     * @param newFileName 保存后新文件名
     * @throws Exception
     */
    public static void download(String ftp_path, String save_path, String oldFileName, String newFileName)
            throws Exception {
        FileOutputStream fos = null;
        try {
            ftpClient.cd(ftp_path);
            File file = new File(save_path);
            if (!file.exists()) {
                file.mkdirs();
            }
            String saveFile = save_path + newFileName;
            File file1 = new File(saveFile);
            fos = new FileOutputStream(file1);
            ftpClient.get(oldFileName, fos);
        } catch (Exception e) {
            log.error("下载文件异常", e);
            throw new Exception("下载文件异常", e);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (Exception e) {
                    log.error("流关闭异常:", e);
                }
            }
        }
    }

    /**
     * 上传
     *
     * @param upload_path 上传文件路径
     * @param ftp_path    服务器保存路径
     * @param newFileName 新文件名
     * @throws Exception
     */
    public static void uploadFile(String upload_path, String ftp_path, String newFileName) throws Exception {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(upload_path);
            ftpClient.cd(ftp_path);
            ftpClient.put(fis, newFileName);
        } catch (Exception e) {
            log.error("上传文件异常", e);
            throw new Exception("上传文件异常", e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    log.error("流关闭异常:", e);
                }
            }
        }
    }

    /**
     * 关闭
     */
    public static void close() throws Exception {
        log.debug("关闭与sftp服务器的连接");
        try {
            ftpClient.disconnect();
            sshSession.disconnect();
        } catch (Exception e) {
            log.error("关闭异常:", e);
        }
    }

}