遇到一个需要通过java代码对远程Linux系统进行远程操作的场景,其中包括远程执行命令、上传文件、下载文件。
一、maven依赖
com.jcraftjsch0.1.53
二、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 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 0){ int i = in.read(tmp,0,1024); if(i 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(); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。