JavaSE ImageIO编写的验证码在linux上的tomcat显示不出来的问题解决

问题描述

  将打包好的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);

附录

猜你喜欢

转载自blog.csdn.net/Notzuonotdied/article/details/80410472