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();
		}
	}
	
	
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SpringBoot封装Starter是一种方便的方式,可以将一些通用的配置和功能封装成一个可复用的模块,以供其他项目使用。通过引用和的内容,我们可以了解到封装自己的Starter主要需要进行以下几个步骤: 1. 创建一个普通的Java项目,作为Starter的源代码根目录。 2. 在项目的pom.xml文件中添加必要的依赖,例如Spring Boot相关的依赖。 3. 在项目的src/main/resources目录下创建META-INF目录,并在其中创建一个名为spring.factories的文件。在该文件中,配置Starter的自动配置类,如com.example.myspringbootstarter.MyServiceAutoConfiguration。这样Spring Boot在启动时会自动加载该自动配置类。 4. 在Starter项目中实现需要封装的功能和配置,可以包括自定义的Bean、配置类、自动配置类等。 5. 将封装好的Starter项目打包,并发布到Maven仓库供其他项目使用。 通过引用的内容,我们还可以了解到在使用封装好的Starter时,需要在项目的pom.xml文件中添加对Starter的依赖。例如,使用groupId为com.example,artifactId为my-spring-boot-starter的Starter,并指定版本号为0.0.1-SNAPSHOT。 综上所述,SpringBoot封装Starter是一种将通用功能和配置封装成可复用模块的方式,方便项目开发和维护。通过合理配置和使用Starter,可以提高开发效率并降低项目的复杂性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringBoot封装自己的Starter的实现方法](https://download.csdn.net/download/weixin_38705252/12749617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringBoot封装自己的starter](https://blog.csdn.net/ldllovegyh/article/details/124861446)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值