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