方法头部采用以下注解
@Async
@Transactional(rollbackFor = Exception.class)
public void handleImg(List<MultipartFile> userFile) {
// ...
}
以上写法遍历图片解析时,会出现 java.io.FileNotFoundException 异常情况。
本人解决方式思路记录:
1.将List<MultipartFile>数组对象遍历构建,采用临时文件形式存成本地临时文件对象。
// 构建本地临时File文件,后期保存完毕后,在删除临时文件
List<File> imgFileList = new ArrayList<>();
for (int i = 0; i < imgFile.length; i++)
imgFileList.add(FileUtil.createLocalFile(imgFile[i], false, null));
工具类提供:
/**
* @return 获取当前项目所在服务器位置
*/
public static String getLocalTemPath() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String savePath = request.getSession().getServletContext().getRealPath("");
int indexOf = savePath.lastIndexOf("\\");
if (indexOf == -1) { // Linux下临时路径获取, 即获取当前项目所在目录--相对路径
savePath = System.getProperty("user.dir");
} else { // 获取绝对路径
savePath = savePath.substring(0, savePath.lastIndexOf("\\"));
}
return savePath + "/";
}
/**
* @param file 文件信息
* @param rename 是否重命名标记
* @param dir 临时文件夹路径
* @return 本地文件生成
* @throws IOException
*/
public static File createLocalFile(MultipartFile file, boolean rename, String dir) throws IOException {
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
String url = getLocalTemPath() + (ObjectUtils.isEmpty(dir) ? "" : (dir + File.separator))
+ (rename ? (UUIDUtils.getUUID().substring(0, 18) + suffix) : file.getOriginalFilename());
File toFile = new File(url);
InputStream ins = file.getInputStream();
FileUtils.copyInputStreamToFile(ins, toFile);
if (ins != null)
ins.close();
return toFile;
}
再调用异步执行方法:
pom文件引用:(File文件转MultipartFile时使用)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>RELEASE</version>
</dependency>
@Async
@Transactional(rollbackFor = Exception.class)
public void handleImg(List<File> userFile) {
userFile.forEach(fileItem -> {
InputStream ins = null;
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(fileItem);
MultipartFile multipartFile = new MockMultipartFile(fileItem.getName(), fileItem.getName(),ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
ins = multipartFile.getInputStream();
// 根据流对象,在具体存到ftp上或者oss等地方,再根据项目逻辑数据存储等
// 关闭流,并删除本地临时文件
ins.close();
fileInputStream.close();
fileItem.delete();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ins != null) ins.close();
if (fileInputStream != null) {
fileInputStream.close();
if (fileItem.exists()) fileItem.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}