java实现远程连接执行命令行与上传下载文件

 更新时间:2024年05月13日 09:57:41   作者:日常500  
这篇文章主要介绍了java实现远程连接执行命令行与上传下载文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

遇到一个需要通过java代码对远程Linux系统进行远程操作的场景,其中包括远程执行命令、上传文件、下载文件。

一、maven依赖

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

二、yml配置

desensitization:
  server:
    ip: xxx #IP地址
    user: root #登录用户名
    password: xxx #登录密码
    port: 22 #远程连接端口
    path: /root/test_data/ #对应处理的目录

三、配置类编写

import com.xxx.fileupload.exception.BizException;
import com.xxx.fileupload.exception.CommonUtilEnum;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @description: ssh远程连接配置类
 * @author ZXS
 * @date 2022/11/8 9:57
 * @version 1.0
 */
@Configuration
public class JSchSessionConfig {
    //指定的服务器地址
    @Value("${desensitization.server.ip}")
    private String ip;
    //用户名
    @Value("${desensitization.server.user}")
    private String user;
    //密码
    @Value("${desensitization.server.password}")
    private String password;
    //服务器端口 默认22
    @Value("${desensitization.server.port}")
    private String port;

    /**
     * @description: 注入一个bean,jsch.Session
     * @param:
     * @return: com.jcraft.jsch.Session
     * @author ZXS
     * @date: 2022/11/8 9:58
     */
    @Bean
    public Session registSession(){
        Session session;
        try {
            JSch jSch = new JSch();
            //设置session相关配置信息
            session = jSch.getSession(user, ip, Integer.valueOf(port));
            session.setPassword(password);
            //设置第一次登陆的时候提示,可选值:(ask | yes | no)
            session.setConfig("StrictHostKeyChecking", "no");
        } catch (JSchException e) {
            throw new BizException(CommonUtilEnum.FILE_DOWNLOAD_FAIL);
        }
        return session;
    }
}

四、组件工具类的编写

import com.xxx.fileupload.exception.BizException;
import com.xxx.fileupload.exception.CommonUtilEnum;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;

/**
 * @description: ssh远程连接工具类
 * @author ZXS
 * @date 2022/9/28 17:11
 * @version 1.0
 */
@Component
@Slf4j
public class SshRemoteComponent {
    private ThreadLocal<Session> connContainer = new ThreadLocal<>();
    @Resource
    private Session session;

    //上传文件到脱敏服务器的指定目录 自行修改
    @Value("${desensitization.server.path}")
    private String path;

    /**
     * @description: 根据端口号创建ssh远程连接
     * @param: port 端口号
     * @return: com.jcraft.jsch.Session
     * @author ZXS
     * @date: 2022/9/28 15:57
     */
    public Session createConnection(){
        try {
            session.connect(30000);
            connContainer.set(session);
        } catch (JSchException e) {
            throw new BizException(CommonUtilEnum.CONN_FAIL);
        }
        return connContainer.get();
    }

    /**
     * @description: 关闭ssh远程连接
     * @param:
     * @return: void
     * @author ZXS
     * @date: 2022/9/28 15:58
     */
    public void closeConnection(){
        Session session=connContainer.get();
        try {
            if(session != null){
                session.disconnect();
            }
        } catch (Exception e) {
            throw new BizException(CommonUtilEnum.CONN_CLOSE_FAIL);
        }finally {
            connContainer.remove();
        }
    }

    /**
     * @description: ssh通过sftp上传文件
     * @param: session,bytes文件字节流,fileName文件名,resultEncoding 返回结果的字符集编码
     * @return: java.lang.String 执行返回结果
     * @author ZXS
     * @date: 2022/9/30 10:02
     */
    public Boolean sshSftpUpload(Session session, byte[] bytes,String fileName) throws Exception{
        //上传文件到指定服务器的指定目录 自行修改
        //String path = "/root/test_data/";
        Channel channel = null;
        OutputStream outstream = null;
        Boolean flag = true;
        try {
            //创建sftp通信通道
            channel = session.openChannel("sftp");
            channel.connect(1000);
            ChannelSftp sftp = (ChannelSftp) channel;
            //进入服务器指定的文件夹
            sftp.cd(path);
            //列出服务器指定的文件列表
            /*Vector v = sftp.ls("*");
            for(int i=0;i<v.size();i++){
               System.out.println(v.get(i));
            }*/
            outstream = sftp.put(fileName);
            outstream.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        } finally {
            if(outstream != null){
                outstream.flush();
                outstream.close();
            }
            if(session != null){
                closeConnection();
            }
            if(channel != null){
                channel.disconnect();
            }
        }
        return flag;
    }

