1.问题描述:
在日常练习的时候遇见的错误,虽然页面可以顺利显示,但后台报错:(虽然不影响导出效果,但看到后台的异常,内心还是不舒服的)
java.lang.IllegalStateException: getOutputStream() has already been called for this response
从字义上分析:getOutputStream()已经调用了这个响应,就是重复被调用引起的异常。
2.问题分析:
在tomcat下jsp出现该错误一般都是在使用了输出流(如输出图片验证码,文件下载等)。
产生这样的异常原因:是web容器生成的servlet代码中有out.write(""),这个和JSP中调用的response.getOutputStream()产生冲突。即Servlet规范说明,不能既调用response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,在调用第二个时候应会抛出IllegalStateException,因为在jsp中,out变量实际上是通过response.getWriter得到的,你的程序中既用了response.getOutputStream,又用了out变量,故出现以上错误。
3.解决方案:
在调用 response.getOutputStream()之前,清空缓存的内容,并返回一个新的BodyContext,更新PageContext的out属性的内容。
1 <body> 2 <% 3 BufferedImage imageBI=new BufferedImage(340,160,BufferedImage.TYPE_INT_RGB); 4 Graphics g=imageBI.getGraphics(); 5 g.fillRect(0, 0, 400, 400); 6 g.setColor(new Color(255,0,0)); 7 g.fillArc(20, 20, 100, 100, 30, 120); 8 g.setColor(new Color(0,255,0)); 9 g.fillArc(20, 20, 100, 100, 150, 120); 10 g.setColor(new Color(0,0,255)); 11 g.fillArc(20, 20, 100, 100, 270, 120); 12 g.setColor(new Color(0,0,0)); 13 g.setFont(new Font("Arial Black",Font.PLAIN,16)); 14 15 g.drawString("red:climb",200,60); 16 g.drawString("green:swim", 200, 100); 17 g.drawString("blue:jump",200,140); 18 g.dispose(); 19 out.clear(); //清空缓存的内容 20 out=pageContext.pushBody(); //更新PageContext的out属性的内容 21 ImageIO.write(imageBI, "jpg", response.getOutputStream()); 22 %> 23 </body>
4.扩展
上面代码,根本没有用到out,为什么可以调用out.clear和pageContext ? 因为这都是JSP的内置对象,可以随时使用。
JSP九大内置对象(在JSP页面上可直接使用,html页面不能用):
4.1 page:一个jsp就是一个servlet类,就是一个java类,java类的this对象,对应JSP的page对象;
4.2 pageContext :当前页对象
4.3 application:上下文对象
4.4 config :servlet生命周期 1.初始化
4.5 request:请求。servlet生命周期 2.service方法:请求,响应
4.6 response:响应
4.7 session:请求对应session,有了request就可以得到session,session=request.getSession();
4.8 out:response对应out对象--》这个就是这个异常根本所在;
4.9 exception:异常对象(有代码存在就会有异常存在)。
原文地址:https://www.cnblogs.com/zs-notes/p/9456234.html
感谢大佬的文章