Response.getWriter() 和Response.getOutputStream冲突
2015-06-12 11:35
645 查看
From:http://yulimeander.blog.sohu.com/119195170.html
ava.lang.IllegalStateException异常:简单分析和简单解决方案
2008-07-19 18:07
ava.lang.IllegalStateException异常:简单分析和简单解决方案
2008-07-19 18:07
今天写java验证码程序,完成后使用一切正常,但是总抛出java.lang.IllegalStateException异常,虽然并不影响正常使用,但看了总让人觉得很不舒服,检查代码并没有错,最后上网查了不少资料,终于发现原因之所在。 我们在做文件上传或者下载,或者过滤等操作时,可能要用到页面的输出流. 例如在JSP使用: response.reset(); response.setContentType(”application/vnd.ms-excel”); OutputStream os = response.getOutputStream(); 抛出异常: ERROR [Engine] StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception java.lang.IllegalStateException: getOutputStream() has already been called for this response 从网上找了下资料,综合一下原因分析: 这是web容器生成的servlet代码中有out.write(””),这个和JSP中调用的response.getOutputStream()产生冲突. 即Servlet规范说明,不能既调用 response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,在调用第二个时候应会抛出 IllegalStateException,因为在jsp中,out变量是通过response.getWriter得到的,在程序中既用了response.getOutputStream,又用了out变量,故出现以上错误。 解决方案: 1.在程序中添加: out.clear(); out = pageContext.pushBody(); 就可以了; 2,不要在%][%之间写内容包括空格和换行符 3,在页面写入图片的时候,需要flush() OutputStream output=response.getOutputStream(); output.flush(); 4,在页面确定写入<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312”> 孙卫琴说可能是tomcat的bug,我给她回了封信: :我看了看这里,http://www.javathinker.org/main.jsp?bc=showessay.jsp+filename=tomcat/tomcat_question_chapter13.htm这里是你回复别人的一个帖子,里面的观点基本上和我理解的一样,但是你最后写到可能是tomcat的bug,我想解释一下:在jsp中,out是内嵌对象,即已经设置了PrintWriter out=response.getWriter();这样在再次getOutputStream()得到输出流时(比如转发过滤、下载文件时)就出错了(写排斥锁),我不止一次看到有人的文件下载页面在后台不断打印这个异常。而在servlet中没有默认out内置对象,所以没有出错.你可以在servlet中添加out对象试试,应该会报异常的.所以正确的处理方式就应该是:在servlet中做控制层,在业务处理以前不要获得out对象,当业务操作失败或出现异常时再生成out对象回显操作结果。 *********************************************************** response.getOutputStream() 和 requonse.getWriter() 区别 (1)使用tomcat5容器调用response.getOutputStream()方法即可实现,但调用requonse.getWriter()方法时,输出二进制数据时(图片等内容无法显示)则出现“getWriter() has already been called for this response”异常。 (2)使用tomcat6容器调用response.getOutputStream()方法时有中文字符会发生“java.io.CharConversionException:Not an ISO 8859-1 character:”异常,调用requonse.getWriter()方法时可实现文本字符串数据输出,调用response.getOutputStream()方法可现实字节流数据的输出。 就上述出现的问题进行分析研究,阅读了tomcat6的源代码发现,在调用response.getOutputStream()方法时会判断是否已调用了requonse.getWriter()方法;相反在调用requonse.getWriter()方法时会判断是否已调用了response.getOutputStream()方法。 在tomcat5时并没有出现这个问题,使用response.getOutputStream()方法可现实两种数据输出,只是在使用requonse.getWriter()时发生异常,而在tomcat6下则必须针对不同的数据类型选择相应输出流,这时为什么呢?仔细阅读tomcat6源代码没有发现问题的根源,给出的参考时:在一次客户端请求的响应动作中,只能调用一种响应输出方法,要么是getWriter()要么是getOutputStream(),且如果使用getOutputStream()方法输出字符串格式的数据时,中文无法正常通过将发生“java.io.CharConversionException:Not an ISO 8859-1 character:”异常,在tomcat5下没有对getOutputStream()方法进行严格控制,中文字符串可正常通过。可见tomcat6的安全机制比tomcat5要严格,对于字符串格式的数据要求使用getWriter()方法输出响应,如果使用了getOutputStream()方法输出响应,则对输出的字符串数据进验证,要求高字节必须为0,显然中文是无法通过的。 |
相关文章推荐
- (转)解析PHP中ob_start()函数的用法
- FragmentPagerAdapter与FragmentStatePagerAdapter区别
- LAMP环境搭建3-PHP5.6
- php 开发环境图文配置
- Windows下PHPUnit安装
- 【AS400系列】通过程序例子说明检查AS400用户密码的API-QSYGETPH
- (转)ThinkPHP系统常量
- PHP 根据IP地址获取所在城市
- [php] 解析JSON字符串
- 关于php 中file_put_contents 和fwrite file_get_contents和curl
- php xml 转array 函数 (原创)
- phpcms 循环输出
- sublime中检查php语法错误
- TP:6DD02CBB
- php中include文件变量作用域的研究
- php学习之mysql(一)找回root密码
- 关于 PHP 7 你必须知道的五件事
- laravel5学习笔记(2)——路由
- OSChina 周五乱弹 —— 快使用PHP,哼哼哈兮
- Win7下IIS安装PHP环境