Spring boot临时文件目录报错
基本的错误信息如下:
1 2018-03-05 at 15:12:03 CST ERROR org.apache.juli.logging.DirectJDKLog 181 log - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.5697655521198317313.8080/work/Tomcat/localhost/ROOT] is not valid] with root cause java.io.IOException: The temporary upload location [/tmp/tomcat.5697655521198317313.8080/work/Tomcat/localhost/ROOT] is not valid 2 at org.apache.catalina.connector.Request.parseParts(Request.java:2846) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 3 at org.apache.catalina.connector.Request.parseParameters(Request.java:3215) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 4 at org.apache.catalina.connector.Request.getParameter(Request.java:1145) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 5 at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 6 at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 7 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 8 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 9 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 10 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 11 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 12 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 13 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 14 at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) ~[spring-boot-actuator-1.5.6.RELEASE.jar!/:1.5.6.RELEASE] 15 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar!/:4.3.10.RELEASE] 16 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 17 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar!/:8.5.16] 18 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 19 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 20 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 21 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 22 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 23 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 24 at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 25 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 26 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 27 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 28 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 29 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 30 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 31 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_151] 32 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_151] 33 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar!/:8.5.16] 34 at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151] 35 36 2018-03-05 at 15:15:00 CST INFO org.quartz.plugins.history.LoggingJobHistoryPlugin 469 jobToBeExecuted - Job default.HostsRetrieveJob_0 fired (by trigger default.HostsRetrieveJob_0) at: 15:15:00 03/05/2018 37 2018-03-05 at 15:15:00 CST INFO com.cmcc.cdn.platform.ops.quartz.jobs.HostsRetrieveJob 76 execute - Retrieve Hosts from cdn-cmdb 38 2018-03-05 at 15:15:00 CST INFO org.quartz.plugins.history.LoggingJobHistoryPlugin 513 jobWasExecuted - Job default.HostsRetrieveJob_0 execution complete at 15:15:00 03/05/2018 and reports: null 39
如果是线上问题暂时不方便修改代码最直接的解决方式就是手动创建这个报错的目录:[/tmp/tomcat.5697655521198317313.8080/work/Tomcat/localhost/ROOT]
这个问题的产生可能原因有很多,如:创建目录的权限问题,上传文件的大小限制配置问题…
[Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.3814974221022613431.8080/work/Tomcat/localhost/ROOT] is not valid] with root causejava.io.IOException: The temporary upload location [/tmp/tomcat.3814974221022613431.8080/work/Tomcat/localhost/ROOT] is not valid
原因:
1.spring boot的应用服务在启动的时候,会生成在操作系统的/tmp目录下生成一个Tomcat.*的文件目录,用于"java.io.tmpdir"文件流操作TomcatEmbeddedServletContainerFactory
2.程序对文件的操作时:会生成临时文件,暂存在临时文件中;lunix 系统的tmpwatch 命令会删除10天未使用的临时文件;长时间不操作,导致/tmp下面的tomcat临时文件目录被删除,且删除的文件不可恢复,上传文件时获取不到文件目录,报错
解决方案:
1.重启服务,临时方案:会重新生成tomcat目录,但是生产环境不建议如此操作;
2.1增加服务配置,自定义baseDir:
2.2启动时增加参数-Djava.io.tmpdir=自定义目录
3.修改tmpwatch 删除文件的逻辑,系统级别的命令,不建议操作
4.在网上看到有:编码的方式catch异常,生成删除的文件夹;(方法未验证)
在网上还查阅到较好的解决办法:
注入一个Bean,手动配置临时目录,代码基本如下:
1 /** 2 * 文件上传临时路径 3 */ 4 @Bean 5 MultipartConfigElement multipartConfigElement() { 6 MultipartConfigFactory factory = new MultipartConfigFactory(); 7 factory.setLocation("/app/pttms/tmp"); 8 return factory.createMultipartConfig(); 9 }
引用:awhip9