首页 > 代码库 > 如何使用jcraft 模拟SFTP登陆

如何使用jcraft 模拟SFTP登陆

大家如果熟悉Linux系统话,对ssh,sftp,scp等命令非常熟悉。ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接。ssh 在连接和传送的过程中会加密所有的数据。

而今天我要介绍的一个jar包,是使用 JSCH。JSCH是一个纯粹的用Java实现SSH功能的java  library.

官方地址为:http://www.jcraft.com/jsch/
GitHub 地址为:https://github.com/vngx/vngx-jsch

maven配置如下:

技术分享
 <!-- 加入sftp依赖包 -->  
    <dependency>  
        <groupId>com.jcraft</groupId>  
        <artifactId>jsch</artifactId>  
        <version>0.1.50</version>  
    </dependency>  
View Code

对于这样的设计我们先设计一个FTP连接接口:

技术分享
package com.xuanyuan.tools;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
/**
 * FTP 接口
 * @author Punk Lin
 * @email lentr@sina.cn
 * @date 2016年12月23日
 *
 */
public interface FTPService {


    /**
     * 登入
     * @param host 登入主机地址
     * @param userName 用户名
     * @param password 密码
     * @param port 端口
     * @throws Exception
     */
    public void login(String host, String userName, String password, int port) throws Exception;

    /**
     * 退出
     */
    public void logout();

    /**
     * 上传文件
     * 
     * @param in
     *            输入流
     * @param remoteFilePath
     *            远程文件绝对路径
     * @throws Exception
     */
    public void uploadFile(InputStream in, String remoteFilePath) throws Exception;

    /**
     * 文件下载到本地
     * 
     * @param sourceFilePath
     *            远程文件绝对路径
     * @param localFilePath
     *            本地目录或绝对路径
     * @throws Exception
     */
    public void downloadFile(String sourceFilePath, String localFilePath)
            throws Exception;

    /**
     * 文件下载到输出流
     * 
     * @param sourceFilePath
     *            远程文件绝对路径
     * @param out
     *            输出流
     * @throws Exception
     */
    public void downloadFile(String sourceFilePath, OutputStream out) throws Exception;

    /**
     * 删除文件
     * 
     * @param directory
     *            要删除文件所在目录
     * @param deleteFile
     *            要删除的文件
     * 
     * @throws Exception
     */
    public void deleteFile(String directory, String fileName) throws Exception;

    /**
     * 列出目录下的文件,包括目录
     * 
     * @param directory
     *            要列出的目录
     * 
     * @return list 文件名列表
     * 
     * @throws Exception
     */
    public Vector<?> listFiles(String directory) throws Exception;

}
View Code

对于它的具体实现,则如下:

技术分享
package com.xuanyuan.tools.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Vector;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.xuanyuan.tools.FTPService;

public class SFTPServiceImpl implements FTPService {
    /** sftp会话session */
    protected Session sshSession = null;

    /** sftp通道 */
    protected ChannelSftp sftp = null;

    @Override
    public void login(String host, String userName, String password, int port)
            throws Exception {
        try {
            JSch jsch = new JSch();
            this.sshSession = jsch.getSession(userName, host, port);
            this.sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            this.sshSession.setConfig(sshConfig);
            this.sshSession.connect(20000);
            this.sftp = (ChannelSftp) sshSession.openChannel("sftp");
            this.sftp.connect();
            this.sftp.setFilenameEncoding("UTF-8");
        } catch (JSchException e) {
            throw new RuntimeException("无法使用sftp登陆,请检查用户名密码或端口");
        }

    }

    @Override
    public void logout() {
        if (this.sftp != null) {
            this.sftp.disconnect();
            this.sshSession.disconnect();
            this.sftp = null;
            this.sshSession = null;
        }
    }

    @Override
    public void uploadFile(InputStream in, String remoteFilePath)
            throws Exception {
        try {
            String filepath = remoteFilePath.substring(0,
                    remoteFilePath.lastIndexOf("/"));
            String fileName = remoteFilePath.substring(
                    remoteFilePath.lastIndexOf("/") + 1,
                    remoteFilePath.length());
            this.sftp.cd(filepath);
            this.sftp.put(in, fileName, 0);

        } catch (SftpException e) {
            throw new RuntimeException("上传文件时发生错误!请检查文件路径是否正确");
        }

    }

    @Override
    public void downloadFile(String sourceFilePath, String localFilePath)
            throws Exception {
        File file = new File(localFilePath);
        FileOutputStream out = null;
        try {
            if (file.isDirectory()) {
                this.sftp.get(sourceFilePath, localFilePath);
            } else {
                out = new FileOutputStream(file);
                this.sftp.get(sourceFilePath, out);
            }
        } catch (SftpException e) {
            throw new RuntimeException("下载文件时发生错误!请检查文件路径是否正确");
        } finally {
            if (out != null)
                out.close();
        }
    }

    @Override
    public void downloadFile(String sourceFilePath, OutputStream out)
            throws Exception {
        try {
            this.sftp.get(sourceFilePath, out);
        } catch (SftpException e) {
            throw new RuntimeException("下载文件时发生错误!请检查文件路径是否正确");
        }

    }

    @Override
    public void deleteFile(String directory, String fileName) throws Exception {
        this.sftp.cd(directory);
        this.sftp.rm(fileName);

    }

    @Override
    public Vector<?> listFiles(String directory) throws Exception {
        return this.sftp.ls(directory);
    }

}
View Code

至此工具完成了。这样我们也可以通过这个工具提供,网页这样的上传道服务器。

 

相信别人往往比相信自己更简单,是恐于未知,还是惧于无力。

 

如何使用jcraft 模拟SFTP登陆