1.controller类
@Tag(name = "读取配置文件")
@Schema(description = "读取配置文件")
@PostMapping("/file")
public OutputStream file(
@RequestBody @Validated UpdateConfigDto updateConfig, HttpServletResponse response) {
return manageClusterServer.readLinux(updateConfig, response);
}
2.server类
String user = updateConfigDto.getSshUser(); String host = updateConfigDto.getIp(); int port = updateConfigDto.getSshPort(); String dir = getDir(updateConfigDto); return FtpUtils.downLoad(user, host, port, dir, response);
3.sftp工具类
package com.skyable.deploy.utils;
import cn.hutool.core.io.IoUtil;
import com.jcraft.jsch.*;
import com.skyable.common.constants.exception.DeployExcpConstants;
import com.skyable.common.exceptions.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Properties;
/**
* @author laoYou
*/
@Slf4j
public class FtpUtils {
/** 超时时间 */
private static final String TIME_OUT = "6000";
/** sftp对象 */
private static ChannelSftp channelSftp = null;
/** 会话 */
private static Session session = null;
/**
* 判断ftp是否已连接
*
* @return
*/
public static boolean isOpen() {
try {
channelSftp = new ChannelSftp();
channelSftp.getServerVersion();
return true;
} catch (Exception e) {
return false;
}
}
/** ftp链接 */
public static void connectionFtp(String user, String ip, Integer port) {
try {
boolean open = isOpen();
if (!open) {
// 创建JSch对象
JSch jsch = new JSch();
String priKeyBasePath = "/root/.ssh/id_rsa";
jsch.addIdentity(priKeyBasePath);
// 通过 用户名,主机地址,端口 获取一个Session对象
session = jsch.getSession(user, ip, port);
// session.setPassword("root");
// 为Session对象设置properties
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// 设置超时时间
session.setTimeout(Integer.parseInt(TIME_OUT));
// 建立链接
session.connect();
// 打开SFTP通道
// 通道
Channel channel = session.openChannel("sftp");
// 建立SFTP通道的连接
channel.connect();
channelSftp = (ChannelSftp) channel;
}
} catch (Exception e) {
log.error("{}", e.getMessage());
}
}
public static void getInputStream(String uploadPath, InputStream inputStream, String fileName) {
try {
File files = new File("/home/test/d.conf");
FileUtils.copyInputStreamToFile(inputStream, files);
FileInputStream io = null;
try {
log.info("上传文件");
if (null == channelSftp || channelSftp.isClosed()) {
log.error("链接丢失");
throw new BusinessException(
DeployExcpConstants.ERROR_CODE_MANAGE_CONFIG_NO_SFTP,
DeployExcpConstants.ERROR_MSG_MANAGE_CONFIG_NO_SFTP);
}
if (isExistDir(uploadPath)) {
channelSftp.cd(uploadPath);
} else {
createDir(uploadPath, channelSftp);
}
io = new FileInputStream(files);
channelSftp.put(io, fileName);
log.info("上传文件");
} catch (Exception e) {
log.error("{}", e.getMessage());
} finally {
if (null != io) {
try {
io.close();
} catch (IOException e) {
e.printStackTrace();
}
}
disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 上传文件到 linux
*
* @param dir 上传文件地址
* @param file 本地文件地址
*/
public static void uploadFile(String dir, MultipartFile file) {
try {
File files = new File("/work/a.txt");
if (!files.exists()) {
files.createNewFile();
}
FileUtils.copyInputStreamToFile(file.getInputStream(), files);
FileInputStream io = null;
try {
if (null == channelSftp || channelSftp.isClosed()) {
throw new BusinessException(
DeployExcpConstants.ERROR_CODE_MANAGE_CONFIG_NO_SFTP,
DeployExcpConstants.ERROR_MSG_MANAGE_CONFIG_NO_SFTP);
}
io = new FileInputStream(files);
channelSftp.put(io, dir);
} catch (Exception e) {
log.error("{}", e.getMessage());
throw new BusinessException(
DeployExcpConstants.ERROR_CODE_MANAGE_CONFIG_NO_SFTP, e.getMessage());
} finally {
if (null != io) {
try {
io.close();
log.info("文件上传成功!!!");
files.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean isExistDir(String directory) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpAttrS = channelSftp.lstat(directory);
isDirExistFlag = true;
return sftpAttrS.isDir();
} catch (Exception e) {
if ("no such file".equals(e.getMessage().toLowerCase())) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
/**
* @param createpath 文件目录地址
*/
public static void createDir(String createpath, ChannelSftp sftp) throws Exception {
try {
String[] pathArry = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if ("".equals(path)) {
continue;
}
filePath.append(path).append("/");
if (isExistDir(filePath.toString())) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
channelSftp.cd(createpath);
} catch (SftpException e) {
log.error("创建目录失败,{}", e.getMessage());
}
}
/** 关闭ftp */
public static void disconnect() {
if (channelSftp.isConnected()) {
session.disconnect();
channelSftp.disconnect();
}
}
/**
* 从linux下载文件
*
* @param user
* @param host
* @param port
* @param dir
*/
public static OutputStream downLoad(
String user, String host, Integer port, String dir, HttpServletResponse response) {
try {
JSch jsch = new JSch();
String priKeyBasePath = "/root/.ssh/id_rsa";
jsch.addIdentity(priKeyBasePath);
Session session = jsch.getSession(user, host, port);
// 避免SSH 的公钥检查
session.setConfig("StrictHostKeyChecking", "no");
//session.setPassword("");
session.connect();
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
InputStream inputStream = sftpChannel.get(dir);
OutputStream outPutStream = response.getOutputStream();
// 直接传给前端
outPutStream.write(IoUtil.readBytes(inputStream));
outPutStream.flush();
outPutStream.close();
return outPutStream;
} catch (JSchException | SftpException | IOException e) {
e.printStackTrace();
}
disconnect();
return null;
}
}
1.controller类
实体类与文件一块传参
@Tag(name = "上传配置file")
@Schema(description = "上传配置file")
@PostMapping("/update/file")
public ResponseResult> updateFiles(
@RequestParam(value = "dtoJson") String updateConfigDto,
@RequestParam(value = "file") MultipartFile file,
HttpServletRequest request,
HttpServletResponse response) {
Gson gson = new Gson();
UpdateConfigDto configDto = gson.fromJson(updateConfigDto, UpdateConfigDto.class);
return manageClusterServer.updateFile(configDto, request, file, response);
}
2.server类
@Override
public ResponseResult> updateFile(
UpdateConfigDto configDto,
HttpServletRequest request,
MultipartFile file,
HttpServletResponse response) {
String user = configDto.getSshUser();
String ip = configDto.getIp();
Integer port = configDto.getSshPort();
String dir = getDir(configDto);
try {
FtpUtils.connectionFtp(user, ip, port);
FtpUtils.uploadFile(dir, file);
} catch (Exception e) {
return ResponseResult.error(
DeployExcpConstants.ERROR_CODE_MANAGE_CONFIG_FILE,
DeployExcpConstants.ERROR_MSG_MANAGE_CONFIG_FILE);
}
return ResponseResult.success();
}
配置文件增加Tomcat的文件限制
server:
port: 8099
tomcat:
max-swallow-size: 5GB
spring:
application:
name: cloud-deploy
servlet:
multipart:
max-file-size: -1 # 设置单个文件的大小为5GB
max-request-size: -1 # 设置总上传的数据大小为50GB