javax异常: javax.imageio.IIOException: Can't create output stream解决方法

简介: javax异常: javax.imageio.IIOException: Can't create output stream解决方法


  • 验证码工具类:

 

1

packagecom.newcapec.utils;

2

3

importcom.sun.image.codec.jpeg.JPEGCodec;

4

importcom.sun.image.codec.jpeg.JPEGImageEncoder;

5

6

importjava.awt.*;

7

importjava.awt.image.BufferedImage;

8

importjava.io.FileOutputStream;

9

importjava.io.IOException;

10

importjava.io.OutputStream;

11

importjava.util.Random;

12

13

/**

14

* <p>Title: ValidateCode.java</p>  

15

* <p>Description: 验证码工具类</p>  

16

*/

17

publicclassValidateCode {    

18

   // 图片的宽度。  

19

   privateintwidth=120;  

20

   // 图片的高度。  

21

   privateintheight=40;  

22

   // 验证码字符个数  

23

   privateintcodeCount=4;  

24

   // 验证码干扰线数  

25

   privateintlineCount=30;  

26

   // 验证码  

27

   privateStringcode=null;  

28

   // 验证码图片Buffer  

29

   privateBufferedImagebuffImg=null;  

30

 

31

   privatechar[] codeSequence= { 'A','a', 'B','b', 'C','c', 'D','d', 'E','e', 'F','f', 'g','H','h',  

32

           'J','j', 'K','k','L', 'M','m', 'N','n', 'P','p', 'Q','q', 'R','r', 'S','s', 'T', 'U','u', 'V', 'W','w',  

33

           'X','x', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9'};  

34

 

35

   // 生成随机数  

36

   privateRandomrandom=newRandom();  

37

 

38

   publicValidateCode() {  

39

       this.createCode();  

40

   }  

41

 

42

   /**

43

    *  

44

    * @param width

45

    *            图片宽

46

    * @param height

47

    *            图片高

48

    */  

49

   publicValidateCode(intwidth, intheight) {  

50

       this.width=width;  

51

       this.height=height;  

52

       this.createCode();  

53

   }  

54

 

55

   /**

56

    *  

57

    * @param width

58

    *            图片宽

59

    * @param height

60

    *            图片高

61

    * @param codeCount

62

    *            字符个数

63

    * @param lineCount

64

    *            干扰线条数

65

    */  

66

   publicValidateCode(intwidth, intheight, intcodeCount, intlineCount) {  

67

       this.width=width;  

68

       this.height=height;  

69

       this.codeCount=codeCount;  

70

       this.lineCount=lineCount;  

71

       this.createCode();  

72

   }  

73

 

74

   publicvoidcreateCode() {  

75

       RandomheightRandom=newRandom();

76

       intcodeX=0;  

77

       intfontHeight=0;  

78

       fontHeight=height-heightRandom.nextInt(7)-7;// 字体的高度  

79

       codeX=width/ (codeCount+1);// 每个字符的宽度  

80

 

81

       // 图像buffer  

82

       buffImg=newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  

83

       Graphics2Dg=buffImg.createGraphics();  

84

 

85

       // 将图像填充为白色  

86

       g.setColor(Color.WHITE);  

87

       g.fillRect(0, 0, width, height);  

88

 

89

       // 创建字体  

90

       ImgFontByteimgFont=newImgFontByte();  

91

       Fontfont=imgFont.getFont(fontHeight);  

92

       g.setFont(font);  

93

 

94

       // 绘制干扰线  

95

       for (inti=0; i<lineCount; i++) {  

96

           intxs=getRandomNumber(width);  

97

           intys=getRandomNumber(height);  

98

           intxe=xs+getRandomNumber(width/8);  

99

           intye=ys+getRandomNumber(height/8);  

100

           g.setColor(getRandomColor());  

101

           g.drawLine(xs, ys, xe, ye);  

102

       }  

103

 

104

       

105

       StringBufferrandomCode=newStringBuffer();  

106

       

107

//        int x = 5;

108

       // 随机产生验证码字符  

109

       for (inti=0; i<codeCount; i++) {

110

           inth=height-8;

111

           intw= (i+1) *codeX+heightRandom.nextInt(4);

112

           StringstrRand=String.valueOf(codeSequence[random  

113

                   .nextInt(codeSequence.length)]);  

114

           // 设置字体颜色  

115

           g.setColor(getRandomColor());  

116

117

           intdegree=newRandom().nextInt() %10;

118

           g.rotate(degree*Math.PI/180,(w+codeX-5)/2, (h+fontHeight)/2);

119

           // 设置字体位置  

120

           g.drawString(strRand, w, h );  //getRandomNumber(height / 2) + 25

121

           g.rotate(-degree*Math.PI/150, (w+codeX-5)/2, (h+fontHeight)/2);

122

           randomCode.append(strRand);  

123

       }  

124

       code=randomCode.toString();  

125

   }  

126

 

127

   /** 获取随机颜色 */  

128

   privateColorgetRandomColor() {  

129

       intr=getRandomNumber(225);  

130

       intg=getRandomNumber(225);  

131

       intb=getRandomNumber(225);  

132

       returnnewColor(r, g, b);  

133

   }

134

 

135

   /** 获取随机数 */  

136

   privateintgetRandomNumber(intnumber) {  

137

       returnrandom.nextInt(number);  

138

   }  

139

 

140

   publicvoidwrite(Stringpath) throwsIOException {  

141

       OutputStreamsos=newFileOutputStream(path);  

142

       this.write(sos);  

143

   }  

144

 

145

   publicvoidwrite(OutputStreamsos) throwsIOException {  

146

//         ImageIO.write(buffImg, "png", sos);

147

       JPEGImageEncoderencoder=JPEGCodec.createJPEGEncoder(sos);

148

       encoder.encode(buffImg);

149

       sos.close();  

150

   }  

151

 

152

   publicBufferedImagegetBuffImg() {  

153

       returnbuffImg;  

154

   }  

155

 

156

   publicStringgetCode() {  

157

       returncode;  

158

   }  

159

 

160

   /** 字体样式类 */  

161

   classImgFontByte {

162

       publicFontgetFont(intfontHeight) {  

163

           returnnewFont("Arial", Font.PLAIN, fontHeight);

164

       }  

165

   }  

166

   

167

   

168

}

169


  • 使用

 

1

publicvoidscaptcha(){

2

       HttpServletResponseresponse=ServletActionContext.getResponse();

3

       response.reset();

4

       // 设置响应的类型格式为图片格式  

5

       response.setContentType("image/jpeg");  

6

       // 禁止图像缓存。  

7

       response.setHeader("Pragma", "no-cache");  

8

       response.setHeader("Cache-Control", "no-cache");  

9

       response.setDateHeader("Expires", 0);  

10

       ValidateCodeinstance=newValidateCode();

11

       CookieUtil.setCookie(response, "scaptcha", instance.getCode().toUpperCase(), null, -1);

12

       try {

13

           instance.write(response.getOutputStream());

14

       } catch (IOExceptione) {

15

           e.printStackTrace();

16

       }

17

   }



在使用ImageIO.write时,发现在Linux平台上,会出现异常:

 

1

javax.imageio.IIOException: Can't create output stream

 

1

检查tomcat的日志,终于真相大白:

2

3

javax.imageio.IIOException: Can't create output stream!

4

5

atjavax.imageio.ImageIO.write(ImageIO.java:1521)

6

7

Causedby: javax.imageio.IIOException: Can't create cache file!

8

9

atjavax.imageio.ImageIO.createImageOutputStream(ImageIO.java:395)

10

11

atjavax.imageio.ImageIO.write(ImageIO.java:1519)

12

13

... 34more

14

Causedby: java.io.IOException: 系统找不到指定的路径。

15

16

原来是ImageIO.write(image, "jpeg", response.getOutputStream());


查看日志,发现是由找不到文件引起

 

1

Java.nio.file.NoSuchFileException: xxx.../temp/imageio4138671232726624650.tmp


  • 主要原因如下:

在使用ImageIO进行图片写操作时,默认会使用缓存目录:${tomcat}/temp,在此缓存目录会生成缓存文件imageio4138671232726624650.tmp(这一串数字应该是当前时间戳,临时文件名),有些生产环境的tomcat,会将temp目录删除,因此报错


  • 4种解决方法如下:

  1. 在tomcat下新建temp目录;
  2. 与方法1相似,通过ImageIO.setCacheDirectory(cacheDirectory);设置任意的、存在的缓存目录
  3. ImageIO默认是使用缓存目录,可以通过ImageIO.setUseCache(false)来设置,更改缓存策略,不使用文件目录缓存,使用内存缓存
  4. 不使用ImageIO,换成其它JDK方法

 

1

ImageIO.write(bi, "jpg", baos);

2

换成:

3

JPEGImageEncoderencoder=JPEGCodec.createJPEGEncoder(response.getOutputStream());

4

encoder.encode(image);


相关文章
|
缓存 应用服务中间件 Apache
javax.imageio.IIOException: Can‘t create output stream!(验证码图片不显示)
javax.imageio.IIOException: Can‘t create output stream!(验证码图片不显示)
pip镜像源大全及配置
在中国使用pip时,可以配置国内镜像源来提高安装速度和稳定性。以下是一些常见的国内镜像源:
17048 0
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
17272 2
|
分布式计算 Java Linux
Java 生成 UUID
Java 生成 UUID
11142 1
|
SQL 关系型数据库 MySQL
MySQL执行SQL文件出现【Unknown collation ‘utf8mb4_0900_ai_ci‘】的解决方案
MySQL执行SQL文件出现【Unknown collation ‘utf8mb4_0900_ai_ci‘】的解决方案
MySQL执行SQL文件出现【Unknown collation ‘utf8mb4_0900_ai_ci‘】的解决方案
|
6月前
|
NoSQL Java Redis
springboot怎么使用Redisson
通过以上步骤,已经详细介绍了如何在Spring Boot项目中使用Redisson,包括添加依赖、配置Redisson、创建配置类以及使用Redisson实现分布式锁和分布式集合。Redisson提供了丰富的分布式数据结构和工具,可以帮助开发者更高效地实现分布式系统。通过合理使用这些工具,可以显著提高系统的性能和可靠性。
2168 34
|
网络安全
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://xxxx.svc.cluster.local:8080/xxxx": Connection reset; nested exception is java.net.SocketException: Connection reset 什么原因导致得
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "xxxx.svc.cluster.local:8080/xxxx ": Connection reset; nested exception is java.net.SocketException: Connection reset 什么原因导致得
4578 0
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
7070 118
|
9月前
|
IDE 开发工具
【开发IDE升级】如何对IDEA版本进行升级
本文介绍了如何将 IntelliJ IDEA Ultimate 从 2020.2.2 版本升级到 2022.3.2 版本。主要内容包括准备工作、卸载旧版本和安装新版本的步骤。首先,从官网下载所需版本并备份旧版配置;接着,通过 Uninstall.exe 卸载旧版,保留配置和插件;最后,安装新版并完成激活。详细的操作步骤和截图帮助用户顺利完成升级过程。
10808 1
【开发IDE升级】如何对IDEA版本进行升级
|
IDE Linux 开发工具
IntelliJ IDEA2022破解IDEA2022.2永久破解激活教程
IDEA 目前已经更新到最新的 2022.2.2 版本了,群里的小伙伴私聊问我,为啥之前 2021.3.1 的激活套路对新版本 2022.2.2 不管用了,是个什么情况? 很显然,IDEA 官方发现了这种破解路数,新版本加入了更严厉的反制破解。所以说,小伙伴们破解成功了以后,尽量不要升级 IDEA, 不然大概率又不行了。 好在z大又更新了新的补丁,针对最新版本,这边笔者亲测可行,仅以下文记录本人 IntelliJ IDEA 2022.2.2 版本的激活破解到 2099 年的全过程,步骤非常详细,跟着图文来就行~
63159 3
IntelliJ IDEA2022破解IDEA2022.2永久破解激活教程