Springboot 封装ssh 服务

前提条件:Linux 已经启动SSH 服务或Windows 启动SSH 服务。

整体项目结构:

第一步:BuleSky 的pom.xml 文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.zzg</groupId>
	<artifactId>BuleSky</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>

	<!--springboot 父类 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.0.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<!--springboot 依赖web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--springboot 依赖test -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<!--springboot 依赖devtool -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!--lombak 集成 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.0</version>
		</dependency>
		<!--apache common 工具包 -->
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
			<version>3.6</version>
		</dependency>
		 <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>
	</dependencies>
	<modules>
		<module>common-ssh</module>
		<module>common-ftp</module>
		<module>common-fastdfs</module>
		<module>common-monitor-windows</module>
		<module>common-monitor_linux</module>
		<module>common-elasticsearch</module>
	</modules>
</project>

common-ssh 项目结构:

common-ssh 的pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.zzg</groupId>
    <artifactId>BuleSky</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>common-ssh</artifactId>
  
  <!--依赖远程ssh 框架 -->
  <dependencies>
  		<dependency>
    		<groupId>com.jcraft</groupId>
    		<artifactId>jsch</artifactId>
    		<version>0.1.55</version>
		</dependency>
  </dependencies>
</project>

Application.java

package com.zzg.common;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SpringApplication.run(Application.class, args);
	}

}

SSHConfig.java

package com.zzg.common.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import lombok.Data;

/**
 * 远程服务器ssh 配置对象
 * @author zzg
 *
 */
@Configuration
@PropertySource(value = "classpath:ssh.properties")
@ConfigurationProperties(prefix = "ssh.remote")
@Data
public class SSHConfig {
	private String ip;
	private String username;
	private String password;
	private int port;
	private boolean isCheck;
}

SSHConstant.java

package com.zzg.common.constant;

public class SSHConstant {
	// Linux 系统
	public static final String SHELL = "shell";
	// Windows 系统
	public static final String EXEC = "exec";
	
}

SSHEntity.java

package com.zzg.common.entity;

import lombok.Data;

@Data
public class SSHEntity {
	private String ip;
	private String username;
	private String password;
	private int port;
	private boolean isCheck;
}

CustomerUser.java

package com.zzg.common.user;

import com.jcraft.jsch.UserInfo;

public class CustomerUser implements UserInfo {

