<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
package com.cepo.blackbird.util;
import com.jcraft.jsch.*;
import javax.swing.text.html.parser.Entity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* @author :zjt
* @date :Created in 2019/8/15 0015 16:19
* @description :用于管理与服务器的连接,和执行命令
*/
public class ShellUtil {
private static final Map<String,ShellSession> SHELL_SESSION_MAP = new HashMap<>();//sessionMap
private static final JSch jsch = new JSch();//session构造器
private static final Integer TIME_OUT_HOUR = 1;//超时时间
private static final Integer DEFAULT_PORT = 22;//默认连接端口
private static final String DEFAULT_CHANNEL_TYPE = "exec"; //默认类别
public static final String shellCommand(final String address,final String username,final String password,final String command){
return ShellUtil.shellCommand(address, username, password, ShellUtil.DEFAULT_CHANNEL_TYPE,command);
}
public static final String shellCommand(final String address,final String username,final String password,final String channelType,final String command){
return ShellUtil.shellCommand(address, username, password,ShellUtil.DEFAULT_PORT, channelType,command);
}
/**
* @Description
* 1、判断连接是否长时间未使用,超出时间则删除
* 2、通过指定服务器ip 用户名密码 连接端口号 调用内部类ShellSession的execute方法执行channelType类别的command
* @param address
* @param username
* @param password
* @param port
* @param channelType
* @param command
* @return java.lang.String
* @author zjt
* @Date 2019/8/16 0016 11:16
*/
public static final String shellCommand(final String address,final String username,final String password,final Integer port,final String channelType,final String command){
if (!ShellUtil.checkNotNull(address,username,password,port,channelType,command))
throw new NullPointerException("params cannot be null");
if (!ShellUtil.SHELL_SESSION_MAP.containsKey(address+":"+username))
ShellUtil.SHELL_SESSION_MAP.put(address + ":" + username, new ShellUtil.ShellSession(address, username, password, port));
ShellSession shellSession = ShellUtil.SHELL_SESSION_MAP.get(address+":"+username);
shellSession.updateLastExecTime();//更新操作时间
//清除超时session实例
ShellUtil.SHELL_SESSION_MAP.entrySet().removeIf(
entry -> entry.getValue().lastExecTime.getTime()+ShellUtil.TIME_OUT_HOUR*60*60*1000 < System.currentTimeMillis()
);
return shellSession==null?null:shellSession.execute(channelType, command);
}
private static final Boolean checkNotNull(Object... objects){
if (objects==null)
return false;
for (Object obj:objects){
if(obj == null)
return false;
}
return true;
}
/**
* @Description 连接实例类
* @author zjt
* @Date 2019/8/16 11:10
*/
static class ShellSession{
Session session;
Date lastExecTime;
/**
* @Description 创建连接
* @param address
* @param username
* @param password
* @param port
* @author zjt
* @Date 2019/8/16 0016 11:19
*/
private ShellSession(String address, String username, String password, Integer port) {
try {
session = ShellUtil.jsch.getSession(username, address, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");//去掉连接确认的
session.connect(30000);
} catch (JSchException e) {
e.printStackTrace();
}
}
private void updateLastExecTime(){
lastExecTime = Calendar.getInstance().getTime();
}
/**
* @Description 执行命令
* @param channelType
* @param command
* @return java.lang.String
* @author zjt
* @Date 2019/8/16 0016 11:20
*/
private String execute(String channelType,String command){
if (this.session==null)
return null;
Channel channel = null;
//InputStream input = null;
BufferedReader input = null;
String resp = "";
try {
channel = this.session.openChannel(channelType);
((ChannelExec) channel).setCommand(command);
input = new BufferedReader(new InputStreamReader(channel.getInputStream()));
channel.connect();
String line;
while ((line = input.readLine()) != null) {
resp+=line+"\n";
}
if (resp!=null&&!resp.equals(""))
resp = resp.substring(0, resp.length()-1);
System.out.println(resp);
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input!=null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (channel!=null){
channel.disconnect();
}
}
return resp;
}
}
}
@Test
public void testExecCommand(){
ShellUtil.shellCommand("你的服务器ip","你的服务器用户名", "你的服务器密码", "执行的命令,这里测试执行的是ls /");
}
控制台输出:
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
Process finished with exit code 0
测试成功
注意: 这种方式调用服务器命令的方式,服务器报错会被吞掉,看不到报错,原因暂时不明。