1.
tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法
在tomcat5下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 i=0;i<4;i++){
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*i+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()放到循环体内
分享到:
相关推荐
在Java Web开发中,"getOutputStream() has already been called for this response" 是一个常见的错误,通常出现在使用Servlet或JSP时。这个错误意味着在HTTP响应中,`getOutputStream()`已经被调用,然后尝试再次...
在使用Tomcat 6服务器部署和运行Java Server Pages (JSP) 时,可能会遇到一个特定的异常:“getOutputStream() has already been called for this response”。该异常发生在尝试向响应对象中写入数据时,已经调用了...
验证码出现getOutputStream() has already been called for this response错误解决
纠结了半天的 java.lang.IllegalStateException: getOutputStream() has already。这个问题困扰了半天,在网上查阅了大量资料 出这个错误一般就是下面2个.....
解决了getOutputStream() has already been called for this response. 并将产生验证码的逻辑从JSP页面中分离出来,单独写了一个类 便于重用。
"Cannot forward after response has been committed" 是一个在Java Web开发中常见的错误,通常与Servlet、Filter或控制器逻辑有关。这个错误表明服务器已经完成了对HTTP响应的处理,并将其发送到客户端,然后试图...
`getOutputStream()` 方法就是从中获取一个输出流,这个流将用于向客户端发送响应内容。 `ServletOutputStream` 实例化后,我们可以通过调用它的`write()` 方法来写入字节数据。例如,如果我们在一个Servlet中想要...
Returns a boolean indicating whether the named response header has already been set. contextDestroyed(ServletContextEvent) - Method in interface javax.servlet.ServletContextListener Notification ...
标题 "java.lang.IllegalStateException: OutputStream already obtain" 涉及到的是Java编程中的一个常见错误,特别是当处理I/O流时。这个异常通常在尝试获取已经存在的OutputStream实例时抛出,表明该输出流已经被...
6. **读写数据**:通过`SerialPort`对象的`getInputStream()`和`getOutputStream()`方法获取输入流和输出流,然后可以使用Java的I/O操作进行串口通信。 7. **关闭串口**:完成通信后,记得调用`SerialPort.close()`...
* This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server ...
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); String inputLine = in.readLine(); System.out.println("接收到消息: " + inputLine); out.println("服务器回复: " + inputLine....
DataOutputStream outToClient = new DataOutputStream(connectionSocket[i].getOutputStream()); outToClient.writeBytes("UNIX>Ntalk " + inet.getHostAddress() + '\n'); outToClient.writeBytes("Server:Red_...
this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { try { MsgBean bean = new MsgBean(); bean.setType("请求下线"); bean.setSource(ClientFrame...
BufferedWriter wrbuf = new BufferedWriter(new OutputStreamWriter(s1.getOutputStream())); wrbuf.write("false\n"); wrbuf.flush(); }else{ Socket s2 = clients.get(str[0]); ...
if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) { throw new SecurityException(); } } catch (Exception e) { e.printStackTrace(); throw new ...
2. **数据传输**:连接建立后,通过Socket的`getOutputStream()`获取输出流,使用`getInputStream()`获取输入流。然后,可以使用`DataOutputStream`和`DataInputStream`进行字节级别的读写操作,或者使用`...
outputS = new ObjectOutputStream(connection.getOutputStream()); beConnected = true; } catch (IOException e) { System.out.println("无法获取连接的输入输出流"); } } ...