前言
SFTP相当于SSH + FTP,其中FTP则协议通常用来在两个服务器之间传输文件,但是它本质上是不安全的。SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。因此SFTP也就是安全的网络文件传输协议。
Jsch进行服务器连接时首先需要实例化一个jsch对象,再利用这个对象根据用户名,主机ip,端口获取一个Session对象,设置好相应的参数后,进行连接,创建连接后,这个session一直可用不需要关闭,之后我们需要在session上建立channel通道。
本文记录基于jcraft.jsch的文件传输工具与方法
依赖
基于springboot,mybatis-plus,PostgreSQL,jcraft.jsch
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.49</version>
</dependency>
ChannelSftp功能
ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:
put(): 文件上传
get(): 文件下载
cd(): 进入指定目录
ls(): 得到指定目录下的文件列表
rename(): 重命名指定文件或目录
rm(): 删除指定文件
mkdir(): 创建目录
rmdir(): 删除目录
JSch支持三种文件传输模式:
-
OVERWRITE
完全覆盖模式,这是JSch的默认文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。
-
RESUME
恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,则从上一次中断的地方续传。
-
APPEND
追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。
实现
JschUtil.java
我们定义JschUtil.java 的 ftp工具类,并定义方法
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.UUID;
/**
* JschUtil ftp(file transport protocol) 文件传输方法
* @author
* @since 2022-05-17
*/
@Slf4j
public class JschUtil {
/**
* ChannelSftp
*/
public static ChannelSftp channelSftp;
public static JSch jSch;
public static Session session;
public static Properties sshConfig;
public static Channel channel;
/**
* 建立ftp连接
* @param ftpAddress
* @param ftpPort
* @param ftpUsername
* @param ftpPassword
* @param ftpBasePath
* @return
* @throws IOException
*/
public static Boolean connect(String ftpAddress,
int ftpPort,
String ftpUsername,
String ftpPassword,
String ftpBasePath) throws IOException {
// 判断是否成功的boolean值
boolean success = false;
try {
// 创建JSch对象
jSch = new JSch();
// 调用JSch对象的getSession方法(参数是服务器的访问用户名,服务器访问路径,服务器的端口号)给session赋值
session = jSch.getSession(ftpUsername, ftpAddress, ftpPort);
// 给session对象设置密码参数也就是你的服务器访问的密码
session.setPassword(ftpPassword);
// 创建参数
sshConfig = new Properties();
// 给参数对象赋值,这里解决
sshConfig.put("StrictHostKeyChecking", "no");
// 这里设置参数给session主要解决把kerberos认证方式去掉,如果不写这一步走到这里你需要向控制台输入你的,kerberos用户名和口令,如果你的项目环境没有涉及到kerberos应该是不用设置
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
// 把参数对象给session对象注入
session.setConfig(sshConfig);
// 打开session连接
session.connect(15000);
// 使用session对象连接服务器
channel = session.openChannel("sftp");
channel.connect();
log.info("连接图片服务器:" + ftpAddress + " 连接用户名为:" + ftpUsername);
channelSftp = (ChannelSftp) channel;
// 使用ChannelSftp对象进行使用命令
// 进入需要进入的路径
channelSftp.cd(ftpBasePath);
// 设置上传成功
success = true;
} catch (JSchException | SftpException e) {
log.error(e.getMessage(), e);
e.printStackTrace();
}
return success;
}
/**
* 断开ftp连接
*/
public static void disConnect() {
if (channelSftp != null && channelSftp.isConnected()) {
channelSftp.disconnect();
log.info("断开channelSftp连接");
}
if (channel != null && channel.isConnected()) {
channel.disconnect();
log.info("断开channel连接");
}
if (session != null && session.isConnected()) {
session.disconnect();
log.info("断开session连接");
}
}
/**
* 重名文件检查与过滤
* 如果存在重名文件,将被重命名(加 _1, _2, ... 后缀)
* @param originalFileName 文件全名
* @return String
*/
public static String filterSameNameFile(String originalFileName) {
// 文件是否存在重名
Boolean repeat = JschUtil.isFileExist(originalFileName);
// 如果存在重名,则加(1)后缀
if (repeat) {
StringBuilder fileName = new StringBuilder();
int suffixNumber = 0;
String fileExtensionName = "";
// 分离文件拓展名(.jpg .png ... )
for (int i = originalFileName.length() - 1; i > 0; i--) {
if (originalFileName.charAt(i) == '.') {
fileExtensionName = originalFileName.substring(i, originalFileName.length());
fileName = new StringBuilder(originalFileName.substring(0, i));
break;
}
}
// 加_1后缀
fileName.append("_" + ++suffixNumber);
repeat = JschUtil.isFileExist(fileName.toString() + fileExtensionName);
// 如果已经存在 _1 后缀,则改为 _2 , _3 ,...直到文件名不重复为止
while (repeat) {
// 把我们添加的"_"后面所有数字字符删除
for (int length = fileName.length(); length > 0; length--) {
char c = fileName.charAt(length - 1);
if (c != '_') {
fileName.delete(length - 1, length);
}
else {
break;
}
}
// 在"_"后面添加suffixNumber
fileName.append(++suffixNumber);
// 文件名查重,repeat = false则退出循环
repeat = JschUtil.isFileExist(fileName.toString() + fileExtensionName);
}
// 合并扩展名后返回
fileName.append(fileExtensionName);
return fileName.toString();
}
// 不存在重名,直接返回
return originalFileName;
}
/**
* 判断文件或目录是否存在
* @param name 文件名
* @return boolean
*/
public static boolean isFileExist(String name) {
boolean isExist = false;
try {
channelSftp.lstat(name);
isExist = true;
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals(Constants.NOT_SUCH_FILE)) {
isExist = false;
}
}
return isExist;
}
/**
* 上传图片到ftp服务器,支持文件重名加后缀
* @param file 图片文件
* @param pathPrefix nginx图片服务器地址前缀
* @return String
* @throws IOException
*/
public static String ftpUpload(MultipartFile file, String pathPrefix, String fileName) throws IOException {
// 获取到文件的文件名
// String fileName = file.getOriginalFilename();
// 根据文件名 + UUID生产新的文件名
// String newFileName = UUID.randomUUID() + ".png";
String newFileName = fileName;
// 判断是否成功的boolean值
boolean success = false;
// 从MultipartFile对象中获取流
InputStream inputStream = file.getInputStream();
// 返回值为图片访问路径
String path = "";
try {
// 进行文件上传
channelSftp.put(inputStream, newFileName);
// 设置上传成功
success = true;
} catch (SftpException e) {
e.printStackTrace();
}
// 判断是否成功
if (success) {
// 设置返回路径为访问路径(你的服务器访问路径+新文件名)
path = pathPrefix + newFileName;
log.info("图片上传成功, 地址: " + path);
}
return path;
}
/**
* ftp下载方法
* @param fileName 文件名
* @param localPath 本地下载路径
* @return Boolean
* @throws IOException
*/
public static Boolean ftpDownload(String fileName, String localPath) throws IOException {
// 判断是否成功的boolean值
boolean success = false;
try {
// 进行文件下载
channelSftp.get(fileName, localPath);
// 设置上传成功
success = true;
} catch (SftpException e) {
e.printStackTrace();
}
// 判断是否成功
if (success){
log.info("图片 " + fileName + " 下载成功");
}
return success;
}
public static void main(String[] args) {
Boolean repeat = true;
String originalFileName = "1232121421412(0).jpg";
// 文件是否存在重名
StringBuilder fileName = new StringBuilder();
// 如果存在重名,则加(1)后缀
if (repeat) {
int suffixNumber = 0;
String fileExtensionName = "";
// 分离文件拓展名(.jpg .png ... )
for (int i = originalFileName.length() - 1; i > 0; i--) {
if (originalFileName.charAt(i) == '.') {
fileExtensionName = originalFileName.substring(i, originalFileName.length());
fileName = new StringBuilder(originalFileName.substring(0, i));
break;
}
}
// 加_1后缀
fileName.append("_" + ++suffixNumber);
// 如果已经存在 _1 后缀,则改为 _2 , _3 ,...直到不重复为止
while (repeat) {
// 把我们添加的"_"后面所有数字字符删除
for (int length = fileName.length(); length > 0; length--) {
char c = fileName.charAt(length - 1);
if (c != '_') {
fileName.delete(length - 1, length);
}
else {
break;
}
}
fileName.append(++suffixNumber);
// 假设_23时不再重复
if ("23".equals(fileName.substring(fileName.length() - 2, fileName.length()))) {
break;
}
}
// 合并扩展名后返回
fileName.append(fileExtensionName);
System.out.println(fileName);
}
}
}
ImageInfoService.java
图片上传下载接口定义
package org.sample.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.sample.common.request.PageRequest;
import org.sample.common.response.Response;
import org.sample.dao.entity.ImageInfo;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* 图片信息服务接口
* @author
* @since 2022-06-07
*/
public interface ImageInfoService extends IService<ImageInfo> {
Response saveImage(MultipartFile image, List<String> authorizedUsers);
Response saveImages(HttpServletRequest httpServletRequest, List<String> authorizedUsers);
Response imagesPagingPreview(PageRequest pageRequest);
Response updateImageInfo(String imageAddress, List<String> authorizedUsers);
Response downloadImage(String imageAddress, String downloadPath);
}
ImageInfoServiceImpl.java
图片传输接口实现类
package org.sample.service.Impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.sample.common.enums.IsDeletedEnum;
import org.sample.common.request.PageRequest;
import org.sample.common.response.PageResponse;
import org.sample.common.response.Response;
import org.sample.common.utils.EncrUtil;
import org.sample.common.utils.JschUtil;
import org.sample.common.utils.ResponseGenerator;
import org.sample.dao.entity.ImageInfo;
import org.sample.dao.mapper.ImageInfoServiceMapper;
import org.sample.service.ImageInfoService;
import org.sample.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.sample.common.utils.JschUtil.ftpDownload;
/**
* 图片信息服务实现类
* @author
* @since 2022-06-07
*/
@Slf4j
@Service
public class ImageInfoServiceImpl extends ServiceImpl<ImageInfoServiceMapper, ImageInfo> implements ImageInfoService {
/**
* 本地图片存放路径
*/
private static String UPLOAD_PATH = "File/Image";
/**
* ftp服务器ip地址
*/
@Value("${ftp.address}")
private String ftpAddress;
/**
* 端口号
*/
@Value("${ftp.port}")
private int ftpPort;
/**
* 用户名
*/
@Value("${ftp.username}")
private String ftpUsername;
/**
* 密码
*/
@Value("${ftp.password}")
private String ftpPassword;
/**
* 图片路径
*/
@Value("${ftp.basepath}")
public String ftpBasePath;
/**
* 访问路径
*/
@Value("${ftp.prefix}")
private String pathPrefix;
/**
* 图片下载次数
*/
@Value("${ftp.image.download.times}")
private Integer imageDownloadTimes;
@Autowired
private ImageInfoServiceMapper imageInfoServiceMapper;
@Autowired
private ImageInfoService imageInfoService;
@Autowired
private UserService userService;
/**
* 单个图片上传
* @param image 图片请求
* @param authorizedUsers 授权用户
* @return Response
*/
@Override
public Response saveImage(MultipartFile image, List<String> authorizedUsers) {
// 获取当前登录用户名
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = principal.getUsername();
// 检查输入的authorizedUsers是否存在
String notExistString = userService.isAuthorizedUsersExist(authorizedUsers);
if (notExistString.length() > 0) {
return ResponseGenerator.genFailResponse("输入的授权用户 " + notExistString + " 无效,请重新检查!");
}
List<String> paths = new ArrayList<>();
String path = "";
try {
log.info("用户: " + username + " 发起图片上传: " + image.getOriginalFilename());
// 连接服务器
JschUtil.connect(ftpAddress, ftpPort, ftpUsername, ftpPassword, ftpBasePath);
// 重名文件检查与过滤
String fileName = JschUtil.filterSameNameFile(image.getOriginalFilename());
// 上传,返回图片路径
path = JschUtil.ftpUpload(image, pathPrefix, fileName);
paths.add(path);
// 断开服务器
JschUtil.disConnect();
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
// 图片路径加密
String encryptPath = EncrUtil.encrypt(path);
// 图片信息存储
ImageInfo imageInfo = new ImageInfo();
imageInfo.setId(0L);
imageInfo.setImageAddress(encryptPath);
imageInfo.setImageOwner(username);
imageInfo.setAllowDownloadTimes(imageDownloadTimes);
// 若authorizedUsers非空,说明指定了授权用户,自动加入当前登录用户,并去重
if (!authorizedUsers.isEmpty()) {
authorizedUsers.add(username);
authorizedUsers = authorizedUsers.stream().distinct().collect(Collectors.toList());
}
imageInfo.setAuthorizedUser(authorizedUsers);
imageInfo.setIsDeleted(IsDeletedEnum.NO.getCode());
imageInfo.setCreateTime(new Timestamp(System.currentTimeMillis()));
imageInfo.setCreateUser(username);
imageInfo.setUpdateUser(username);
int insert = imageInfoServiceMapper.insert(imageInfo);
if (insert > 0) {
log.info("图片信息上传成功");
Response response = ResponseGenerator.genSuccessResponse(paths);
response.setMessage(response.getMessage() + " 上传成功!");
return response;
}
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
/**
* 单个/多个图片上传
* @param httpServletRequest 图片请求
* @param authorizedUsers 授权用户
* @return Response
*/
@Override
public Response saveImages(HttpServletRequest httpServletRequest, List<String> authorizedUsers) {
// 获取当前登录用户名
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = principal.getUsername();
// 检查输入的authorizedUsers是否存在
String notExistString = userService.isAuthorizedUsersExist(authorizedUsers);
if (notExistString.length() > 0) {
return ResponseGenerator.genFailResponse("输入的授权用户 " + notExistString + " 无效,请重新检查!");
}
// 提取图片序列
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) httpServletRequest;
Iterator<String> fileNames = multiRequest.getFileNames();
List<MultipartFile> multipartFiles = multiRequest.getFiles(fileNames.next());
List<String> paths = new ArrayList<>();
try {
log.info("用户: " + username + " 发起图片上传");
// 连接服务器
JschUtil.connect(ftpAddress, ftpPort, ftpUsername, ftpPassword, ftpBasePath);
// 循环上传
for (MultipartFile image : multipartFiles) {
String path = "";
// 重名文件检查与过滤
String fileName = JschUtil.filterSameNameFile(image.getOriginalFilename());
// 上传
path = JschUtil.ftpUpload(image, pathPrefix, fileName);
paths.add(path);
}
// 断开服务器
JschUtil.disConnect();
} catch (Exception e) {
log.error(e.getMessage(), e);
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
// 若authorizedUsers非空,说明指定了授权用户,自动加入当前登录用户,并去重
if (!authorizedUsers.isEmpty()) {
authorizedUsers.add(username);
authorizedUsers = authorizedUsers.stream().distinct().collect(Collectors.toList());
}
List<String> finalAuthorizedUsers = authorizedUsers;
// 构造 entityList,批量插入
List<ImageInfo> entityList = paths.stream().map(path -> {
ImageInfo imageInfo = new ImageInfo();
imageInfo.setImageAddress(EncrUtil.encrypt(path));
imageInfo.setImageOwner(username);
imageInfo.setAllowDownloadTimes(imageDownloadTimes);
imageInfo.setAuthorizedUser(finalAuthorizedUsers);
imageInfo.setIsDeleted(IsDeletedEnum.NO.getCode());
imageInfo.setCreateTime(new Timestamp(System.currentTimeMillis()));
imageInfo.setCreateUser(username);
imageInfo.setUpdateUser(username);
return imageInfo;
}).collect(Collectors.toList());
boolean insert = imageInfoService.saveBatch(entityList);
if (insert) {
log.info("图片信息上传成功");
Response response = ResponseGenerator.genSuccessResponse(paths);
response.setMessage(response.getMessage() + " 上传成功!");
return response;
}
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
/**
* 图片分页查询
* @param pageRequest 输入页码和页大小
* @return Response(PageResponse)
*/
@Override
public Response imagesPagingPreview(PageRequest pageRequest) {
// 获取当前登录用户名
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = principal.getUsername();
// 筛选username有预览权限的entity,并解码图片地址
List<ImageInfo> imageInfos = imageInfoServiceMapper.selectList(Wrappers.lambdaQuery(ImageInfo.class)
.eq(ImageInfo::getIsDeleted, IsDeletedEnum.NO.getCode())
);
List<ImageInfo> imageInfoList = imageInfos.stream()
.filter(new Predicate<ImageInfo>() {
// 筛选出权限用户
@Override
public boolean test(ImageInfo imageInfo) {
String[] stringAuthorizedUsers = (String[]) imageInfo.getAuthorizedUser();
if (stringAuthorizedUsers == null) {
return Boolean.TRUE;
}
List<String> authorizedUsers = Arrays.asList(stringAuthorizedUsers);
return authorizedUsers.isEmpty() || authorizedUsers.contains(username);
}
})
.map(imageInfo -> {
// 图片地址解码
imageInfo.setImageAddress(EncrUtil.decrypt(imageInfo.getImageAddress()));
return imageInfo;
}).collect(Collectors.toList());
PageResponse pageResponse = new PageResponse(imageInfoList, imageInfoList.size(), pageRequest.getPageSize(), pageRequest.getPageNo());
return ResponseGenerator.genSuccessResponse(pageResponse);
}
/**
* 更新图片信息(预览和下载权限人)
* @param imageAddress 图片地址
* @param authorizedUsers 授权用户
* @return Response
*/
@Override
public Response updateImageInfo(String imageAddress, List<String> authorizedUsers) {
// 获取当前登录用户名
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = principal.getUsername();
// 检查输入的authorizedUsers是否存在
String notExistString = userService.isAuthorizedUsersExist(authorizedUsers);
if (notExistString.length() > 0) {
return ResponseGenerator.genFailResponse("输入的授权用户 " + notExistString + " 无效,请重新检查!");
}
// 查询需要update的imageinfo
List<ImageInfo> imageInfos = imageInfoServiceMapper.selectList(Wrappers.lambdaQuery(ImageInfo.class)
.likeLeft(ImageInfo::getImageOwner, username)
.likeRight(ImageInfo::getImageOwner, username)
.likeLeft(ImageInfo::getImageAddress, EncrUtil.encrypt(imageAddress))
.likeRight(ImageInfo::getImageAddress, EncrUtil.encrypt(imageAddress))
.eq(ImageInfo::getIsDeleted, IsDeletedEnum.NO.getCode())
);
try {
// 如果没get到,则抛出异常
ImageInfo imageInfo = imageInfos.get(0);
// 若authorizedUsers非空,说明指定了授权用户,自动加入当前登录用户,并去重
if (!authorizedUsers.isEmpty()) {
authorizedUsers.add(username);
authorizedUsers = authorizedUsers.stream().distinct().collect(Collectors.toList());
}
imageInfo.setAuthorizedUser(authorizedUsers);
imageInfo.setUpdateTime(new Timestamp(System.currentTimeMillis()));
boolean update = imageInfoService.updateById(imageInfo);
if (update) {
log.info("用户: " + username + " 修改图片信息 " + imageAddress + " 修改成功");
return ResponseGenerator.genSuccessResponse(authorizedUsers);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
/**
* 单个图片下载
* @param imageAddress 图片在服务器地址(分页查询可得)
* @param downloadPath 下载的本地地址
* @return Response
*/
@Override
public Response downloadImage(String imageAddress, String downloadPath) {
// 获取当前登录用户名
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = principal.getUsername();
log.info("用户: " + username + " 发起图片下载: " + imageAddress);
// 可下载图片过滤,下载次数限制检查
List<ImageInfo> imageInfos = imageInfoServiceMapper.selectList(Wrappers.lambdaQuery(ImageInfo.class)
.likeLeft(ImageInfo::getImageAddress, EncrUtil.encrypt(imageAddress))
.likeRight(ImageInfo::getImageAddress, EncrUtil.encrypt(imageAddress))
.eq(ImageInfo::getIsDeleted, IsDeletedEnum.NO.getCode())
.gt(ImageInfo::getAllowDownloadTimes, 0)
);
// 如果imageInfos则为空,则图片已删除,或已经超过下载次数,直接返回!
if (imageInfos.isEmpty()) {
log.info("图片已被删除或超过规定下载次数!");
return ResponseGenerator.genFailResponse("图片已被删除或超过规定下载次数!");
}
// 下载授权人过滤
List<ImageInfo> imageInfoList = imageInfos.stream()
.filter(new Predicate<ImageInfo>() {
// 筛选出权限用户
@Override
public boolean test(ImageInfo imageInfo) {
String[] stringAuthorizedUsers = (String[]) imageInfo.getAuthorizedUser();
if (stringAuthorizedUsers == null) {
return Boolean.TRUE;
}
List<String> authorizedUsers = Arrays.asList(stringAuthorizedUsers);
return authorizedUsers.isEmpty() || authorizedUsers.contains(username);
}
}).collect(Collectors.toList());
// 如果过滤掉了,imageInfoList则为空,则用户没有预览和下载权限,直接返回!
if (imageInfoList.isEmpty()) {
log.info("用户: " + username + " 没有预览和下载权限!");
return ResponseGenerator.genFailResponse("用户没有预览和下载权限!");
}
// 提取图片名
String fileName = imageAddress.replaceAll(pathPrefix, "");
// 判断是否成功的boolean值
Boolean download = false;
try {
// 连接服务器
JschUtil.connect(ftpAddress, ftpPort, ftpUsername, ftpPassword, ftpBasePath);
// 下载图片到指定路径
download = JschUtil.ftpDownload(fileName, downloadPath);
// 断开服务器
JschUtil.disConnect();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
// 下载成功
if (download) {
// 修改下载次数: 下载次数 - 1
try {
ImageInfo imageInfo = imageInfoList.get(0);
imageInfo.setAllowDownloadTimes(imageInfo.getAllowDownloadTimes() - 1);
imageInfo.setUpdateTime(new Timestamp(System.currentTimeMillis()));
boolean update = imageInfoService.updateById(imageInfo);
if (update) {
log.info("用户: " + username + " 下载图片 " + fileName + " 一次");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
List<String> list = new ArrayList<>();
list.add(downloadPath + fileName);
Response response = ResponseGenerator.genSuccessResponse(list);
response.setMessage("下载成功!");
return response;
}
return ResponseGenerator.genFailResponse("网络错误!当前服务不可用,请尝试重试或联系客服");
}
}