Spring Boot集成JSch的示例代码

 更新时间:2024年03月27日 11:39:52   作者:HBLOG  
本文主要介绍了Spring Boot集成JSch的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

1.JSch介绍

JSch是SSH2的纯Java实现。
JSch允许您连接到sshd服务器并使用端口转发,X11转发,文件传输等,并且可以将其功能集成到您自己的Java程序中。

2.实现原理

根据远程主机的IP地址,用户名和端口,建立会话(Session)
设置用户信息(包括密码和Userinfo),然后连接session,getSession()只是创建一个session,需要设置必要的认证信息之后,调用connect()才能建立连接。
设置channel上需要远程执行的Shell脚本,连接channel,就可以远程执行该Shell脚本,调用openChannel(String type) 可以在session上打开指定类型的channel。该channel只是被初始化,使用前需要先调用connect()进行连接。
可以读取远程执行Shell脚本的输出,然后依次断开channel和session的连接

3.代码工程

实验目标:实现文件上传到服务,服务器下载文件以及执行服务器命令

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>JSch</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.55</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
    </dependencies>
</project>

remote.java

package com.et.jsch.model;

import lombok.Data;

@Data
public class Remote {
  private String host;
  private final int port = 22;
  private String user;
  private String password;
  private final String identity = "~/.ssh/id_rsa";
  private String passphrase;
}

JSchUtil.java

package com.et.jsch.util;

import com.et.jsch.model.Remote;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * ssh tools
 */
@Slf4j
public class JSchUtil {

    public static final int SESSION_TIMEOUT = 30000;
    public static final int CONNECT_TIMEOUT = 3000;

    /**
     * get session
     *
     * @param remote ssh server info
     * @return session
     * @throws JSchException /
     */
    public static Session getSession(Remote remote) throws JSchException {
        JSch jSch = new JSch();
        if (Files.exists(Paths.get(remote.getIdentity()))) {
            jSch.addIdentity(remote.getIdentity(), remote.getPassphrase());
        }
        Session session = jSch.getSession(remote.getUser(), remote.getHost(), remote.getPort());
        session.setPassword(remote.getPassword());
        session.setConfig("StrictHostKeyChecking", "no");
        return session;
    }

