快捷搜索:  汽车  科技

java调用shell脚本实现文件上传(Java操作Linux)

java调用shell脚本实现文件上传(Java操作Linux)

一、本项目核心目的

(目前支持.sql 和 .py脚本,.java脚本跟.py脚本大同小异,只是命令不同)

  • 1.从A服务器获取脚本文件
  • 2.上传到B服务器指定文件夹
  • 3.通过命令执行上传后得脚本文件
  • 4.返回执行结果
二、核心jar包

<!--sftp文件上传--> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency> <!--ssh执行--> <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency>三、Spring Boot 与 nacos 版本不对应时会报错,当前Spring Boot版本为2.3.9.RELEASE

java调用shell脚本实现文件上传(Java操作Linux)(1)

四、pom.xml 文件

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-config-spring-boot-starter</artifactId> <version>0.2.7</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.12.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-commons</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> <version>2.2.2.RELEASE</version> </dependency> <!--sftp文件上传--> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency> </dependencies>五、RemoteCommandConfig(服务器调用)

import ch.ethz.ssh2.Connection; import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @Slf4j @Component public class RemoteCommandConfig { /** * 只是用来测试,无其他用处 */ public static void main(String[] args) { Connection conn = login("这里填服务器IP地址" "账号" "密码"); JSONObject execute = execute(conn "cd /script/ &&mysql -vvv -uadmin -p123456 spring_data < 测试.sql"); System.out.println(execute.toString()); } private static String DEFAULTCHART = "UTF-8"; /** * @return 登录成功返回true,否则返回false * @描述 登录主机 */ public static Connection login(String ip String username String password) { boolean flg; Connection conn = null; try { conn = new Connection(ip); conn.connect();//连接 flg = conn.authenticateWithPassword(username password);//认证 if (flg) { return conn; } } catch (IOException e) { log.error("脚本执行登录服务器失败 error={}" e.getMessage()); e.printStackTrace(); } return conn; } /** * @param cmd 即将执行的命令 * @return 命令执行完后返回的结果值 * @描述 远程执行shll脚本或者命令 */ public static JSONObject execute(Connection conn String cmd) { JSONObject result = new JSONObject(); result.put("code" 200); String str = ""; try { if (conn != null) { session session = conn.openSession();//打开一个会话 session.execCommand(cmd);//执行命令 str = processStdout(session.getStdout() DEFAULTCHART); //如果为得到标准输出为空,说明脚本执行出错了 if (StringUtils.isBlank(str)) { result.put("code" 400); result.put("msg" "得到标准输出为空 链接conn:" conn " 执行的命令:" cmd); str = processStdout(session.getStderr() DEFAULTCHART); } else { result.put("msg" 200); result.put("msg" "执行命令成功 链接conn:" conn " 执行的命令:" cmd); } conn.close(); session.close(); } } catch (IOException e) { log.info("执行命令失败 链接conn:" conn " 执行的命令:" cmd " error={}" e.getMessage()); } result.put("data" str); return result; } /** * @param in 输入流对象 * @param charset 编码 * @return 以纯文本的格式返回 * @描述 解析脚本执行返回的结果集 */ private static String processStdout(InputStream in String charset) { InputStream stdout = new StreamGobbler(in); StringBuffer buffer = new StringBuffer(); try { BufferedReader br = new BufferedReader(new InputStreamReader(stdout charset)); String line; while ((line = br.readLine()) != null) { buffer.append(line "\n"); } } catch (Exception e) { log.error("解析脚本出错 error={}" e.getMessage()); e.printStackTrace(); } return buffer.toString(); }六、RestTemplateConfig防止项目因为RestTemplate启动失败

import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate(RestTemplateBuilder builder){ return builder.build(); } }七、ScriptDealWithController (方法整合)

import ch.ethz.ssh2.Connection; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.api.config.annotation.NacosValue; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.sd.config.RemoteCommandConfig; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.http.*; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.io.OutputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; //nacos实时动态参数获取 @RefreshScope @RestController @RequestMapping("/script") public class ScriptDealWithController { /** * 本项目所在服务器地址 */ @NacosValue(value = "${gyyh_login.ip}") private String gyyhIP;//登录获取ip @NacosValue(value = "${gyyh_login.username}") private String gyyhUsername;//系统账号 @NacosValue(value = "${gyyh_login.password}") private String gyyhPassword;//系统密码 /** * MySQL服务器地址 */ @NacosValue(value = "${mysql_script.ip}") private String myIp;//MySQL所在ip @NacosValue(value = "${mysql_script.username}") private String myUsername;//MySQL所在ip账号 @NacosValue(value = "${mysql_script.password}") private String myPassword;//MySQL所在ip密码 @NacosValue(value = "${mysql_script.command}") private String myCommand;//MySQL脚本执行命令 @NacosValue(value = "${mysql_script.file_path}") private String myFilePath;//文件保存路径 /** * pythonL服务器地址 */ @NacosValue(value = "${python_script.ip}") private String pyIp;//MySQL所在ip @NacosValue(value = "${python_script.username}") private String pyUsername;//MySQL所在ip账号 @NacosValue(value = "${python_script.password}") private String pyPassword;//MySQL所在ip密码 @NacosValue(value = "${python_script.command}") private String pyCommand;//MySQL脚本执行命令 @NacosValue(value = "${python_script.file_path}") private String pyFilePath;//文件保存路径 @Autowired private RestTemplate restTemplate; /** * @描述 获取平台登录token * @参数 [] * @返回值 java.lang.String * @创建时间 2021/7/23 */ public String getToken() { String url = gyyhIP "/获取token地址"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String String> params = new LinkedMultiValueMap<>(); params.add("username" gyyhUsername); params.add("password" gyyhPassword); HttpEntity<MultiValueMap<String String>> requestEntity = new HttpEntity<>(params headers); ResponseEntity<String> response = restTemplate.exchange(url HttpMethod.POST requestEntity String.class); JSONObject body = JSON.parseObject(response.getBody()); JSONObject data = body.getJSONObject("data"); if (CollectionUtils.isEmpty(data)) { throw new RuntimeException("token获取失败"); } return data.getString("token"); } /** * @描述 调用平台文件下载接口获取文件流 * @参数 [body] * @返回值 byte[] * @创建时间 2021/7/23 */ public byte[] download(String token String type String downloadId) { String url = gyyhIP "文件下载接口地址"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization" token); Map<String String> params = new HashMap<>(); params.put("type" type); params.put("downloadId" downloadId); HttpEntity<Map<String String>> requestEntity = new HttpEntity<>(params headers); ResponseEntity<byte[]> response = restTemplate.postForEntity(url requestEntity byte[].class); return response.getBody(); } /** * @描述 写入文件到指定目录下 * @参数 [bfile filePath fileName] * @返回值 void * @创建时间 2021/7/23 */ public void upload(byte[] bfile String ip String username String password String filePath String fileName) throws Exception { //服务器端口 默认22 int port = 22; Session session = null; Channel channel = null; JSch jsch = new JSch(); if (port <= 0) { //连接服务器,采用默认端口 session = jsch.getSession(username myIp); } else { //采用指定的端口连接服务器 session = jsch.getSession(username ip port); } //如果服务器连接不上,则抛出异常 if (session == null) { throw new Exception("session is null"); } //设置登陆主机的密码 session.setPassword(password);//设置密码 //设置第一次登陆的时候提示,可选值:(ask | yes | no) session.setConfig("StrictHostKeyChecking" "no"); //设置登陆超时时间 session.connect(30000); OutputStream outstream = null; try { //创建sftp通信通道 channel = session.openChannel("sftp"); channel.connect(1000); ChannelSftp sftp = (ChannelSftp) channel; //进入服务器指定的文件夹 sftp.cd(filePath); //以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换以下流就可以了 outstream = sftp.put(fileName); outstream.write(bfile); } catch (Exception e) { e.printStackTrace(); } finally { //关流操作 if (outstream != null) { outstream.flush(); outstream.close(); } if (session != null) { session.disconnect(); } if (channel != null) { channel.disconnect(); } } } /** * @描述 脚本执行 * @参数 [body] * @返回值 java.lang.String * @创建时间 2021/7/27 */ @PostMapping("/execute") public JSONObject execute(@RequestBody JSONObject body) throws Exception { String fileName = ""; String type = body.getString("type"); String downloadId = body.getString("downloadId"); //脚本类型 sql 、python String languageType = body.getString("languageType"); Connection conn = null; //执行脚本 String cmd = ""; //获取平台登录token String token = getToken(); //调用平台文件下载接口获取文件流 byte[] download = download(token type downloadId); if (StringUtils.equals("sql" languageType)) { cmd = myCommand; fileName = new Date().getTime() ".sql"; conn = RemoteCommandConfig.login(myIp myUsername myPassword); //写入文件到sql服务器指定目录下 upload(download myIp myUsername myPassword myFilePath fileName); } else if (StringUtils.equals("python" languageType)) { cmd = pyCommand; fileName = new Date().getTime() ".py"; conn = RemoteCommandConfig.login(pyIp pyUsername pyPassword); //写入文件到py服务器指定目录下 upload(download pyIp pyUsername pyPassword pyFilePath fileName); } //执行脚本 return RemoteCommandConfig.execute(conn cmd fileName); } } 八、启动类

import com.alibaba.nacos.api.config.ConfigType; import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @NacosPropertySource(dataId = "script_****" type = ConfigType.YAML groupId = "DEFAULT_GROUP" autoRefreshed = true) public class ScriptDealWithApplication { public static void main(String[] args) { SpringApplication.run(ScriptDealWithApplication.class args); } }九、application.yml配置

server: port: 8001 nacos: config: server-addr: 101.***.**.**:8848 #Nacos 链接地址 namespace: 55572fea-***-********************* #Nacos 命名空间ID 十、nacos配置

java调用shell脚本实现文件上传(Java操作Linux)(2)

java调用shell脚本实现文件上传(Java操作Linux)(3)

java调用shell脚本实现文件上传(Java操作Linux)(4)

gyyh_login: ip: http://101.***.***.***:8088/ username: admin password: 123456 mysql_script: ip: 192.168.**.*** username: root password: vagrant file_path: /usr/local/script/ command: cd /usr/local/script/ &&mysql -vvv -uroot -p123456 spring_data < python_script: ip: 192.168.**.*** username: root password: vagrant file_path: /usr/local/script/ command: python /usr/local/script/

猜您喜欢: