【bug】Java操作FTP報(bào)錯(cuò)MalformedServerReplyException: Could not parse response code. Server Reply: SSH-2...

大家好,我是一直默默努力的大齡程序媛大丫姨,今天幫助同事解決一個(gè)附件上傳的問(wèn)題,他反饋說(shuō)附件上傳后,代碼卡死,不報(bào)錯(cuò),無(wú)反應(yīng),結(jié)果經(jīng)過(guò)我細(xì)細(xì)排查,發(fā)現(xiàn)不支持ftp協(xié)議。

問(wèn)題

MalformedServerReplyException: Could not parse response code. Server Reply: SSH-2.0-OpenSSH 異常。

場(chǎng)景

Java后臺(tái)使用org.apache.commons.net.ftp.FTPClient 連接服務(wù)器,進(jìn)行FTP操作 :上傳/下載文件。

異常

org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: SSH-2.0-OpenSSH
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:337)
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
    at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:400)
    at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:924)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:183)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:203)
    at com.web.util.FtpUtil.connectFTP(FtpUtil.java:351)
    at com.web.util.FtpUtil.main(FtpUtil.java:375)
null

Process finished with exit code 0

原因

一般我們使用 Xftp 或 FileZilla這些軟件去連接服務(wù)器(FTP/SFTP)都是可以連接到。區(qū)別就是連接的參數(shù)中

  1. 協(xié)議:ftp 或 sftp

  2. 端口:21/22

但是在Java后臺(tái)使用org.apache.commons.net.ftp.FTPClient通過(guò)協(xié)議SSH2進(jìn)行SFTP連接時(shí)就會(huì)報(bào)如上錯(cuò)誤,原因是它不支持這種方式的連接(使用FTPSClient的SSL也是不行的)。

解決方法

有兩種:

  • 第一種:Java后臺(tái)繼續(xù)使用org.apache.commons.net.ftp.FTPClient工具,然后把服務(wù)器開啟FTP協(xié)議。

  • 第二種:換一種連接方式,使用 com.jcraft.jsch.ChannelSftp 代替org.apache.commons.net.ftp.FTPClient。

使用第二種需要引入 com.jcraft.jsch.ChannelSftp 架包。SpringBoot項(xiàng)目在pom中直接引入,其他的可自行下載。

 <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.49</version>
        </dependency>

使用第一種方法需要找運(yùn)維去把服務(wù)器開啟SFTP協(xié)議,一般你個(gè)小開發(fā)人家能不能幫你或者基于一些安全考慮能不能開啟都是問(wèn)題。所以這里推薦使用第二種方法。

ChannelSftp 和 FTPClient 的一些使用中區(qū)別:

1. 連接方式

FTPClient的連接

 FTPClient ftp = new FTPClient();
            ftp.connect(ip, port);
            //下面三行代碼必須要,而且不能改變編碼格式
            ftp.setControlEncoding("UTF-8");
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
            conf.setServerLanguageCode("zh");
            //如果采用默認(rèn)端口,可以使用ftp.connect(url) 的方式直接連接FTP服務(wù)器
            ftp.login(userName, password);//登錄

ChannelSftp 連接

            JSch jsch = new JSch();
            if (privateKey != null) {
                jsch.addIdentity(privateKey);// 設(shè)置私鑰
            }
            Session session = jsch.getSession(userName, host, port);
            if (password != null) {
                session.setPassword(password);
            }
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftp = (ChannelSftp) channel;

2、主要功能方法

切換到 directory 目錄

ChannelSftp.cd(directory);

FtpClient.changeWorkingDirectory(ftpFilePath);

上傳文件

ChannelSftp.put(FileInputStream, fileName) ;

FtpClient.storeFile(fileName, FileInputStream);

下載文件

ChannelSftp.get(fileName, new FileOutputStream(file));

FtpClient.retrieveFileStream() 或 FtpClient.retrieveFile

還有需要注意的就是關(guān)閉的連接的方法,ChannelSftp需要你把 Session也關(guān)閉掉。

原文鏈接

https://blog.csdn.net/shenju2011/article/details/106614717

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容