getOutputStream() has already been called for this response改成serverlet怎么改。我用的是tomcat。

解决方案 »

  1.   

    加上response.reset(),并且所有的%>后面不要换行,包括最后一个;
    因为Application Server在处理编译jsp时对于%>和<%之间的内容一般是原样输出,而且默认是PrintWriter,
    而你却要进行流输出:ServletOutputStream,这样做相当于试图在Servlet中使用两种输出机制,
    就会发生:getOutputStream() has already been called for this response的错误
    详细请见《More Java Pitfill》一书的第二部分 Web层Item 33:试图在Servlet中使用两种输出机制 270
    而且如果有换行,对于文本文件没有什么问题,但是对于其它格式,比如AutoCAD、Word、Excel等文件
    下载下来的文件中就会多出一些换行符0x0d和0x0a,这样可能导致某些格式的文件无法打开,有些也可以正常打开
      

  2.   

    我将验证码的生成写在jsp里也出现了这样的问题,而且照楼上的说法也始终没有解决(看了jsp对应的.java,发现无论如何也避免不了回车的输出——我没有显示输出回车,可是容器将我的jsp生成java时自动给我加回车)后来无奈,写在servlet里面就没有这个问题了
      

  3.   

    请问楼上的,servlet是如何写的,能否把代码共享一下,谢谢!
      

  4.   

    binny(骑个破车看夕阳)  的解答是正确的,我以前也碰过这种总是,后来把%><%之间的内容,全部删掉就OK了,包括最后一个%>的回车(习惯性会打回车)也要删掉,就OK了,再试一下吧,再不行就把源码发上来,也许有人能帮忙解决的.
      

  5.   

    我原来用jsp写也是,后来改成servlet就ok了package CMCC;
    import java.io.*;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.GraphicsEnvironment;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageWriter;
    import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
    import javax.imageio.stream.ImageOutputStream;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class VerifyCodeServlet extends HttpServlet
    {
         private static final int IMAGE_WIDTH = 60;
         private static final int IMAGE_HEIGHT = 20;
         private static final int FONT_HEIGHT = 16;
         private static final String SVG_SOURCE1 = "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">"
             + "<svg width=\""
             + IMAGE_WIDTH
             + "\" height=\""
             + IMAGE_HEIGHT
             + "\" xmlns=\"http://www.w3.org/2000/svg\">"
             + "<text x=\"0\" y=\""
             + IMAGE_HEIGHT
             + "\" font-family=\"Arial\" font-size=\""
             + IMAGE_HEIGHT + "\" fill=\"black\">";     private static final String SVG_SOURCE2 = "</text></svg>";
         private boolean svgMode = false;
         private PrintWriter out = null;
         protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException 
         {
             //if (sn == null)
                 // return;
                  
             String vcode = sn2vcode();         arg0.getSession().setAttribute("rand",vcode) ;//代码内容写入session中         if (svgMode)
                  outSVG(vcode, arg1);
             else
                  outJPEG(vcode, arg1);
         }
         private void outSVG(String vcode, HttpServletResponse resp) throws IOException 
         {
             resp.setContentType("image/svg+xml");
             resp.getOutputStream().print(SVG_SOURCE1 + vcode + SVG_SOURCE2);
         }     private void outJPEG(String vcode, HttpServletResponse resp) throws IOException 
         {
             resp.setContentType("image/jpeg");
             BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
                  BufferedImage.TYPE_INT_RGB);
             Random random = new Random();
             Graphics g = image.getGraphics();
             //g.setColor(getRandColor(200, 250));
             g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_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(IMAGE_WIDTH);
                  int y = random.nextInt(IMAGE_HEIGHT);
                  int xl = random.nextInt(12);
                  int yl = random.nextInt(12);
                  g.drawLine(x, y, x + xl, y + yl);
             }
             for (int i = 1; i <= 4; i++) 
             {
                  String rand = vcode.substring(i - 1, i);
                  g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
                  g.drawString(rand, 13 * (i - 1) + 0, 16);
             }
             ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
             JPEGImageWriteParam params = new JPEGImageWriteParam(null);
             ImageOutputStream ios = ImageIO.createImageOutputStream(resp.getOutputStream());
             writer.setOutput(ios);
             writer.write(null, new IIOImage(image, null, null), params);
             writer.dispose();
             ios.close();
         }     static String sn2vcode() 
         {
             String sRand = "";
             Random random = new Random();
             for (int i=0;i<4;i++)
             {
                  String rand=String.valueOf(random.nextInt(10));
                  sRand+=rand;
             }
             return sRand;
         }
         public void init() throws ServletException 
         {
             try 
             {
                  GraphicsEnvironment.getLocalGraphicsEnvironment();
             } 
            catch (Throwable e) 
             {
           
                  svgMode = true;
             }
         }
         public 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);
         }
    }
      

  6.   

    在页面中直接写:
    <body bgcolor="#ffffff">
    <h1>
    <%
    response.getOutputStream();
    %>
    </h1>
    </body>
    就会出错,应该输出流只能被打开一次,而生成servlet以后,在你的语句之前已经被打开过了。
    因为servlet要输出html标签。
    这是jdk中的说明:
    java.lang.IllegalStateException - if the getWriter method has been called on this response
    getWriter method,看清楚,不一定是getOutputStream
      

  7.   

    JSP默认的输出流为PrintWriter ,即<% %>以外的东西所默认的输出方式,如果你尝试在JSP中使用ServletOutputStream就会引起错误.要嘛直接改用Servlet输出(复写service方法),要嘛删除除<%%>中的任何东西(包括HTML标签,空格,回车等东西)应该就可以.粗浅看法,不知道对错:P