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 交通频道 作文范文 南郑县第二十届教师节献词 我的家乡日照 季度工作总结模板 小学生学习青春励志 四年级下册语文暑假作业答案(苏教版) 致自己——一个快奔三的SB 我的阅读故事 用爱去交流 熟悉的歌 初中初二作文1000字:泪为谁流 高中语文组工作计划 感怀(又见桐花发旧枝) 坐着火车去曼谷 小班数学说课稿:认识三角形 你说每一次努力都不输给懵懂的爱情作文200字 2010年电力局领导个人年度述职报告 《创世卷二》四--昆仑山之姐姐? 忆十年 坚固的棱锥 名人励志200字小故事 哭先生过寿作文1000字 春季新产品推广会开幕词 中国的巨变作文800字 2015快乐的动物教学反思 观察绿豆(二)250字 她和他之友谊作文1000字 十一月离语作文800字 享受滑旱冰的乐趣 初中初一作文650字:杭州西湖导游词 再寄小记者读后感 最美好的时光,永远在当下 副局长述职报告 秘书论文-高级秘书为决策服务的特殊技能 香山红叶 祝福考试顺利的句子 《 我的城里住个你 》 回避盲区 与往日重逢 县行政服务中心上半年总结和下半年打算 小学二年级作文400字:诚实让它受益 书我的良师益友 拔莴苣 中外合作办学模式下辅导员队伍建设的挑战及要求 小学数学教师读书笔记 一个热爱单杠运动的人 设立中外合资经营企业合同(金融1) 电信公司创建学习型企业材料_会议发言 纪念卢沟桥事变七十八周年记 一想起这件事,我就泪流不止作文800字 考试祝福语短信汇集

Copyright © 2016 phpStudy |