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();

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


相关文章
|
8月前
|
XML Java Maven
springboot-多环境配置文件
本文介绍了如何创建开发和生产环境的配置文件,并在IDEA和Maven中进行配置。开发环境中,通过设置profile为`dev`来指定配置文件;生产环境中,使用Maven命令参数`-Pprod`打包并指定配置文件。公共配置可放在`application.yml`中统一管理。日志配置需确保`logback-spring.xml`中的profile正确,以保证日志正常输出。
472 4
springboot-多环境配置文件
|
9月前
|
存储 前端开发 Java
Springboot静态资源映射及文件映射
在Spring Boot项目中,为了解决前端访问后端存储的图片问题,起初尝试通过静态资源映射实现,但发现这种方式仅能访问打包时已存在的文件。对于动态上传的图片(如头像),需采用资源映射配置,将特定路径映射到服务器上的文件夹,确保新上传的图片能即时访问。例如,通过`addResourceHandler(&quot;/img/**&quot;).addResourceLocations(&quot;file:E:\\myProject\\forum_server\\&quot;)`配置,使前端可通过URL直接访问图片。
527 0
Springboot静态资源映射及文件映射
|
8月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
Java 应用服务中间件
SpringBoot获取项目文件的绝对路径和相对路径
SpringBoot获取项目文件的绝对路径和相对路径
664 1
SpringBoot获取项目文件的绝对路径和相对路径
|
XML Java Kotlin
springboot + minio + kkfile实现文件预览
本文介绍了如何在容器中安装和启动kkfileviewer,并通过Spring Boot集成MinIO实现文件上传与预览功能。首先,通过下载kkfileviewer源码并构建Docker镜像来部署文件预览服务。接着,在Spring Boot项目中添加MinIO依赖,配置MinIO客户端,并实现文件上传与获取预览链接的接口。最后,通过测试验证文件上传和预览功能的正确性。
1189 4
springboot + minio + kkfile实现文件预览
|
网络协议 Java
springboot配置hosts文件
springboot配置hosts文件
191 11
|
存储 前端开发 JavaScript
|
Java
SpringBoot获取文件将要上传的IP地址
SpringBoot获取文件将要上传的IP地址
143 0
|
缓存 Java 程序员
Java|SpringBoot 项目开发时,让 FreeMarker 文件编辑后自动更新
在开发过程中,FreeMarker 文件编辑后,每次都需要重启应用才能看到效果,效率非常低下。通过一些配置后,可以让它们免重启自动更新。
272 0