在JEEE开发文件下载中。有时候看到:
java 代码
- 严重: Servlet.service() for servlet jsp threw exception
- java.lang.IllegalStateException: getOutputStream() has already been called for this response
- at org.apache.catalina.connector.Response.getWriter(Response.java:604)
- at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
- at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
- at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
- at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
这样的错误,常常让人摸不清问题的所在。一个偶然的操作,我把servelt中业务逻辑的代码,用try,catch包起来。如下所示:
java 代码
- try {
- ............
- } catch (RuntimeException e) {
- e.printStackTrace();
- }
发现以上异常消失。一个
RuntimeException 错误的堆栈被打印出来。这个
RuntimeException 错误被处理之后,一切正常。于是联想到以后如何处理服务器的这一怪异行为。
到网上搜索后。
java 代码
- 在tomcat中jsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最后
- 有一段这样的代码
- finally {
- if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
- }
- 这里是在释放在jsp中使用的对象,会调用response.getWriter(),因为这个方法是和
- response.getOutputStream()相冲突的!所以会出现以上这个异常。
-
- 然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那样--
- 将jsp内的所有空格和回车符号所有都删除掉),
然后又看了一下我先前的错误堆栈:
java 代码
- java.lang.IllegalStateException: getOutputStream() has already been called for this response
- at org.apache.catalina.connector.Response.getWriter(Response.java:604)
- at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
- at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
- at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
- at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:186)
- at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
- at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
- at org.apache.jsp.unhandledException_jsp._jspService(unhandledException_jsp.java:120)
- at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
呵呵。org.apache.jasper.runtime.PageContextImpl.release
由上面的堆栈可以看出。在
javax.servlet.http.HttpServlet.service中出错。会执行org.apache.jasper.runtime.JspFactoryImpl.releasePageContext,然后会调用org.apache.catalina.connector.Response.getWriter(Response.java:604),由于
getWriter,和您下载文件时用的response.getOutputStream()冲突。见以下doc
java 代码
- getOutputStream
-
- public ServletOutputStream getOutputStream()
- throws java.io.IOException
-
- Returns a ServletOutputStream suitable for writing binary data in the response. The servlet container does not encode the binary data.
-
- Calling flush() on the ServletOutputStream commits the response.
- Either this method or getWriter() may be called to write the body, not both.
-
- Returns:
- a ServletOutputStream for writing binary data
- Throws:
- IllegalStateException - if the getWriter method has been called on this response
- java.io.IOException - if an input or output exception occurred
- See Also:
- getWriter()
至此。一切都明白了。想到经常在做服务器开发的时候,经常出现莫名其妙的服务器错误。在重新启动服务器后又消失掉了。有可能是再您的程序中,出现了unchecked的异常。而服务器在处理异常是有一些预订的行为。有可能在处理异常时又出现新的错误。从而把您的视线移到服务器出现的那个错误上。而我们往往对这些错误没什么办法。在这个时候,您不妨跟踪到您代码出错的那一行。把异常捕获。
分享到:
相关推荐
在Java Web开发中,"getOutputStream() has already been called for this response" 是一个常见的错误,通常出现在使用Servlet或JSP时。这个错误意味着在HTTP响应中,`getOutputStream()`已经被调用,然后尝试再次...
1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 在tomcat6.0下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有...
验证码出现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响应的处理,并将其发送到客户端,然后试图...
ServletOutputStream out = response.getOutputStream(); out.write("<html><body>Hello, World!</body></html>".getBytes()); out.flush(); out.close(); ``` 描述中的"InputStream i" 提到了输入流`InputStream`...
本篇将深入探讨`response`设置的实例源码,以及如何在Servlet中应用这些设置。 一、Response对象的基本介绍 `HttpServletResponse`接口是`ServletResponse`接口的子接口,它扩展了通用的响应功能,以适应HTTP协议的...
标题 "java.lang.IllegalStateException: OutputStream already obtain" 涉及到的是Java编程中的一个常见错误,特别是当处理I/O流时。这个异常通常在尝试获取已经存在的OutputStream实例时抛出,表明该输出流已经被...
try (OutputStream out = response.getOutputStream()) { // 使用Apache POI或其他库生成Excel内容并写入out流 } ``` #### 五、动态生成JPEG图像 如果需要动态生成并发送JPEG格式的图像,也需要设置正确的响应...
Returns a boolean indicating whether the named response header has already been set. contextDestroyed(ServletContextEvent) - Method in interface javax.servlet.ServletContextListener Notification ...
OutputStream ou = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); // 设置响应类型为二进制流 // 写入响应流并关闭 ou.write(buffer); ou....
2. getOutputStream():从Servlet中可以通过getOutputStream方法取得ServletOutputStream对象,既可以输出字符数据,也可以输出MIME格式的二进制数据。 3. setContentType():在响应中可以表明内容格式和长度。 4. ...
这里使用了Servlet的`HttpServletResponse`对象,调用其`setContentType`方法设置响应的MIME类型为`image/jpeg`或`image/png`,然后使用`getOutputStream`获取输出流,并调用`ImageIO.write`方法将图片写入。...
在Java Web开发中,`response.jsp`通常是指服务器端的响应页面,主要涉及Servlet和JSP(JavaServer Pages)技术。`response`对象是Servlet API中的一个关键组件,全称为`HttpServletResponse`,它用于构建并发送回...
JSP内置对象request和response详解 JSP内置对象request和response是JSP开发中两个非常重要的对象,它们分别用于处理客户端请求和响应信息。在本文档中,我们将详细介绍request和response对象的功能和使用方法。 ...
3. 使用`FileInputStream`读取文件内容,并通过`response.getOutputStream().write()`将内容写入响应流。 通过以上方法,我们可以在处理中文文件名的文件下载时,有效避免乱码问题,确保用户能够正确下载并识别文件...
3. `getOutputStream()`:返回ServletOutputStream,用于写入二进制数据到响应体,如文件下载。 4. `getWriter()`:返回PrintWriter,用于写入文本数据到响应体,如HTML、JSON等。 在实际应用中,我们通常会创建一...
**Data Integrity**: Ensures that the data has not been tampered with during transmission. - C. **Confidentiality**: Ensures that the data is not disclosed to unauthorized parties. - A. **...