    /**
     * @description: ssh通过sftp下载文件
     * @param: session,fileName文件名,filePath 文件下载保存路径
     * @return: java.lang.String 执行返回结果
     * @author ZXS
     * @date: 2022/9/30 10:03
     */
    public Boolean sshSftpDownload(Session session, String fileName, String filePath) throws Exception{
        Channel channel = null;
        InputStream inputStream = null;
        FileOutputStream fileOutputStream;
        Boolean flag = true;
        try {
            //创建sftp通信通道
            channel = session.openChannel("sftp");
            channel.connect(1000);
            ChannelSftp sftp = (ChannelSftp) channel;
            //进入服务器指定的文件夹
            sftp.cd(path);
            inputStream = sftp.get(fileName);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            fileOutputStream = new FileOutputStream(filePath+"/"+fileName);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            byte[] buf = new byte[4096];
            int length = bufferedInputStream.read(buf);
            while (-1 != length){
                bufferedOutputStream.write(buf,0,length);
                length = bufferedInputStream.read(buf);
            }
            bufferedInputStream.close();
            bufferedOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        } finally {
            if(inputStream != null){
                inputStream.close();
            }
            if(session != null){
                closeConnection();
            }
            if(channel != null){
                channel.disconnect();
            }
        }
        return flag;
    }

    /**
     * @description: 远程执行单条Linux命令
     * @param: session,command命令字符串
     * @return: java.lang.String
     * @author ZXS
     * @date: 2022/9/28 16:34
     */
    public Boolean execCommand(Session session, String command){
        //默认方式,执行单句命令
        ChannelExec channelExec;
        Boolean flag = true;
        try {
            channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);
            channelExec.setErrStream(System.err);
            channelExec.connect();

            /** 判断执行结果 **/
            InputStream in = channelExec.getInputStream();
            byte[] tmp = new byte[1024];
            while(true){
                while(in.available() > 0){
                    int i = in.read(tmp,0,1024);
                    if(i < 0) break;
                    log.info("脚本执行过程:"+new String(tmp,0,i));
                }
                //获取执行结果
                if(channelExec.isClosed()){
                    if(in.available() > 0) continue;
                    if(channelExec.getExitStatus() != 0){
                        //脚本非正常结束,退出吗非零
                        flag = false;
                        log.info("脚本执行出错");
                    }
                    break;
                }
                try{
                    Thread.sleep(1000);
                }catch (Exception e){
                    log.info(e.getMessage());
                }
            }
            channelExec.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

五、使用测试

@SpringBootTest
@Slf4j
public class TestCase {
    @Resource
    private SshRemoteComponent component;
    @Test
    public void test(){
        Session session = component.createConnection();
        component.execCommand(session, "pwd");
        component.closeConnection();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Java操作MySQL实现数据交互的方法

    使用Java操作MySQL实现数据交互的方法

    JDBC是Java中用于操作数据库的API,可以为多种关系数据库提供统一访问,它通过JDK自带的JDBC API和数据库驱动包进行操作,实现数据库的增删改查,本文给大家介绍使用Java操作MySQL实现数据交互的方法,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • Java 多个文件生成zip包、下载zip包的实现代码

    Java 多个文件生成zip包、下载zip包的实现代码

    这篇文章主要介绍了Java 多个文件生成zip包、下载zip包,包括文件上传,文件下载,多个文件打成zip包的操作代码,本文给大家介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • JAVA8妙用Optional解决判断Null为空的问题方法

    JAVA8妙用Optional解决判断Null为空的问题方法

    本文主要介绍了JAVA8妙用Optional解决判断Null为空的问题方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Java中的包(package)是什么和使用方法

    Java中的包(package)是什么和使用方法

    包是Java中一种强大的组织代码的工具,它们帮助开发者将代码分组,防止命名冲突,并通过控制访问级别来增强代码的安全性,这篇文章主要介绍了Java中的包(package)是什么和如何使用它们,需要的朋友可以参考下
    2024-07-07
  • 如何获取jar包resources文件路径

    如何获取jar包resources文件路径

    java项目发布到jar之后找不到文件路径,遇到这样问题如何处理呢,下面小编给大家分享获取jar包resources文件路径的解决方法,感兴趣的朋友一起看看吧
    2023-12-12
  • Java多态概念、实现机制与实践应用详解

    Java多态概念、实现机制与实践应用详解

    多态是指同一个方法在不同对象上具有不同的行为,通过多态程序可以在运行时决定调用哪个方法,从而提高代码的灵活性和可扩展性,这篇文章主要介绍了Java多态概念、实现机制与实践应用的相关资料,需要的朋友可以参考下
    2026-01-01
  • SpringBoot获取配置文件的简单实现方法

    SpringBoot获取配置文件的简单实现方法

    这篇文章主要给大家介绍了关于SpringBoot如何获取配置文件的简单实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • SpringBoot多Profile配置的实现示例

    SpringBoot多Profile配置的实现示例

    在实际开发中,我们常常需要根据不同环境配置不同的参数,多Profile配置机制可以帮助我们按需加载配置文件,提升项目的可维护性和灵活性,感兴趣的可以了解一下
    2025-08-08
  • 教你在Spring Boot微服务中集成gRPC通讯的方法

    教你在Spring Boot微服务中集成gRPC通讯的方法

    这篇文章主要介绍了教你在Spring Boot微服务中集成gRPC通讯的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Spring boot中使用Spring-data-jpa方便快捷的访问数据库(推荐)

    Spring boot中使用Spring-data-jpa方便快捷的访问数据库(推荐)

    Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。这篇文章主要介绍了Spring-boot中使用Spring-data-jpa方便快捷的访问数据库,需要的朋友可以参考下
    2018-05-05

最新评论