	@Override
	public String getPassphrase() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getPassword() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean promptPassphrase(String arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean promptPassword(String arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	// 消息通知
	@Override
	public boolean promptYesNo(String arg0) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public void showMessage(String arg0) {
		// TODO Auto-generated method stub

	}

}

SSHActuator.java

package com.zzg.common.util;

import com.jcraft.jsch.*;

import java.io.*;
import java.util.concurrent.TimeUnit;

import static java.lang.String.format;

import com.zzg.common.config.SSHConfig;
import com.zzg.common.constant.SSHConstant;
import com.zzg.common.entity.SSHEntity;
import com.zzg.common.user.CustomerUser;

import lombok.extern.slf4j.Slf4j;

/**
 * ssh 远程连接服务器
 * @author zzg
 *
 */
@Slf4j
public class SSHActuator {
	private static int SESSION_TIMEOUT = 30000;
	private static int CHANNEL_TIMEOUT = 3000;
	private static int INTERVAL = 100;
	
	private JSch jsch = null;
	private Session session = null;
	
	//私有构造函数
	private SSHActuator(SSHEntity entity){
		try{
			jsch =new JSch();
	        session = jsch.getSession(entity.getUsername(),entity.getIp(),entity.getPort());
	        session.setPassword(entity.getPassword());
	        session.setUserInfo(new CustomerUser());
	        session.connect(SESSION_TIMEOUT);
		}catch(JSchException e){
			log.error(e.getMessage());
			System.out.println(e.getMessage());
		}
		
	}
	
	// 单列模式
	public static SSHActuator getInstance(SSHEntity entity) throws JSchException {
		return new SSHActuator(entity);
	}
	
	// 获取连接会话
	public Session getSession(){
        return session;
    }

	// 关闭连接会话
    public void close(){
        getSession().disconnect();
    }
    
    // 执行shell 脚本
    public long shell(String cmd, String outputFileName) throws JSchException, IOException, InterruptedException {
        long start = System.currentTimeMillis();
        Channel channel = session.openChannel(SSHConstant.SHELL);
        PipedInputStream pipeIn = new PipedInputStream();
        PipedOutputStream pipeOut = new PipedOutputStream( pipeIn );
        FileOutputStream fileOut = new FileOutputStream( outputFileName, true);
        channel.setInputStream(pipeIn);
        channel.setOutputStream(fileOut);
        channel.connect(CHANNEL_TIMEOUT);

        pipeOut.write(cmd.getBytes());
        Thread.sleep( INTERVAL );
        pipeOut.close();
        pipeIn.close();
        fileOut.close();
        channel.disconnect();
        return System.currentTimeMillis() - start;
    }
    
    // 执行exec 脚本
    public int exec(String cmd) throws IOException, JSchException, InterruptedException {
        ChannelExec channelExec = (ChannelExec)session.openChannel(SSHConstant.EXEC);
        channelExec.setCommand( cmd );
        channelExec.setInputStream( null );
        channelExec.setErrStream( System.err );
        InputStream in = channelExec.getInputStream();
        channelExec.connect();

        int res = -1;
        StringBuffer buf = new StringBuffer( 1024 );
        byte[] tmp = new byte[ 1024 ];
        while ( true ) {
            while ( in.available() > 0 ) {
                int i = in.read( tmp, 0, 1024 );
                if ( i < 0 ) break;
                buf.append( new String( tmp, 0, i ) );
            }
            if ( channelExec.isClosed() ) {
                res = channelExec.getExitStatus();
                System.out.println( format( "Exit-status: %d", res ) );
                break;
            }
            TimeUnit.MILLISECONDS.sleep(INTERVAL);
        }
        System.out.println( buf.toString() );
        channelExec.disconnect();
        return res;
    }
}

ssh.properties(ssh 配置参数)

#linux setting
# ssh.remote.ip:192.168.60.178
#windows setting
ssh.remote.ip:192.168.1.74
ssh.remote.username:root
ssh.remote.password:123456
ssh.remote.port:22
ssh.remote.isCheck:false

SSHTest.java(ssh 功能测试)

package com.zzg.common.ssh.test;

import java.io.IOException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.jcraft.jsch.JSchException;
import com.zzg.common.config.SSHConfig;
import com.zzg.common.entity.SSHEntity;
import com.zzg.common.util.SSHActuator;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SSHTest {
	@Autowired
	private SSHConfig config;
	
	@Test
	public void ssh(){
		SSHEntity entity = new SSHEntity();
		entity.setIp(config.getIp());
		entity.setUsername(config.getUsername());
		entity.setPassword(config.getPassword());
		entity.setPort(config.getPort());
		try {
			SSHActuator ssh = SSHActuator.getInstance(entity);
			System.out.println("================");
	        long shell1 = ssh.shell("ls\n","C:\\Users\\zzg\\Desktop\\shell.txt");
	        long shell2 = ssh.shell("pwd\n","C:\\Users\\zzg\\Desktop\\shell.txt");
	        System.out.println("shell 1 执行了"+shell1+"ms");
	        System.out.println("shell 2 执行了"+shell2+"ms");
	        System.out.println("================");
	        ssh.close();
		} catch (JSchException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Test
	public void cmd(){
		SSHEntity entity = new SSHEntity();
		entity.setIp(config.getIp());
		entity.setUsername(config.getUsername());
		entity.setPassword(config.getPassword());
		entity.setPort(config.getPort());
		try {
			SSHActuator ssh = SSHActuator.getInstance(entity);
			System.out.println("================");
	        long shell1 = ssh.shell("ipconfig\n","C:\\Users\\zzg\\Desktop\\shell.txt");
	        long shell2 = ssh.shell("ipconfig\n","C:\\Users\\zzg\\Desktop\\shell.txt");
	        System.out.println("shell 1 执行了"+shell1+"ms");
	        System.out.println("shell 2 执行了"+shell2+"ms");
	        System.out.println("================");
	        ssh.close();
		} catch (JSchException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
}

猜你喜欢

转载自blog.csdn.net/zhouzhiwengang/article/details/88639453