遇到一个需要通过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(); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论