    /**
     * excute remote command
     *
     * @param session session
     * @param command command
     * @return /
     * @throws JSchException /
     */
    public static List<String> remoteExecute(Session session, String command) throws JSchException {
        log.debug(">> {}", command);
        List<String> resultLines = new ArrayList<>();
        ChannelExec channel = null;
        try {
            channel = openExecChannel(session);
            channel.setCommand(command);
            InputStream input = channel.getInputStream();
            channel.connect(CONNECT_TIMEOUT);
            try {
                BufferedReader inputReader = new BufferedReader(new InputStreamReader(input));
                String inputLine;
                while ((inputLine = inputReader.readLine()) != null) {
                    log.debug("   {}", inputLine);
                    resultLines.add(inputLine);
                }
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (Exception e) {
                        log.error("JSch inputStream close error:", e);
                    }
                }
            }
        } catch (IOException e) {
            log.error("IOException:", e);
        } finally {
            disconnect(channel);
        }
        return resultLines;
    }

    /**
     * scp file to remote server
     *
     * @param session     session
     * @param source      local file
     * @param destination remote target file
     * @return file size
     */
    public static long scpTo(Session session, String source, String destination) {
        FileInputStream fileInputStream = null;
        ChannelExec channel = null;
        try {
            channel = openExecChannel(session);
            OutputStream out = channel.getOutputStream();
            InputStream in = channel.getInputStream();
            boolean ptimestamp = false;
            String command = "scp";
            if (ptimestamp) {
                command += " -p";
            }
            command += " -t " + destination;
            channel.setCommand(command);
            channel.connect(CONNECT_TIMEOUT);
            if (checkAck(in) != 0) {
                return -1;
            }
            File _lfile = new File(source);
            if (ptimestamp) {
                command = "T " + (_lfile.lastModified() / 1000) + " 0";
                // The access time should be sent here,
                // but it is not accessible with JavaAPI ;-<
                command += (" " + (_lfile.lastModified() / 1000) + " 0\n");
                out.write(command.getBytes());
                out.flush();
                if (checkAck(in) != 0) {
                    return -1;
                }
            }
            //send "C0644 filesize filename", where filename should not include '/'
            long fileSize = _lfile.length();
            command = "C0644 " + fileSize + " ";
            if (source.lastIndexOf('/') > 0) {
                command += source.substring(source.lastIndexOf('/') + 1);
            } else {
                command += source;
            }
            command += "\n";
            out.write(command.getBytes());
            out.flush();
            if (checkAck(in) != 0) {
                return -1;
            }
            //send content of file
            fileInputStream = new FileInputStream(source);
            byte[] buf = new byte[1024];
            long sum = 0;
            while (true) {
                int len = fileInputStream.read(buf, 0, buf.length);
                if (len <= 0) {
                    break;
                }
                out.write(buf, 0, len);
                sum += len;
            }
            //send '\0'
            buf[0] = 0;
            out.write(buf, 0, 1);
            out.flush();
            if (checkAck(in) != 0) {
                return -1;
            }
            return sum;
        } catch (JSchException e) {
            log.error("scp to caught jsch exception, ", e);
        } catch (IOException e) {
            log.error("scp to caught io exception, ", e);
        } catch (Exception e) {
            log.error("scp to error, ", e);
        } finally {
            closeInputStream(fileInputStream);
            disconnect(channel);
        }
        return -1;
    }

    /**
     * scp remote file to local
     *
     * @param session     session
     * @param source      remote file
     * @param destination local file
     * @return file size
     */
    public static long scpFrom(Session session, String source, String destination) {
        FileOutputStream fileOutputStream = null;
        ChannelExec channel = null;
        try {
            channel = openExecChannel(session);
            channel.setCommand("scp -f " + source);
            OutputStream out = channel.getOutputStream();
            InputStream in = channel.getInputStream();
            channel.connect();
            byte[] buf = new byte[1024];
            //send '\0'
            buf[0] = 0;
            out.write(buf, 0, 1);
            out.flush();
            while (true) {
                if (checkAck(in) != 'C') {
                    break;
                }
            }
            //read '644 '
            in.read(buf, 0, 4);
            long fileSize = 0;
            while (true) {
                if (in.read(buf, 0, 1) < 0) {
                    break;
                }
                if (buf[0] == ' ') {
                    break;
                }
                fileSize = fileSize * 10L + (long) (buf[0] - '0');
            }
            String file = null;
            for (int i = 0; ; i++) {
                in.read(buf, i, 1);
                if (buf[i] == (byte) 0x0a) {
                    file = new String(buf, 0, i);
                    break;
                }
            }
            // send '\0'
            buf[0] = 0;
            out.write(buf, 0, 1);
            out.flush();
            // read a content of lfile
            if (Files.isDirectory(Paths.get(destination))) {
                fileOutputStream = new FileOutputStream(destination + File.separator + file);
            } else {
                fileOutputStream = new FileOutputStream(destination);
            }
            long sum = 0;
            while (true) {
                int len = in.read(buf, 0, buf.length);
                if (len <= 0) {
                    break;
                }
                sum += len;
                if (len >= fileSize) {
                    fileOutputStream.write(buf, 0, (int) fileSize);
                    break;
                }
                fileOutputStream.write(buf, 0, len);
                fileSize -= len;
            }
            return sum;
        } catch (JSchException e) {
            log.error("scp to caught jsch exception, ", e);
        } catch (IOException e) {
            log.error("scp to caught io exception, ", e);
        } catch (Exception e) {
            log.error("scp to error, ", e);
        } finally {
            closeOutputStream(fileOutputStream);
            disconnect(channel);
        }
        return -1;
    }

    /**
     * remote edit
     *
     * @param session session
     * @param source  target file
     * @param process edit command collect
     * @return isSuccess
     */
    private static boolean remoteEdit(Session session, String source, Function<List<String>, List<String>> process) {
        InputStream in = null;
        OutputStream out = null;
        try {
            String fileName = source;
            int index = source.lastIndexOf('/');
            if (index >= 0) {
                fileName = source.substring(index + 1);
            }
            //backup source
            remoteExecute(session, String.format("cp %s %s", source, source + ".bak." + System.currentTimeMillis()));
            //scp from remote
            String tmpSource = System.getProperty("java.io.tmpdir") + session.getHost() + "-" + fileName;
            scpFrom(session, source, tmpSource);
            in = new FileInputStream(tmpSource);
            //edit file according function process
            String tmpDestination = tmpSource + ".des";
            out = new FileOutputStream(tmpDestination);
            List<String> inputLines = new ArrayList<>();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String inputLine = null;
            while ((inputLine = reader.readLine()) != null) {
                inputLines.add(inputLine);
            }
            List<String> outputLines = process.apply(inputLines);
            for (String outputLine : outputLines) {
                out.write((outputLine + "\n").getBytes());
                out.flush();
            }
            //scp to remote
            scpTo(session, tmpDestination, source);
            return true;
        } catch (Exception e) {
            log.error("remote edit error, ", e);
            return false;
        } finally {
            closeInputStream(in);
            closeOutputStream(out);
        }
    }

    /**
     * update file
     *
     * @param session   session
     * @param in        file stream
     * @param directory local dir
     * @param fileName  FTP server file name:xxx.txt ||xxx.txt.zip
     */
    public static boolean uploadFile(Session session, InputStream in, String directory, String fileName) {
        log.info(">>>>>>>>uploadFile--ftp start>>>>>>>>>>>>>");
        ChannelSftp channel = null;
        try {
            channel = openSftpChannel(session);
            channel.connect(CONNECT_TIMEOUT);
            String[] folders = directory.split("/");
            try {
                for (int i = 0; i < folders.length; i++) {
                    if (i == 0 && folders[i].length() == 0) {
                        channel.cd("/");
                    } else if (folders[i].length() > 0) {
                        try {
                            channel.cd(folders[i]);
                        } catch (SftpException e) {
                            channel.mkdir(folders[i]);
                            channel.cd(folders[i]);
                        }
                    }
                }
            } catch (SftpException e) {
                log.error("ftp create file fail" + directory, e);
                return false;
            }

            try {
                channel.put(in, fileName);
            } catch (SftpException e) {
                log.error("sftp error-->" + e.getMessage(), e);
                return false;
            }

            log.info(">>>>>>>>uploadFile--ftp upload end>>>>>>>>>>>>>");
            log.info(">>>>>>>>ftp upload dir:{},filename:{}>>>>>>>>>>>>>", directory, fileName);

            return true;
        } catch (JSchException e) {
            log.error("JSch error-->" + e.getMessage(), e);
            return false;
        } finally {
            closeInputStream(in);
            disconnect(channel);
        }
    }


    /**
     *
     *
     * @param channel   sftp connect
     * @param directory
     * @param fileName
     * @return
     */
    public static InputStream stream(ChannelSftp channel, String directory, String fileName) {
        try {
            channel.connect(CONNECT_TIMEOUT);
            InputStream inputStream = channel.get(directory + "/" + fileName);
            log.info(">>>>>>>>ftp file directory:{},filename:{}>>>>>>>>>>>>>", directory, fileName);
            return inputStream;
        } catch (SftpException e) {
            log.error("sftp error-->" + e.getMessage());
            return null;
        } catch (JSchException e) {
            log.error("JSch error-->" + e.getMessage());
            return null;
        }
    }


    /**
     * ftp delete remote file
     *
     * @param session   session
     * @param directory directory
     * @param fileName  filename
     * @return is Success
     */
    public static boolean deleteFile(Session session, String directory, String fileName) {
        log.info(">>>>>>>>deleteFile--ftp delete file end>>>>>>>>>>>>>");
        ChannelSftp channel = null;
        try {
            channel = openSftpChannel(session);
            channel.connect(CONNECT_TIMEOUT);
            channel.rm(directory + "/" + fileName);

            log.info(">>>>>>>>deleteFile--deletefile end>>>>>>>>>>>>>");
            log.info(">>>>>>>>ftp delete file directory:{},filename:{}>>>>>>>>>>>>>", directory, fileName);
        } catch (SftpException e) {
            log.error("ftp create directory fail" + directory);
            return false;
        } catch (JSchException e) {
            log.error("JSch error-->" + e.getMessage());
            return false;
        } finally {
            disconnect(channel);
        }

        return true;
    }

    public static Channel openChannel(Session session, String type) throws JSchException {
        if (!session.isConnected()) {
            session.connect(SESSION_TIMEOUT);
        }
        return session.openChannel(type);
    }

    public static ChannelSftp openSftpChannel(Session session) throws JSchException {
        return (ChannelSftp) openChannel(session, "sftp");
    }

    public static ChannelExec openExecChannel(Session session) throws JSchException {
        return (ChannelExec) openChannel(session, "exec");
    }

    /**
     * disconnect
     *
     * @param session
     */
    public static void disconnect(Session session) {
        if (session != null) {
            if (session.isConnected()) {
                try {
                    session.disconnect();
                    log.info("session disconnect successfully");
                } catch (Exception e) {
                    log.error("JSch session disconnect error:", e);
                }
            }
        }
    }

    /**
     * close connection
     *
     * @param channel channel connection
     */
    public static void disconnect(Channel channel) {
        if (channel != null) {
            if (channel.isConnected()) {
                try {
                    channel.disconnect();
                    log.info("channel is closed already");
                } catch (Exception e) {
                    log.error("JSch channel disconnect error:", e);
                }
            }
        }
    }

    public static int checkAck(InputStream in) throws IOException {
        int b = in.read();
        // b may be 0 for success,
        //          1 for error,
        //          2 for fatal error,
        //          -1
        if (b == 0) {
            return b;
        }
        if (b == -1) {
            return b;
        }
        if (b == 1 || b == 2) {
            StringBuilder sb = new StringBuilder();
            int c;
            do {
                c = in.read();
                sb.append((char) c);
            }
            while (c != '\n');
            if (b == 1) { // error
                log.debug(sb.toString());
            }
            if (b == 2) { // fatal error
                log.debug(sb.toString());
            }
        }
        return b;
    }

    public static void closeInputStream(InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                log.error("Close input stream error." + e.getMessage());
            }
        }
    }

    public static void closeOutputStream(OutputStream out) {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                log.error("Close output stream error." + e.getMessage());
            }
        }
    }

}

