问题描述
将打包好的war部署到linux服务器上,发现验证码部分一直显示不出来。后来看了日志:
22-May-2018 18:51:59.813 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1838 ms
java.io.IOException: An exception occurred processing [/headBar/makeCertPic.jsp] at line [73]
70: // 将认证码存入SESSION
71: session.setAttribute("certCode", sRand.toString());
72: g.dispose();
73: ImageIO.write(image, "JPEG", response.getOutputStream());
74: %>
Stacktrace:
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:472)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at filter.UserFilter.doFilter(UserFilter.kt:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:407)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.imageio.IIOException: Can't create output stream!
at javax.imageio.ImageIO.write(ImageIO.java:1574)
at org.apache.jsp.headBar.makeCertPic_jsp._jspService(makeCertPic_jsp.java:193)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
... 28 more
Caused by: javax.imageio.IIOException: Can't create cache file!
at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:423)
at javax.imageio.ImageIO.write(ImageIO.java:1572)
... 32 more
Caused by: java.nio.file.NoSuchFileException: /home/wangyu/Android/apache-tomcat-9.0.6/temp/imageio138834226394495527.tmp
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.createFile(Files.java:632)
at java.nio.file.TempFileHelper.create(TempFileHelper.java:138)
at java.nio.file.TempFileHelper.createTempFile(TempFileHelper.java:161)
at java.nio.file.Files.createTempFile(Files.java:897)
at javax.imageio.stream.FileCacheImageOutputStream.<init>(FileCacheImageOutputStream.java:88)
at com.sun.imageio.spi.OutputStreamImageOutputStreamSpi.createOutputStreamInstance(OutputStreamImageOutputStreamSpi.java:68)
at javax.imageio.ImageIO.createImageOutputStream(ImageIO.java:419)
... 33 more
解决方法
主要原因是因为ImageIO
需要默认需要有一个文件夹作为缓冲(默认是写入到tomcat/temp
文件夹下),而tomcat
默认是不会创建temp
文件夹的,所以需要我们手动创建temp
文件夹。
其他方法1
通过ImageIO.setCacheDirectory(cacheDirectory);
设置任意的、存在的缓存目录。
其他方法2
ImageIO默认是使用缓存目录,可以通过ImageIO.setUseCache(false)
来设置,更改缓存策略,不使用文件目录缓存,使用内存缓存。
其他方法3
不使用ImageIO,换成其它JDK方法。将ImageIO.write(bi, "jpg", os);
换成:
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
encoder.encode(image);