tomcat6下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法


1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法

  在tomcat6.0下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有妥善处理好的原因。

  具体的原因就是:
  在tomcat中jsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最后有一段这样的代码

复制代码 代码如下:
finally {
    if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
}

  这里是在释放在jsp中使用的对象,会调用response.getWriter(),因为这个方法是和response.getOutputStream()相冲突的!所以会出现以上这个异常。

  然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那样--将jsp内的所有空格和回车符号所有都删除掉),在使用完输出流以后调用以下两行代码即可:

复制代码 代码如下:
out.clear();
out = pageContext.pushBody();

  最后这里是一个输出彩色验证码例子(这样的例子几乎随处可见)

imag.jsp

<%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%@ page import="java.io.OutputStream" %>
<%!
  Color getRandColor(int fc,int bc){
    Random random = new Random();
    if(fc>255) fc=255;
    if(bc>255) bc=255;
    int r=fc+random.nextInt(bc-fc);
    int g=fc+random.nextInt(bc-fc);
    int b=fc+random.nextInt(bc-fc);
    return new Color(r,g,b);
  }
 %>
<%
  try{
    response.setHeader("Pragma","No-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);
    int width=60, height=20;
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    OutputStream os=response.getOutputStream();
    Graphics g = image.getGraphics();
    Random random = new Random();
    g.setColor(getRandColor(200,250));
    g.fillRect(0, 0, width, height);

    g.setFont(new Font("Times New Roman",Font.PLAIN,18));
    g.setColor(getRandColor(160,200));
    for (int i=0;i<155;i++){
      int x = random.nextInt(width);
      int y = random.nextInt(height);
      int xl = random.nextInt(12);
      int yl = random.nextInt(12);
      g.drawLine(x,y,x+xl,y+yl);
     }
    String sRand="";
    for (int j=0;j<4;j++){
      String rand=String.valueOf(random.nextInt(10));
      sRand+=rand;
      g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
      g.drawString(rand,13*j+6,16);
    }
    session.setAttribute("rand",sRand);
    g.dispose();

    ImageIO.write(image, "JPEG",os);
    os.flush();
    os.close();
    os=null;
    response.flushBuffer();
    out.clear();
    out = pageContext.pushBody();
  }catch(IllegalStateException e){
      System.out.println(e.getMessage());
    e.printStackTrace();
  }
%>

  如有不足之处,欢迎斧正!

2.getOutputStream() has already been called for this response问题的解决

  在jsp向页面输出图片的时候,使用response.getOutputStream()会有这样的提示:java.lang.IllegalStateException:getOutputStream() has already been called for this response,会抛出Exception

  原因一:
  JSP默认的输出流为PrintWriter ,即<% %>以外的东西所默认的输出方式,如果你尝试在JSP中使用ServletOutputStream就会引起错误.要嘛直接改用Servlet输出(复写service方法),要嘛删除除%><%中的任何东西(包括HTML标签,空格,回车等东西)应该就可以。对于这样的情况应该这样来解决,删除%><%之间的所有内容包括空格和换行符,最后也要消除空格和换行符,最好再加上一句response.reset()。

  原因二: 

  在J2EE的API参考里有这么个:

  ServletResponse的getWriter()方法里会抛出这个异常:

    IllegalStateException - if the getOutputStream method has already been called for this response object

  而它的getOutputStream()方法里会抛出这个异常:

    IllegalStateException - if the getOutputStream method has already been called for this response object

  并且两者的函数申明里都有这么样的一句

    Either this method or getOutputStream() may be called to write the body, not both.
    Either this method or getWriter() may be called to write the body, not both.


  以上说明也解释了为什么在往页面中写入图片的时候要使用如下循环格式

复制代码 代码如下:
OutputStream output=response.getOutputStream();
while((len=in.read(b)) >0) {
  output.write(b,0,len);
}
output.flush();

而不是把response.getOutputStream().write()放到循环体内

在页面中直接写:

复制代码 代码如下:
<body bgcolor="#ffffff">
<h1>
<%
    response.getOutputStream();
%>
</h1>
</body>

将会出现错误消息如下:

java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:604)
org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)

以上就是tomcat6下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法的全部内容,希望能给大家一个参考,也希望大家多多支持phpstudy。



相关阅读:
android同时控制EditText输入字符个数和禁止特殊字符输入的方法
Android手机开发 控件 TextView文字居中
C#常见的几种集合 ArrayList,Hashtable,List<T>,Dictionary<K,V> 遍历方法对比
MapReduce中ArrayWritable 使用指南
基于android背景选择器selector的用法汇总
Android实现计时与倒计时的常用方法小结
Java多线程继承Thread类详解
jQuery的end()方法使用详解
php实现基于微信公众平台开发SDK(demo)扩展的方法
Java实现图片对比功能
Android计算器简单逻辑实现实例分享
php下foreach提示Warning:Invalid argument supplied for foreach()的解决方法
微软官方演示Win10系统用户体验视频
Java使用DSA密钥对生成XML签名的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 买菜作文550字 2011教学工作室工作总结 残月 2016设立有限责任公司出资合同 初中初二作文800字:鹅妈妈告状 校园的秋天作文100字 广西百色高考满分作文范文800字 夜雨作文1000字 小学六年级作文700字:一个水龙头 职场励志感悟:怎样成为职场里受欢迎的人 我若去了,你便再也寻不到我 和奶奶去赶集 天空的云 教师工作总结范文800字 还是满满的爱 春游国旗下讲话稿两篇 写给我最亲爱的傻瓜 解放思想学习讨论活动汇报材料 工作英语励志名言 时间就是金钱 农民精神文化生活调查研究报告 离婚协议书书写格式 一世韶华,长歌落幕 把爱大声说出来作文500字 我喜欢写日记作文250字 一二九活动心得体会 致曾经的曾经——匆匆流年 小学一年级作文300字:这件事,让我懂得成全 初二政治教学反思 云浪 三十岁的职场指南 追逐凌云 天堂有鱼 学校财务个人年终工作总结 关于秋天的作文400字10篇_作文精选 2014新年贺卡祝福大全 《破产姐妹》经典台词语录摘抄 21条经典语录精华推荐 时,天,年 2009年新农村建设驻村工作队总结 小学五年级作文450字:我的“洒鬼”爷爷 留一条路给别人走 你我相约,携度仲夏 简短的开学祝福语 平安夜给父母的祝福话语 高中高三作文1200字:游宝葫芦农庄 欣赏的力量(转载)700字 人生是一场持久战,高考只是其中一页 中学教师新学期教科研工作体会 漫上来的旧时光 大写的爱??给地震中的老师

Copyright © 2016 phpStudy |