springboot 多线程使用MultipartFile读取excel文件内容报错问题

简介: springboot 多线程使用MultipartFile读取excel文件内容报错问题


springboot 多线程使用MultipartFile读取excel文件内容报错问题

springboot项目开启多线程

image.png

image.png

启动类加注解开启 @EnableAsync,实现类方法加注解 @Async

前端页面

image.png

报错信息

主线线程名称:http-nio-8051-exec-6
支线线程名称:threadPoolTaskExecutor-1
java.io.FileNotFoundException: C:\Users\dongao\AppData\Local\Temp\tomcat.1255209411477782290.8051\work\Tomcat\localhost\ROOT\upload_7d7b99e5_38da_4a03_93e0_bff20cb48022_00000000.tmp (系统找不到指定的文件。)
  at java.io.FileInputStream.open0(Native Method)
  at java.io.FileInputStream.open(FileInputStream.java:195)
  at java.io.FileInputStream.<init>(FileInputStream.java:138)
  at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getInputStream(DiskFileItem.java:194)
  at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100)
  at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getInputStream(StandardMultipartHttpServletRequest.java:250)
  at com.dongao.project.utils.UploadUtil.readExcel(UploadUtil.java:156)
  at com.dongao.project.utils.UploadUtil.readExcelToMap(UploadUtil.java:98)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl.importData(ImportBatchServiceImpl.java:161)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$FastClassBySpringCGLIB$$440ed2f6.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
  at com.dongao.support.cat.CatUtils.proceed(CatUtils.java:18)
  at com.dongao.support.cat.CatSpringAop.getObject(CatSpringAop.java:26)
  at com.dongao.support.cat.CatSpringAop.aroundServiceMethod(CatSpringAop.java:22)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$EnhancerBySpringCGLIB$$a16c4d4e.importData(<generated>)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$FastClassBySpringCGLIB$$440ed2f6.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
17:36:46.137 25472 [threadPoolTaskExecutor-1] INFO  com.ruoyi.framework.datasource.DynamicDataSourceContextHolder - [setDataSourceType,26] - 切换到SLAVE数据源
17:36:46.163 25472 [threadPoolTaskExecutor-1] ERROR org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler - [handleUncaughtException,39] - Unexpected exception occurred invoking async method: public void com.dongao.project.importbatch.service.ImportBatchServiceImpl.importData(org.springframework.web.multipart.MultipartFile,java.lang.Long) throws java.lang.Exception
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
  at java.util.ArrayList.rangeCheck(ArrayList.java:653)
  at java.util.ArrayList.get(ArrayList.java:429)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl.importData(ImportBatchServiceImpl.java:178)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$FastClassBySpringCGLIB$$440ed2f6.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
  at com.dongao.support.cat.CatUtils.proceed(CatUtils.java:18)
  at com.dongao.support.cat.CatSpringAop.getObject(CatSpringAop.java:26)
  at com.dongao.support.cat.CatSpringAop.aroundServiceMethod(CatSpringAop.java:22)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$EnhancerBySpringCGLIB$$a16c4d4e.importData(<generated>)
  at com.dongao.project.importbatch.service.ImportBatchServiceImpl$$FastClassBySpringCGLIB$$440ed2f6.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)


问题分析

前端页面传过来的文件会存在临时文件夹中,如下

C:\Users\dongao\AppData\Local\Temp\tomcat.1255209411477782290.8051\work\Tomcat\localhost\ROOT\


这个时候如果单线程操作,即正常程序流程解析是不会有问题的;

如果走异步多线程解析文件,主线程已经结束了,临时文件会被清空,这时候再来读取文件就会报错

java.io.FileNotFoundException: C:\Users\dongao\AppData\Local\Temp\tomcat.1255209411477782290.8051\work\Tomcat\localhost\ROOT\upload_7d7b99e5_38da_4a03_93e0_bff20cb48022_00000000.tmp (系统找不到指定的文件。)


问题处理

由于主线程结束,临时文件被清空,导致多线程业务类无法获取到临时文件而报错(系统找不到指定的文件。),此时可以在主线程中转换获取文件流信息

InputStream is = file.getInputStream();

文件流信息存储在内存中,多线程时也可以获取到文件内容,解决问题。


相关文章
|
4月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
422 5
|
7月前
|
Python
Excel中如何批量重命名工作表与将每个工作表导出到单独Excel文件
本文介绍了如何在Excel中使用VBA批量重命名工作表、根据单元格内容修改颜色,以及将工作表导出为独立文件的方法。同时提供了Python实现导出工作表的代码示例,适用于自动化处理Excel文档。
|
9月前
|
人工智能 算法 安全
使用CodeBuddy实现批量转换PPT、Excel、Word为PDF文件工具
通过 CodeBuddy 实现本地批量转换工具,让复杂的文档处理需求转化为 “需求描述→代码生成→一键运行” 的极简流程,真正实现 “技术为效率服务” 的目标。感兴趣的快来体验下把
496 10
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
3299 65
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
11月前
|
JavaScript 前端开发 Java
Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use;端口冲突的原理与解决方案
本文解决了Idea启动SpringBoot程序报错:Veb server failed to start. Port 8082 was already in use的问题,并通过介绍端口的使用原理和操作系统的端口管理机制,可以更有效地解决端口冲突问题,并确保Web服务器能够顺利启动和运行。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
12月前
|
文字识别 Serverless 开发工具
【全自动改PDF名】批量OCR识别提取PDF自定义指定区域内容保存到 Excel 以及根据PDF文件内容的标题来批量重命名
学校和教育机构常需处理成绩单、报名表等PDF文件。通过OCR技术,可自动提取学生信息并录入Excel,便于统计分析和存档管理。本文介绍使用阿里云服务实现批量OCR识别、内容提取、重命名及导出表格的完整步骤,包括开通相关服务、编写代码、部署函数计算和设置自动化触发器等。提供Python示例代码和详细操作指南,帮助用户高效处理PDF文件。 链接: - 百度网盘:[链接](https://pan.baidu.com/s/1mWsg7mDZq2pZ8xdKzdn5Hg?pwd=8866) - 腾讯网盘:[链接](https://share.weiyun.com/a77jklXK)
1800 5
|
Python
按条件将Excel文件拆分到不同的工作表
使用Python的pandas库,可以轻松将Excel文件按条件拆分到不同的工作表中。本文通过一个示例代码展示了如何生成一个包含总成绩表和三个班级表的Excel文件。代码首先创建了一个包含学生姓名、班级和各科成绩的数据框,然后按班级分组,将每个班级的数据分别写入不同的工作表。最后,生成的Excel文件将包含四个工作表,分别为总成绩表和三个班级的成绩表。
284 6
按条件将Excel文件拆分到不同的工作表
|
Python
批量将不同的工作簿合并到同一个Excel文件
本文介绍如何使用Python的`pandas`库批量合并不同工作簿至同一Excel文件。通过模拟生成三个班级的成绩数据,分别保存为Excel文件,再将这些文件合并成一个包含所有班级成绩的总成绩单。步骤包括安装必要库、生成数据、保存与合并工作簿。
415 6
|
Python
按条件将Excel文件拆分到不同的工作表
使用Python的pandas库,可以轻松将Excel文件按条件拆分为多个工作表。本文通过一个具体示例,展示了如何根据学生班级将成绩数据拆分到不同的工作表中,并生成一个包含总成绩表和各班级成绩表的Excel文件。代码简洁明了,适合初学者学习和应用。
470 6
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
289 1

热门文章

最新文章