DemoApplication.java

package com.et.jsch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

代码仓库

https://github.com/Harries/springboot-demo

4.测试

import com.alibaba.fastjson.JSONObject;
import com.et.jsch.DemoApplication;
import com.et.jsch.model.Remote;
import com.et.jsch.util.JSchUtil;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class JSchUtilTests {
    private Logger log = LoggerFactory.getLogger(getClass());

    Session session;
    @Before
    public void before() throws JSchException {
        Remote remote= new Remote();
        remote.setHost("xxx.xxx.xxx.xxx");
        remote.setUser("root");
        remote.setPassword("xxxx");
        session= JSchUtil.getSession(remote);
    }
    @After
    public void after(){
        JSchUtil.disconnect(session);
    }
    @Test
    public void remoteExecute() throws JSchException {
        List<String>  list= JSchUtil.remoteExecute(session,"ls");
        System.out.println(JSONObject.toJSON(list));
    }
    @Test
    public void uploadFile() throws JSchException, FileNotFoundException {
        String filestr ="D:\\tmp\\test\\file_utils\\file1.txt";
        File file = new File(filestr);
        InputStream in = new FileInputStream(file);

        String directory="/root/test";
        String fileName="test.txt";
       boolean flag= JSchUtil.uploadFile(session,in,directory,fileName);
        System.out.println(flag);
    }
    @Test
    public void deleteFile() throws JSchException, FileNotFoundException {
        String directory="/root/test";
        String fileName="test.txt";
        boolean flag= JSchUtil.deleteFile(session,directory,fileName);
        System.out.println(flag);
    }
    @Test
    public void scpFrom() throws JSchException, FileNotFoundException {

        String source="/root/test/file1.txt";
        String destination ="D:\\tmp\\scfFrom.txt";
        long  filesize= JSchUtil.scpFrom(session,source,destination);
        System.out.println(filesize);
    }
    @Test
    public void scpTo() throws JSchException, FileNotFoundException {

        String filestr ="D:\\tmp\\test\\file_utils\\file1.txt";
        String destination="/root/test/file1.txt";
        long  filesize= JSchUtil.scpTo(session,filestr,destination);
        System.out.println(filesize);
    }

}

自己尝试一下吧,非常好的一个工具,更多功能可以去官网看例子

5.引用

http://www.jcraft.com/jsch/examples/

http://www.liuhaihua.cn/archives/710346.html

到此这篇关于Spring Boot集成JSch的示例代码的文章就介绍到这了,更多相关SpringBoot集成JSch内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • Java中的@RequiredArgsConstructor注解详解

    Java中的@RequiredArgsConstructor注解详解

    这篇文章主要介绍了Java中的@RequiredArgsConstructor注解详解,@RequiredArgsConstructor是Lombok的一个注解,简化了我们对@Autowired书写,@RequiredArgsConstructor注解可以代替@Autowired注解,需要的朋友可以参考下
    2024-01-01
  • Springboot+SpringSecurity+JWT实现用户登录和权限认证示例

    Springboot+SpringSecurity+JWT实现用户登录和权限认证示例

    这篇文章主要介绍了Springboot+SpringSecurity+JWT实现用户登录和权限认证示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • SpringBoot整合SpringCloud的过程详解

    SpringBoot整合SpringCloud的过程详解

    SpringCloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,在介绍SpringCloud默认使用的注册中心前,先给大家介绍下分布式系统的三个指标,具体内容详情跟随小编一起看看吧
    2021-09-09
  • JAVA使用commos-fileupload实现文件上传与下载实例解析

    JAVA使用commos-fileupload实现文件上传与下载实例解析

    这篇文章主要介绍了JAVA使用commos-fileupload实现文件上传与下载的相关资料,需要的朋友可以参考下
    2016-02-02
  • PageHelper分页查询操作方法示例

    PageHelper分页查询操作方法示例

    这篇文章主要为大家介绍了PageHelper分页查询数据操作方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • java中常用XML解析器的使用

    java中常用XML解析器的使用

    这篇文章主要介绍了java中常用XML解析器的使用的相关资料,需要的朋友可以参考下
    2023-02-02
  • java的IO流详细解读

    java的IO流详细解读

    这篇文章主要介绍了java的IO流详细解读,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • SpringCloud使用集中配置组件Config规避信息泄露

    SpringCloud使用集中配置组件Config规避信息泄露

    项目应用中,数据库连接信息、Access-key、Secret-key等由于其及其敏感和特殊性,一旦泄露出去就很可能会使得应用遭到黑客攻击,例如数据库账号密码泄露可能导致“拖库”,甚至数据丢失。此等事件偶有发生,那么,在分布式微服务项目中,怎么避免这种情况呢
    2022-07-07
  • Spring框架对于Bean的管理详解

    Spring框架对于Bean的管理详解

    在实际开发中,我们往往要用到Spring容器为我们提供的诸多资源,例如想要获取到容器中的配置、获取到容器中的Bean等等。本文为大家详细讲讲工具类如何获取到Spring容器中的Bean,需要的可以参考一下
    2022-07-07
  • Java class文件格式之属性详解_动力节点java学院整理

    Java class文件格式之属性详解_动力节点java学院整理

    这篇文章主要介绍了Java class文件格式之属性详解,需要的朋友可以参考下
    2017-06-06

最新评论

?


http://www.vxiaotou.com